Appearance
Creating Virtual Files
Learn how to create different types of virtual files, configure them properly, and publish them to your WordPress site.
File Creation Process
Step 1: Access File Creation
Navigate to Virtual Files
- In WordPress admin, click Virtual Files in left menu
- Click Add New button
- Or visit directly:
/wp-admin/post-new.php?post_type=virtual_file
File Creation Interface
- Title: Descriptive name for your reference
- Filename: Actual filename that will be served (without extension)
- File Type: Extension and MIME type selection via dropdown
- Content Editor: Where you add file content (textarea or CodeMirror)
- Status: Active/Inactive selector in sidebar
- Enhanced Info Sidebar: Shows MIME type, public URL, and analytics (Pro)
- Action Buttons: Copy URL, Visit File, Upgrade to Pro
Step 2: Configure File Details
Basic Information
- Title: Internal name for organization (e.g., "Main Robots File")
- Filename: The actual URL filename without extension (e.g.,
robots) - File Type: Choose from supported extensions via dropdown
File Types and Extensions
| File Type | Extension | MIME Type | Best For |
|---|---|---|---|
| Text File | .txt | text/plain | Documentation, logs, simple data |
| Markdown | .md | text/markdown | Documentation, readme files |
| JSON | .json | application/json | API responses, configuration |
| XML | .xml | application/xml | Sitemaps, RSS feeds, data exchange |
| RSS | .rss | application/rss+xml | News feeds, updates |
| CSV | .csv | text/csv | Data export, spreadsheets |
| YAML | .yml, .yaml | text/yaml | Configuration files |
| Log File | .log | text/plain | Debug logs, access logs |
Step 3: Add Content
Content Editor Features
- Basic Editor (Free): Simple WordPress text area with monospace font
- CodeMirror Editor (Pro): Professional code editor with:
- Syntax highlighting for all supported file types
- Line numbers and bracket matching
- Search functionality
- Dark/light theme options (default/monokai)
- Auto-indent and code folding
- Keyboard shortcuts (Ctrl-Space autocomplete, Ctrl-/ toggle comment, F11 fullscreen)
Content Validation
- Real-time Validation: Shows file accessibility status
- Security Scanning: Automatic content sanitization (PHP tag removal, script/iframe filtering)
- Size Limits: 1MB maximum content size
- Uniqueness Check: Prevents duplicate filenames
- Character Validation: No forbidden characters (
<>:"|?*)
File Type Examples
Text Files (.txt)
robots.txt Example
text
User-agent: *
Allow: /
Disallow: /wp-admin/
Disallow: /wp-includes/
Disallow: /wp-content/plugins/
Disallow: /wp-content/themes/
Disallow: /readme.html
Disallow: /license.txt
# Allow specific bots
User-agent: Googlebot
Allow: /
User-agent: Bingbot
Allow: /
# Sitemap location
Sitemap: https://yourdomain.com/sitemap.xml
# Crawl delay
Crawl-delay: 1.htaccess Example
text
# Security headers
<IfModule mod_headers.c>
Header always set X-Content-Type-Options nosniff
Header always set X-Frame-Options DENY
Header always set X-XSS-Protection "1; mode=block"
</IfModule>
# Performance optimization
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
</IfModule>
# Gzip compression
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/rss+xml
</IfModule>Markdown Files (.md)
API Documentation Example
markdown
# API Documentation
## Overview
This API provides access to website content in JSON format.
## Authentication
All API endpoints require authentication:
```bash
curl -H "Authorization: Bearer YOUR_TOKEN" \
https://yourdomain.com/api/posts.jsonEndpoints
Posts
URL: /api/posts.jsonMethod: GET Description: Retrieve all published posts
Response:
json
{
"status": "success",
"data": [
{
"id": 1,
"title": "Sample Post",
"slug": "sample-post",
"content": "Post content here",
"date": "2026-01-01T00:00:00Z",
"author": "John Doe"
}
],
"total": 1,
"pages": 1
}Pages
URL: /api/pages.jsonMethod: GET Description: Retrieve all published pages
Media
URL: /api/media.jsonMethod: GET Description: Retrieve media library items
Error Handling
401 Unauthorized
json
{
"error": "unauthorized",
"message": "Invalid or missing authentication token"
}404 Not Found
json
{
"error": "not_found",
"message": "Requested resource not found"
}Rate Limiting
- Requests: 100 per hour per IP
- Burst: 10 requests per minute
- Headers: Check
X-RateLimit-LimitandX-RateLimit-Remaining
Usage Examples
JavaScript
javascript
// Fetch posts
fetch('/api/posts.json')
.then(response => response.json())
.then(data => {
console.log('Posts:', data.data);
})
.catch(error => {
console.error('Error:', error);
});PHP
php
// Fetch posts using WordPress HTTP API
$response = wp_remote_get('https://yourdomain.com/api/posts.json');
if (!is_wp_error($response)) {
$data = json_decode(wp_remote_retrieve_body($response), true);
print_r($data);
}License
© 2026 Your Website Name. All rights reserved.
### **JSON Files (.json)**
#### **Configuration File Example**
```json
{
"application": {
"name": "My WordPress Site",
"version": "1.0.0",
"environment": "production",
"debug": false
},
"api": {
"version": "v1",
"base_url": "https://yourdomain.com/api",
"endpoints": {
"posts": "/posts.json",
"pages": "/pages.json",
"media": "/media.json",
"users": "/users.json"
},
"authentication": {
"type": "bearer_token",
"required": true
},
"rate_limiting": {
"requests_per_hour": 100,
"burst_per_minute": 10
}
},
"features": {
"caching": {
"enabled": true,
"ttl": 3600,
"invalidation": "auto"
},
"cors": {
"enabled": true,
"allowed_origins": ["*"],
"allowed_methods": ["GET", "POST", "PUT", "DELETE"],
"allowed_headers": ["Content-Type", "Authorization"]
},
"analytics": {
"enabled": true,
"tracking_level": "detailed"
}
},
"security": {
"https_required": true,
"token_expiration": 86400,
"max_request_size": "10MB"
},
"database": {
"type": "mysql",
"version": "8.0+",
"charset": "utf8mb4"
},
"wordpress": {
"version": "6.0+",
"multisite": false,
"permalink_structure": "/%postname%/"
}
}API Response Example
json
{
"status": "success",
"message": "Data retrieved successfully",
"timestamp": "2026-01-01T12:00:00Z",
"data": {
"posts": [
{
"id": 1,
"title": "Welcome to Our Site",
"slug": "welcome",
"content": "Welcome to our amazing website!",
"excerpt": "Welcome to our amazing website!",
"author": {
"id": 1,
"name": "Admin User",
"email": "admin@yourdomain.com"
},
"categories": [
{
"id": 1,
"name": "Uncategorized",
"slug": "uncategorized"
}
],
"tags": ["welcome", "intro"],
"featured_media": null,
"status": "published",
"date_created": "2026-01-01T10:00:00Z",
"date_modified": "2026-01-01T10:00:00Z",
"url": "https://yourdomain.com/welcome",
"meta": {
"views": 150,
"likes": 12,
"shares": 5
}
}
],
"pagination": {
"current_page": 1,
"total_pages": 5,
"total_items": 25,
"items_per_page": 5,
"has_next": true,
"has_prev": false
}
},
"performance": {
"query_time": "0.045s",
"memory_usage": "12.5MB",
"cache_hit": true
}
}XML Files (.xml)
Sitemap Example
xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
<!-- Homepage -->
<url>
<loc>https://yourdomain.com/</loc>
<lastmod>2026-01-01T12:00:00+00:00</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
<image:image>
<image:loc>https://yourdomain.com/wp-content/uploads/2026/01/homepage.jpg</image:loc>
<image:title>Homepage Image</image:title>
<image:caption>Main website banner</image:caption>
</image:image>
</url>
<!-- Posts -->
<url>
<loc>https://yourdomain.com/sample-post</loc>
<lastmod>2026-01-01T10:00:00+00:00</lastmod>
<changefreq>weekly</changefreq>
<priority>0.8</priority>
<image:image>
<image:loc>https://yourdomain.com/wp-content/uploads/2026/01/post-image.jpg</image:loc>
<image:title>Sample Post Image</image:title>
</image:image>
</url>
<!-- Pages -->
<url>
<loc>https://yourdomain.com/about-us</loc>
<lastmod>2026-01-01T08:00:00+00:00</lastmod>
<changefreq>monthly</changefreq>
<priority>0.6</priority>
</url>
<!-- Categories -->
<url>
<loc>https://yourdomain.com/category/technology</loc>
<lastmod>2026-01-01T09:00:00+00:00</lastmod>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
</urlset>RSS Feed Example
xml
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>My WordPress Site</title>
<description>Latest news and updates from My WordPress Site</description>
<link>https://yourdomain.com</link>
<language>en-US</language>
<copyright>Copyright 2026 My WordPress Site. All rights reserved.</copyright>
<managingEditor>editor@yourdomain.com</managingEditor>
<webMaster>webmaster@yourdomain.com</webMaster>
<pubDate>Mon, 01 Jan 2026 12:00:00 +0000</pubDate>
<lastBuildDate>Mon, 01 Jan 2026 12:00:00 +0000</lastBuildDate>
<generator>WordPress 6.0</generator>
<docs>https://www.rssboard.org/rss/specification</docs>
<ttl>60</ttl>
<image>
<url>https://yourdomain.com/wp-content/uploads/2026/01/logo.jpg</url>
<title>My WordPress Site</title>
<link>https://yourdomain.com</link>
<width>144</width>
<height>144</height>
<description>Site logo</description>
</image>
<!-- Posts -->
<item>
<title>Sample Post Title</title>
<link>https://yourdomain.com/sample-post</link>
<comments>https://yourdomain.com/sample-post#comments</comments>
<pubDate>Mon, 01 Jan 2026 10:00:00 +0000</pubDate>
<dc:creator>Admin User</dc:creator>
<category>Technology</category>
<category>WordPress</category>
<guid isPermaLink="true">https://yourdomain.com/sample-post</guid>
<description>This is a sample post description that appears in RSS feeds.</description>
<content:encoded><![CDATA[
<p>This is the full content of the post with <strong>HTML formatting</strong> preserved.</p>
<img src="https://yourdomain.com/wp-content/uploads/2026/01/post-image.jpg" alt="Post image" />
<p>Continue reading the post for more information...</p>
]]></content:encoded>
<enclosure url="https://yourdomain.com/wp-content/uploads/2026/01/podcast.mp3"
type="audio/mpeg"
length="1234567" />
</item>
<item>
<title>Another Post</title>
<link>https://yourdomain.com/another-post</link>
<pubDate>Sun, 31 Dec 2023 15:30:00 +0000</pubDate>
<dc:creator>Guest Author</dc:creator>
<category>Tutorials</category>
<description>Another post description for RSS feed.</description>
<content:encoded><![CDATA[
<p>Full content with HTML formatting and images.</p>
]]></content:encoded>
</item>
</channel>
</rss>CSV Files (.csv)
Product Export Example
csv
id,title,description,price,category,stock,sku,created_at
1,"WordPress Theme","Premium WordPress theme with modern design",49.99,"Themes",15,"WP-THEME-001","2026-01-01T10:00:00Z"
2,"Plugin Bundle","Collection of essential WordPress plugins",29.99,"Plugins",50,"WP-BUNDLE-001","2026-01-02T14:30:00Z"
3,"Support Package","1 year priority support package",99.99,"Services",100,"WP-SUPPORT-001","2026-01-03T09:15:00Z"
4,"Custom Development","Custom WordPress development service",299.99,"Services",5,"WP-DEV-001","2026-01-04T16:45:00Z"User Export Example
csv
id,username,email,first_name,last_name,role,registered_at,last_login
1,"admin","admin@yourdomain.com","Admin","User","administrator","2026-01-01T10:00:00Z","2026-01-15T14:30:00Z"
2,"editor","editor@yourdomain.com","Editor","User","editor","2026-01-02T11:20:00Z","2026-01-14T09:45:00Z"
3,"author","author@yourdomain.com","Author","User","author","2026-01-03T13:45:00Z","2026-01-13T16:20:00Z"YAML Files (.yml/.yaml)
Docker Configuration Example
yaml
# WordPress Docker Configuration
version: '3.8'
services:
# WordPress Application
wordpress:
image: wordpress:6.0-php8.0-apache
container_name: my-wordpress
restart: unless-stopped
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: secure_password_here
WORDPRESS_DB_NAME: wordpress
WORDPRESS_TABLE_PREFIX: wp_
WORDPRESS_DEBUG: false
volumes:
- ./wp-content:/var/www/html/wp-content
- ./uploads:/var/www/html/wp-content/uploads
depends_on:
- db
networks:
- wordpress-network
# MySQL Database
db:
image: mysql:8.0
container_name: my-wordpress-db
restart: unless-stopped
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: secure_password_here
MYSQL_ROOT_PASSWORD: root_password_here
volumes:
- db_data:/var/lib/mysql
- ./mysql-backups:/backup
networks:
- wordpress-network
# Redis Cache
redis:
image: redis:7-alpine
container_name: my-wordpress-redis
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- redis_data:/data
networks:
- wordpress-network
# Nginx Reverse Proxy
nginx:
image: nginx:alpine
container_name: my-wordpress-nginx
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./ssl:/etc/nginx/ssl
depends_on:
- wordpress
networks:
- wordpress-network
# Volumes
volumes:
db_data:
driver: local
redis_data:
driver: local
# Networks
networks:
wordpress-network:
driver: bridgeCI/CD Pipeline Example
yaml
# GitHub Actions Workflow for WordPress
name: WordPress Deployment
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
env:
NODE_VERSION: '18'
PHP_VERSION: '8.0'
jobs:
# Test Suite
test:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:8.0
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: wordpress_test
options: >-
--health-cmd="mysqladmin ping"
--health-interval=10s
--health-timeout=5s
--health-retries=3
ports:
- 3306:3306
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ env.PHP_VERSION }}
extensions: mbstring, xml, mysql, curl
coverage: xdebug
- name: Install dependencies
run: |
npm ci
composer install --no-progress --no-suggest --optimize-autoloader
- name: Run tests
run: |
npm run test:php
npm run test:js
- name: Code coverage
run: |
npm run coverage:php
npm run coverage:js
# Build and Deploy
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
- name: Build assets
run: |
npm ci
npm run build
- name: Deploy to server
uses: appleboy/ssh-action@v0.1.5
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
cd /var/www/html
git pull origin main
npm run build
wp plugin activate virtual-files
wp cache flushFree vs Pro File Limits
Free Version
- Maximum 5 active virtual files
- Only 5 most recently updated active files are accessible
- Older files return 404 even if set to "Active"
- Basic text editor only
- No file analytics
Pro Version
- Unlimited virtual files
- All active files are accessible
- Advanced CodeMirror editor
- File analytics and tracking
- All file types supported
Publishing and Testing
Publishing Your File
- Review Content: Double-check your file content for errors
- Set Status: Choose "Active" to make file publicly accessible or "Inactive" to keep it private
- Save File: Click "Publish" (for new files) or "Update" (for existing files)
- Test Access: Verify file is accessible via its URL
Testing Your Virtual File
- Direct URL: Visit
yourdomain.com/your-filename.ext - Headers Check: Verify correct MIME headers are sent
- Content Validation: Ensure content displays correctly
- Performance: Check load times and caching
Common Testing Methods
CURL Testing
bash
# Test file with headers
curl -I https://yourdomain.com/robots.txt
# Test file content
curl https://yourdomain.com/api-config.json
# Test with specific headers
curl -H "Accept: application/json" \
https://yourdomain.com/api-endpoint.jsonBrowser Testing
- Chrome DevTools: Check Network tab for headers
- Firefox Developer: Inspect response headers
- Safari Web Inspector: Verify content delivery
Validation Tools
- JSON: Use JSONLint
- XML: Use W3C Validator
- RSS: Use W3C Feed Validator
- CSV: Use CSV Validator
Best Practices
File Naming
- Use lowercase letters
- Avoid spaces (use hyphens)
- Keep names descriptive but short
- Use appropriate extensions
- Avoid special characters
Content Optimization
- Keep file sizes reasonable
- Use proper formatting
- Validate syntax before publishing
- Test in multiple browsers
Security Considerations
- Don't include sensitive data
- Validate user input in dynamic content
- Use HTTPS for sensitive endpoints
- Regular security audits
Performance Tips
- Enable caching for frequently accessed files (Pro feature)
- Use appropriate file formats for your use case
- Monitor file access through WordPress analytics (Pro feature)
- Consider rewrite rules efficiency
Troubleshooting
Common Issues
File Not Accessible
- Check file status is "Active" (for Free users: only 5 most recent active files are accessible)
- Verify rewrite rules are flushed
- Check file doesn't conflict with existing WordPress URLs
- Test with different browsers
Incorrect MIME Type
- Verify file extension matches content
- Check MIME type settings
- Validate content format
- Test with header inspection tools
Content Not Displaying
- Check for syntax errors
- Verify content encoding
- Test with validation tools
- Check browser console for errors
Getting Help
- Documentation: Check our troubleshooting guide
- Support: Contact through WordPress admin or Freemius
- Community: Join our WordPress forums
Next Steps
Now that you've mastered creating virtual files:
- Learn File Management: Advanced organization techniques
- Configure Settings: Optimize your plugin configuration
- Explore Backup & Restore: Backup and restore capabilities
- Check Features: Discover advanced functionality