{% trans "Step 1: Create Plugin Directory Structure" %}
# 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
{% trans "Step 2: Create meta.xml (REQUIRED)" %}
<?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>
{% trans "Required: Category (type)" %}: {% trans "The <type> field is required. See the Plugin Categories section below for valid options. Plugins without a valid category will not appear in the Plugin Store." %}
{% trans "Step 3: Create urls.py" %}
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'),
]
{% trans "Step 4: Create views.py" %}
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 "Step 5: Create Templates" %}
{% trans "Templates must extend baseTemplate/index.html:" %}
{% verbatim %}
{% extends "baseTemplate/index.html" %}
{% load static %}
{% load i18n %}
{% block title %}
My First Plugin - {% trans "CyberPanel" %}
{% endblock %}
{% block content %}
{{ plugin_name }}
Version {{ version }}
{% endblock %}
{% endverbatim %}
{% trans "Important" %}: {% trans "Always use the @cyberpanel_login_required decorator for all views to ensure users are authenticated." %}