FREQUENTLY ASKED QUESTIONS
Code:
Option 1 — Route + Controller:
1. Create a route class extending \XF\Mvc\Router
2. Create a controller class extending \XF\Pub\Controller
3. Register in _metadata.json:
"routes": {
"public": {
"myroute": ["Controller","MyCustom"]
}
}
4. Access: /myroute
Option 2 — Node-Based:
1. Create a new node type (add-on required)
2. Or use existing "Page" node type
3. Admin CP → Nodes → Create Page
4. Enter HTML content, callback PHP class for dynamic content
Option 3 — Template Modification:
1. Create template modification in ACP → Appearance → Template Modifications
2. Target: PAGE_CONTAINER or specific templates
3. Add: <xf:if is="$customCondition">Your content</xf:if>
4. Controlled: hook system (e.g., <xf:hook name="my_hook" />)
Code:
1. Setup structure:
src/addons/VendorName/AddonName/
├── _metadata.json
├── Entity/
├── Repository/
├── Service/
├── Controller/
├── Admin/
├── Pub/
├── View/
├── Template/
└── Setup.php
2. _metadata.json format:
{
"title": "My Add-on",
"version_string": "1.0.0",
"version_id": 100,
"developer": "MyVendor",
"require": [],
"json_hash": ""
}
3. Setup.php:
<?php
namespace MyVendor\MyAddon;
class Setup extends \XF\Addon\AbstractSetup
{
public function install(array $stepParams = []) {
// Create tables, add permissions, etc.
$this->schemaManager()->createTable('xf_my_table', function(\Laminas\Dd\Sql\Ddl\CreateTable $table) {
$table->addColumn('item_id', 'int')->autoIncrement();
$table->addColumn('title', 'varchar', 150);
$table->addPrimaryKey('item_id');
});
}
public function uninstall(array $stepParams = []) {}
public function upgrade(array $stepParams = []) {}
}
4. Development mode:
- Set $config['development']['enabled'] = true; in src/config.php
- ACP → Development → Code Event Listeners / Content Types
- Regenerate: XF development output → Rebuild add-on JSON
Code:
1. Caching:
- Enable Redis/Memcached: $config['cache']['enabled'] = true;
- $config['cache']['provider'] = 'Redis';
- $config['cache']['config'] = ['server' => '127.0.0.1', 'port' => 6379];
- Cache templates, entities, route matches
2. MySQL optimization:
- Query log: identify slow queries
- Add indexes for frequently queried columns
- Use EXPLAIN on complex queries
- Enable MySQL query cache (if not MariaDB with query cache removed)
- Consider read replicas for large forums
3. PHP optimization:
- PHP 8.2+ (JIT enabled: opcache.jit=1255)
- Enable OPcache: opcache.enable=1, opcache.memory_consumption=256
- Increase memory_limit for media processing
- Use FastCGI (php-fpm) over mod_php/mod_cgi
4. Template optimization:
- Minimize template modifications (use hooks efficiently)
- Combine CSS/JS assets
- Enable template caching
- Use sprite sheets for icons
5. CDN:
- Offload static assets to CDN
- Use Cloudflare (APO for caching HTML)
- Serve images via Cloudflare Images or Imgix
General: For 50K+ posts, invest in dedicated server (not shared hosting). Vultr HF $48/mo or Hetzner $35/mo handle 200K posts comfortably.
Code:
1. File permissions:
chmod 755 /var/www/html
chmod 644 /var/www/html/*.php
chmod 700 /var/www/html/src/config.php
chmod 777 /var/www/html/data
chmod 777 /var/www/html/internal_data
2. .htaccess hardening:
<FilesMatch "config\.php|.*\.json|.*\.lock">
Deny from all
</FilesMatch>
Options -Indexes
ServerSignature Off
3. Admin CP security:
- Change admin path: $config['adminPath'] = 'hidden_admin';
- Two-factor auth (enforced for staff)
- IP whitelist for admin access
- Session timeout: 15 min
4. SQL injection prevention:
- Always use prepared statements (XF does this)
- Never use raw SQL with string concatenation
- Sanitize user input with XF validation ($input->filter())
5. XSS prevention:
- Use XF's template escaping: {$var} auto-escapes
- For raw HTML: {{ $var|raw }} (careful!)
- Content Security Policy header
6. CSRF:
- All forms include _xfToken
- Never disable CSRF checks
- Use POST for state-changing operations
7. Regular updates:
- Keep XF updated (security patches)
- Monitor xenforo.com/community for security announcements
- Subscribe to XF security mailing list
COMMON ISSUES & SOLUTIONS
| Issue | Symptom | Solution |
| White screen on install | PHP 8.2+ incompatibility | Check PHP error log, enable XF debugging mode |
| Add-on not showing | Invalid _metadata.json | Verify JSON format, rebuild add-on JSON in dev mode |
| Template not rendering | Template modification syntax error | Disable modification, check regex pattern |
| Slow page loads | MySQL queries unoptimized | Enable query log, add missing indexes |
| Can't login to ACP | Session issues or IP change | Clear cookies, check admin IP whitelist, rebuild session |
| Asset load failure | Broken file permissions | chmod -R 777 data/ internal_data/, rebuild |
| Email not sending | Mail config missing | Configure SMTP in ACP, test with debug mode |
| Search not indexing | Search engine needs rebuild | ACP → Tools → Rebuild Search Index |
ASK YOUR QUESTIONS
Code:
Post your XenForo 2 development questions below. Include:
- XenForo version
- PHP version
- What you're trying to achieve
- What you've tried
- Error messages (if any)
Community members and experienced devs will help you out.
Check the archives for previously answered questions.