Version {{ version }}
+{% trans "Settings page for My First Plugin" %}
+ +
+
+
+{% load i18n %}
+{% trans "Hello, world!" %}
+ + +{% url 'myPlugin:main' %} + + +{{ variable }} +{{ object.attribute }} +{{ object.method }} + + +{{ text|upper }} +{{ text|truncatewords:10 }} +{{ date|date:"Y-m-d" }} + + +{% if condition %} + +{% elif other_condition %} + +{% else %} + +{% endif %} + + +{% for item in items %} +{{ item }}
+{% empty %} +No items
+{% endfor %} +``` + +### 5. Static Files + +#### Organizing Static Files + +``` +static/ +└── pluginName/ + ├── css/ + │ └── style.css + ├── js/ + │ └── script.js + └── images/ + └── logo.png +``` + +#### Using Static Files in Templates + +```html +{% load static %} + + + + + + + + +
+```
+
+#### Collecting Static Files
+
+After installation, static files are automatically collected. To manually collect:
+
+```bash
+cd /usr/local/CyberCP
+python3 manage.py collectstatic --noinput
+```
+
+### 6. Database Models
+
+#### Creating Models
+
+```python
+# models.py
+from django.db import models
+
+class MyModel(models.Model):
+ name = models.CharField(max_length=255)
+ description = models.TextField(blank=True)
+ created_at = models.DateTimeField(auto_now_add=True)
+ updated_at = models.DateTimeField(auto_now=True)
+ is_active = models.BooleanField(default=True)
+
+ class Meta:
+ db_table = 'my_plugin_mymodel'
+ ordering = ['-created_at']
+ verbose_name = 'My Model'
+ verbose_name_plural = 'My Models'
+
+ def __str__(self):
+ return self.name
+```
+
+#### Using Models in Views
+
+```python
+from .models import MyModel
+
+@cyberpanel_login_required
+def list_items(request):
+ items = MyModel.objects.filter(is_active=True)
+ context = {'items': items}
+ return render(request, 'myPlugin/list.html', context)
+
+@cyberpanel_login_required
+def create_item(request):
+ if request.method == 'POST':
+ name = request.POST.get('name')
+ description = request.POST.get('description')
+ item = MyModel.objects.create(
+ name=name,
+ description=description
+ )
+ return redirect('myPlugin:list')
+ return render(request, 'myPlugin/create.html')
+```
+
+#### Database Migrations
+
+```bash
+# Create migrations
+cd /usr/local/CyberCP
+python3 manage.py makemigrations pluginName
+
+# Apply migrations
+python3 manage.py migrate pluginName
+
+# Show migration status
+python3 manage.py showmigrations pluginName
+```
+
+---
+
+## Advanced Features
+
+### 1. Forms & Validation
+
+#### Creating Forms
+
+```python
+# forms.py
+from django import forms
+
+class MyForm(forms.Form):
+ name = forms.CharField(
+ max_length=255,
+ required=True,
+ widget=forms.TextInput(attrs={'class': 'form-control'})
+ )
+ email = forms.EmailField(
+ required=True,
+ widget=forms.EmailInput(attrs={'class': 'form-control'})
+ )
+ description = forms.CharField(
+ required=False,
+ widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 5})
+ )
+```
+
+#### Using Forms in Views
+
+```python
+from .forms import MyForm
+
+@cyberpanel_login_required
+def my_form_view(request):
+ if request.method == 'POST':
+ form = MyForm(request.POST)
+ if form.is_valid():
+ # Process valid form data
+ name = form.cleaned_data['name']
+ email = form.cleaned_data['email']
+ # Save or process data
+ return JsonResponse({'success': True})
+ else:
+ # Return form errors
+ return JsonResponse({'success': False, 'errors': form.errors})
+ else:
+ form = MyForm()
+
+ context = {'form': form}
+ return render(request, 'myPlugin/form.html', context)
+```
+
+#### Rendering Forms in Templates
+
+```html
+
+```
+
+### 2. AJAX & API Endpoints
+
+#### Creating API Endpoints
+
+```python
+from django.http import JsonResponse
+from django.views.decorators.csrf import csrf_exempt
+from django.views.decorators.http import require_http_methods
+import json
+
+@cyberpanel_login_required
+@csrf_exempt # Only if not using CSRF token in AJAX
+@require_http_methods(["POST"])
+def api_endpoint(request):
+ try:
+ data = json.loads(request.body)
+ # Process data
+ result = {
+ 'success': True,
+ 'message': 'Operation completed',
+ 'data': data
+ }
+ return JsonResponse(result)
+ except Exception as e:
+ return JsonResponse({
+ 'success': False,
+ 'error': str(e)
+ }, status=400)
+```
+
+#### JavaScript AJAX Example
+
+```javascript
+function sendAjaxRequest(data) {
+ // Get CSRF token
+ const csrftoken = getCookie('csrftoken');
+
+ fetch('/plugins/myPlugin/api/', {
+ method: 'POST',
+ headers: {
+ 'X-CSRFToken': csrftoken,
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(data)
+ })
+ .then(response => response.json())
+ .then(data => {
+ if (data.success) {
+ console.log('Success:', data.message);
+ } else {
+ console.error('Error:', data.error);
+ }
+ })
+ .catch(error => {
+ console.error('Request failed:', error);
+ });
+}
+```
+
+### 3. File Uploads
+
+#### Handling File Uploads
+
+```python
+from django.core.files.storage import default_storage
+from django.core.files.base import ContentFile
+
+@cyberpanel_login_required
+def upload_file(request):
+ if request.method == 'POST' and request.FILES.get('file'):
+ uploaded_file = request.FILES['file']
+
+ # Validate file
+ if uploaded_file.size > 10 * 1024 * 1024: # 10MB limit
+ return JsonResponse({'success': False, 'error': 'File too large'})
+
+ # Save file
+ file_path = f'myPlugin/uploads/{uploaded_file.name}'
+ path = default_storage.save(file_path, ContentFile(uploaded_file.read()))
+
+ return JsonResponse({
+ 'success': True,
+ 'file_path': path
+ })
+
+ return JsonResponse({'success': False, 'error': 'No file provided'})
+```
+
+### 4. Logging
+
+#### Using CyberPanel's Logging System
+
+```python
+from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
+
+# Write to log file
+logging.writeToFile("Plugin message: Something happened")
+
+# Write error
+logging.writeToFile(f"Error: {str(exception)}", 1) # 1 = error level
+
+# Write with plugin name
+logging.writeToFile(f"[MyPlugin] Action completed successfully")
+```
+
+### 5. Background Tasks
+
+#### Using Subprocess for Long-Running Tasks
+
+```python
+import subprocess
+import threading
+
+def run_background_task(command):
+ """Run a command in the background"""
+ def task():
+ try:
+ result = subprocess.run(
+ command,
+ shell=True,
+ capture_output=True,
+ text=True
+ )
+ logging.writeToFile(f"Task completed: {result.stdout}")
+ except Exception as e:
+ logging.writeToFile(f"Task error: {str(e)}", 1)
+
+ thread = threading.Thread(target=task)
+ thread.daemon = True
+ thread.start()
+ return thread
+```
+
+---
+
+## Best Practices
+
+### 1. Code Organization
+
+- **Keep files under 500 lines**: Split large files into modules
+- **Use descriptive names**: Functions, variables, and classes should be self-documenting
+- **Follow PEP 8**: Python style guide
+- **Add comments**: Explain complex logic
+- **Modular structure**: Separate concerns (views, models, utils)
+
+### 2. Error Handling
+
+```python
+from django.http import JsonResponse
+from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
+
+@cyberpanel_login_required
+def my_view(request):
+ try:
+ # Your code here
+ result = perform_operation()
+ return JsonResponse({'success': True, 'data': result})
+ except ValueError as e:
+ logging.writeToFile(f"Validation error: {str(e)}", 1)
+ return JsonResponse({'success': False, 'error': str(e)}, status=400)
+ except Exception as e:
+ logging.writeToFile(f"Unexpected error: {str(e)}", 1)
+ return JsonResponse({'success': False, 'error': 'An error occurred'}, status=500)
+```
+
+### 3. Security Best Practices
+
+- **Always validate input**: Never trust user input
+- **Use parameterized queries**: When using raw SQL
+- **Sanitize output**: Escape HTML in templates
+- **Check permissions**: Verify user has access
+- **Use HTTPS**: For sensitive operations
+- **Rate limiting**: Prevent abuse
+- **CSRF protection**: Always include CSRF tokens
+
+### 4. Performance Optimization
+
+- **Database queries**: Use `select_related()` and `prefetch_related()`
+- **Caching**: Cache expensive operations
+- **Lazy loading**: Load data only when needed
+- **Pagination**: For large datasets
+- **Static files**: Minify CSS/JS in production
+
+### 5. Testing
+
+```python
+# tests.py
+from django.test import TestCase, Client
+from django.urls import reverse
+
+class MyPluginTests(TestCase):
+ def setUp(self):
+ self.client = Client()
+ # Set up test data
+
+ def test_main_view(self):
+ # Test main view
+ response = self.client.get(reverse('myPlugin:main'))
+ self.assertEqual(response.status_code, 200)
+
+ def test_api_endpoint(self):
+ # Test API endpoint
+ response = self.client.post(
+ reverse('myPlugin:api'),
+ data={'key': 'value'},
+ content_type='application/json'
+ )
+ self.assertEqual(response.status_code, 200)
+```
+
+---
+
+## Security Guidelines
+
+### 1. Input Validation
+
+```python
+import re
+from django.core.exceptions import ValidationError
+
+def validate_input(data):
+ """Validate and sanitize user input"""
+ if not data:
+ raise ValidationError("Input cannot be empty")
+
+ # Remove dangerous characters
+ data = re.sub(r'[<>"\']', '', data)
+
+ # Check length
+ if len(data) > 1000:
+ raise ValidationError("Input too long")
+
+ return data.strip()
+```
+
+### 2. SQL Injection Prevention
+
+**Always use Django ORM (recommended):**
+
+```python
+# ✅ GOOD - Using ORM
+items = MyModel.objects.filter(name=user_input)
+
+# ❌ BAD - Raw SQL with string formatting
+items = MyModel.objects.raw(f"SELECT * FROM table WHERE name = '{user_input}'")
+```
+
+**If using raw SQL, use parameterized queries:**
+
+```python
+from django.db import connection
+
+cursor = connection.cursor()
+cursor.execute("SELECT * FROM table WHERE name = %s", [user_input])
+```
+
+### 3. XSS Prevention
+
+**Django templates auto-escape by default:**
+
+```html
+
+{{ user_input }}
+
+
+{{ user_input|safe }}
+```
+
+**Only use `|safe` if you're certain the content is safe:**
+
+```python
+from django.utils.html import escape
+
+# Escape in Python
+safe_html = escape(user_input)
+```
+
+### 4. File Upload Security
+
+```python
+import os
+from django.core.exceptions import ValidationError
+
+ALLOWED_EXTENSIONS = ['.jpg', '.png', '.pdf']
+MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB
+
+def validate_uploaded_file(file):
+ """Validate uploaded file"""
+ # Check extension
+ ext = os.path.splitext(file.name)[1].lower()
+ if ext not in ALLOWED_EXTENSIONS:
+ raise ValidationError(f"File type {ext} not allowed")
+
+ # Check size
+ if file.size > MAX_FILE_SIZE:
+ raise ValidationError("File too large")
+
+ # Check content type
+ if file.content_type not in ['image/jpeg', 'image/png', 'application/pdf']:
+ raise ValidationError("Invalid file type")
+
+ return True
+```
+
+---
+
+## Testing & Debugging
+
+### 1. Debugging Tools
+
+#### Enable Django Debug Mode (Development Only)
+
+```python
+# In your view
+import logging
+logger = logging.getLogger(__name__)
+
+def my_view(request):
+ logger.debug("Debug message")
+ logger.info("Info message")
+ logger.warning("Warning message")
+ logger.error("Error message")
+```
+
+#### Check Logs
+
+```bash
+# CyberPanel logs
+tail -f /usr/local/lscp/logs/error.log
+
+# Django logs (if configured)
+tail -f /var/log/cyberpanel/error.log
+
+# Plugin-specific logs
+tail -f /home/cyberpanel/plugin_logs/myPlugin.log
+```
+
+### 2. Common Issues & Solutions
+
+#### Template Not Found
+
+**Problem:** `TemplateDoesNotExist` error
+
+**Solutions:**
+- Check template path: `templates/pluginName/template.html`
+- Verify template name in `render()` call
+- Ensure template extends `baseTemplate/index.html`
+- Run `python3 manage.py collectstatic`
+
+#### URL Not Found
+
+**Problem:** 404 error when accessing plugin URL
+
+**Solutions:**
+- Verify URL pattern in `urls.py`
+- Check `app_name` is set correctly
+- Ensure plugin is in `INSTALLED_APPS`
+- Restart CyberPanel: `systemctl restart lscpd`
+
+#### Import Errors
+
+**Problem:** `ImportError` or `ModuleNotFoundError`
+
+**Solutions:**
+- Check Python syntax: `python3 -m py_compile views.py`
+- Verify `__init__.py` exists
+- Check import paths
+- Ensure plugin is installed correctly
+
+#### Static Files Not Loading
+
+**Problem:** CSS/JS/images not appearing
+
+**Solutions:**
+- Run `python3 manage.py collectstatic --noinput`
+- Check static file paths in templates
+- Verify files exist in `static/pluginName/`
+- Clear browser cache
+
+---
+
+## Packaging & Distribution
+
+### 1. Creating Plugin Package
+
+```bash
+# Navigate to plugin directory
+cd /home/cyberpanel/plugins/myPlugin
+
+# Create ZIP file
+zip -r myPlugin-v1.0.0.zip . \
+ -x "*.pyc" \
+ -x "__pycache__/*" \
+ -x "*.log" \
+ -x ".git/*" \
+ -x ".DS_Store"
+```
+
+### 2. Plugin Distribution Checklist
+
+- [ ] Plugin tested and working
+- [ ] All required files included
+- [ ] `meta.xml` is valid and complete
+- [ ] README.md with installation instructions
+- [ ] No sensitive data (passwords, API keys)
+- [ ] Proper file permissions
+- [ ] Version number updated
+- [ ] Documentation complete
+
+### 3. Version Management
+
+**Semantic Versioning:**
+
+- **MAJOR.MINOR.PATCH** (e.g., 1.2.3)
+- **MAJOR**: Breaking changes
+- **MINOR**: New features, backward compatible
+- **PATCH**: Bug fixes, backward compatible
+
+**Update version in:**
+- `meta.xml`
+- `views.py` (if version displayed)
+- `README.md`
+- Git tags (if using version control)
+
+---
+
+## Troubleshooting
+
+### Installation Issues
+
+**Plugin not appearing in list:**
+- Check `meta.xml` format and validity
+- Verify plugin directory exists in `/home/cyberpanel/plugins/`
+- Check file permissions
+- Review CyberPanel logs
+
+**Installation fails:**
+- Check Python syntax errors
+- Verify all required files exist
+- Check file permissions
+- Review installation logs
+- Ensure sufficient disk space
+
+### Runtime Issues
+
+**Plugin page not loading:**
+- Verify URL routing
+- Check authentication decorator
+- Review template paths
+- Check for JavaScript errors
+- Verify plugin is enabled
+
+**Database errors:**
+- Run migrations: `python3 manage.py migrate pluginName`
+- Check database permissions
+- Verify model definitions
+- Review migration files
+
+**Static files missing:**
+- Run `python3 manage.py collectstatic`
+- Check static file paths
+- Verify file permissions
+- Clear browser cache
+
+---
+
+## Examples & References
+
+### Reference Plugins
+
+1. **examplePlugin**: Basic plugin structure
+ - Location: `/usr/local/CyberCP/examplePlugin/`
+ - URL: `/plugins/examplePlugin/`
+
+2. **testPlugin**: Comprehensive example
+ - Location: `/usr/local/CyberCP/testPlugin/`
+ - URL: `/plugins/testPlugin/`
+ - **Author:** usmannasir
+
+3. **discordWebhooks**: Discord webhook integration plugin
+ - Location: `/usr/local/CyberCP/discordWebhooks/` (if installed)
+ - URL: `/plugins/discordWebhooks/`
+ - **Author:** Master3395
+
+### Useful Resources
+
+- **CyberPanel Documentation**: https://cyberpanel.net/KnowledgeBase/
+- **Django Documentation**: https://docs.djangoproject.com/
+- **Python Documentation**: https://docs.python.org/
+- **CyberPanel GitHub**: https://github.com/usmannasir/cyberpanel
+- **Plugin Repository**: https://github.com/master3395/cyberpanel-plugins
+
+### Code Examples Repository
+
+Check the `examplePlugin` and `testPlugin` directories in CyberPanel for complete working examples.
+
+---
+
+## Conclusion
+
+This guide provides comprehensive information for developing CyberPanel plugins. Start with a simple plugin and gradually add more features as you become familiar with the system.
+
+### Quick Start Checklist
+
+1. ✅ Create plugin directory structure
+2. ✅ Create `meta.xml` with required fields
+3. ✅ Create `urls.py` with URL patterns
+4. ✅ Create `views.py` with view functions
+5. ✅ Create templates extending `baseTemplate/index.html`
+6. ✅ Test plugin locally
+7. ✅ Install via CyberPanel UI
+8. ✅ Verify plugin works correctly
+
+### Getting Help
+
+- Review existing plugins for examples
+- Check CyberPanel community forum
+- Review Django documentation
+- Examine CyberPanel source code
+- Create GitHub issues for bugs
+
+---
+
+**Happy Plugin Development!**
+
+**Author:** master3395
+**Last Updated:** 2026-01-04
+**Version:** 2.0.0
diff --git a/pluginHolder/templates/pluginHolder/help.html b/pluginHolder/templates/pluginHolder/help.html
new file mode 100644
index 000000000..d822febbc
--- /dev/null
+++ b/pluginHolder/templates/pluginHolder/help.html
@@ -0,0 +1,658 @@
+{% extends "baseTemplate/index.html" %}
+{% load i18n %}
+{% load static %}
+
+{% block title %}{% trans "Plugin Development Help - CyberPanel" %}{% endblock %}
+
+{% block header_scripts %}
+
+{% endblock %}
+
+{% block content %}
+{% trans "Comprehensive guide to creating plugins for CyberPanel. Learn how to build, package, and distribute your own plugins." %}
+{% trans "CyberPanel's plugin system allows developers to extend the control panel's functionality with custom features. Plugins integrate seamlessly with CyberPanel's Django-based architecture, providing access to the full power of the platform while maintaining security and consistency." %}
+ +/home/cyberpanel/plugins/
+ /usr/local/CyberCP/
+ # Navigate to plugins directory
+cd /home/cyberpanel/plugins
+
+# Create your plugin directory
+mkdir myFirstPlugin
+cd myFirstPlugin
+
+# Create required subdirectories
+mkdir -p templates/myFirstPlugin
+mkdir -p static/myFirstPlugin/css
+mkdir -p static/myFirstPlugin/js
+mkdir -p migrations
+
+ <?xml version="1.0" encoding="UTF-8"?>
+<cyberpanelPluginConfig>
+ <name>My First Plugin</name>
+ <type>Utility</type>
+ <description>A simple example plugin</description>
+ <version>1.0.0</version>
+ <url>/plugins/myFirstPlugin/</url>
+ <settings_url>/plugins/myFirstPlugin/settings/</settings_url>
+</cyberpanelPluginConfig>
+
+ from django.urls import path
+from . import views
+
+app_name = 'myFirstPlugin'
+
+urlpatterns = [
+ path('', views.main_view, name='main'),
+ path('settings/', views.settings_view, name='settings'),
+]
+
+ from django.shortcuts import render, redirect
+from functools import wraps
+
+def cyberpanel_login_required(view_func):
+ """Custom decorator for CyberPanel session authentication"""
+ @wraps(view_func)
+ def _wrapped_view(request, *args, **kwargs):
+ try:
+ userID = request.session['userID']
+ return view_func(request, *args, **kwargs)
+ except KeyError:
+ from loginSystem.views import loadLoginPage
+ return redirect(loadLoginPage)
+ return _wrapped_view
+
+@cyberpanel_login_required
+def main_view(request):
+ context = {
+ 'plugin_name': 'My First Plugin',
+ 'version': '1.0.0'
+ }
+ return render(request, 'myFirstPlugin/main.html', context)
+
+ {% trans "Templates must extend baseTemplate/index.html:" %}
+{% extends "baseTemplate/index.html" %}
+{% load static %}
+{% load i18n %}
+
+{% block title %}
+ My First Plugin - {% trans "CyberPanel" %}
+{% endblock %}
+
+{% block content %}
+ <div class="container">
+ <h1>{{ plugin_name }}</h1>
+ <p>Version {{ version }}</p>
+ </div>
+{% endblock %}
+
+ __init__.py - {% trans "Required" %} - {% trans "Python package marker" %}meta.xml - {% trans "Required" %} - {% trans "Plugin metadata" %}urls.py - {% trans "Required" %} - {% trans "URL routing" %}views.py - {% trans "Required" %} - {% trans "View functions" %}models.py - {% trans "Optional" %} - {% trans "Database models" %}forms.py - {% trans "Optional" %} - {% trans "Django forms" %}utils.py - {% trans "Optional" %} - {% trans "Utility functions" %}templates/ - {% trans "Optional" %} - {% trans "HTML templates" %}static/ - {% trans "Optional" %} - {% trans "CSS, JS, images" %}{% trans "Always use the cyberpanel_login_required decorator:" %}
+@cyberpanel_login_required
+def my_view(request):
+ # Your view code
+ pass
+
+ from django.urls import path
+from . import views
+
+app_name = 'myPlugin'
+
+urlpatterns = [
+ path('', views.main_view, name='main'),
+ path('item/<int:item_id>/', views.item_detail, name='item_detail'),
+]
+
+ {% trans "Always extend baseTemplate/index.html:" %}
+{% extends "baseTemplate/index.html" %}
+{% load static %}
+{% load i18n %}
+
+ from django.db import models
+
+class MyModel(models.Model):
+ name = models.CharField(max_length=255)
+ created_at = models.DateTimeField(auto_now_add=True)
+
+ class Meta:
+ db_table = 'my_plugin_mymodel'
+
+ from django import forms
+
+class MyForm(forms.Form):
+ name = forms.CharField(max_length=255, required=True)
+ email = forms.EmailField(required=True)
+
+ from django.http import JsonResponse
+
+@cyberpanel_login_required
+def api_endpoint(request):
+ data = {'status': 'success'}
+ return JsonResponse(data)
+
+ # Check Python syntax
+python3 -m py_compile views.py
+
+# Check XML validity
+xmllint --noout meta.xml
+
+# View logs
+tail -f /usr/local/lscp/logs/error.log
+
+ cd /home/cyberpanel/plugins/myPlugin
+zip -r myPlugin-v1.0.0.zip . \
+ -x "*.pyc" \
+ -x "__pycache__/*" \
+ -x "*.log"
+
+ /usr/local/CyberCP/examplePlugin//plugins/examplePlugin//usr/local/CyberCP/testPlugin//plugins/testPlugin//usr/local/CyberCP/discordWebhooks//plugins/discordWebhooks/+ {% trans "Author" %}: master3395 | + {% trans "Version" %}: 2.0.0 | + {% trans "Last Updated" %}: 2026-01-04 +
+| {% trans "Name" %} | -{% trans "Type" %} | -{% trans "Description" %} | +{% trans "Plugin Name" %} | {% trans "Version" %} | +{% trans "Modify Date" %} | +{% trans "Status" %} | +{% trans "Action" %} | +{% trans "Active" %} | +{% trans "Help" %} | +{% trans "About" %} | {{ plugin.name }} | -- {{ plugin.type }} - | -{{ plugin.desc }} | {{ plugin.version }} | ++ + {{ plugin.modify_date|default:"N/A" }} + + | ++ {% if plugin.installed %} + {% trans "Installed" %} + {% else %} + {% trans "Not Installed" %} + {% endif %} + | +
+
+ {% if plugin.installed %}
+ {% if plugin.enabled %}
+
+ {% else %}
+
+ {% endif %}
+
+ {% else %}
+
+ {% endif %}
+
+ |
+ + {% if plugin.installed %} + {% if plugin.enabled %} + + {% else %} + + {% endif %} + {% else %} + - + {% endif %} + | ++ + {% trans "Help" %} + + | ++ + {% trans "About" %} + + | {% endfor %}
|---|
{% trans "The versions displayed here represent the latest plugins from the CyberPanel Plugin Store repository. They may or may not represent the latest available versions. Additionally, the plugin repository may only contain plugins released within the last few months." %}
++ + {% trans "Use at Your Own Risk" %} +
+{% trans "The plugins displayed here are contributed by both the CyberPanel Developers and independent third parties. We make no guarantees that the plugins available here are functional, tested, or compatible with your system. You are encouraged to read the information found in the help and about links for each plugin before attempting the installation." %}
+