Skip to content
Open
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ themes/
dist/
asset/static

# Local editor checkout fetched during build
exelearning/
# Local editor checkout fetched during build (anchored to repo root so it
# does not also ignore view/exelearning/ or similar subtrees).
/exelearning/
.env
.playwright-mcp/
31 changes: 30 additions & 1 deletion Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,36 @@ public function getConfigForm(PhpRenderer $renderer)

$formHtml = $renderer->formCollection($form, false);

return $this->renderEditorStatusSection($renderer, $settings) . $formHtml;
return $this->renderEditorStatusSection($renderer, $settings)
. $this->renderStylesSection($renderer)
. $formHtml;
}

/**
* Render a short section pointing to the dedicated Styles admin page.
*/
protected function renderStylesSection(PhpRenderer $renderer): string
{
$translate = function ($text) use ($renderer) {
return $renderer->translate($text);
};
$stylesUrl = $renderer->url('admin/exelearning-styles');
$html = '<fieldset id="exelearning-styles-link">';
$html .= '<legend>' . $renderer->escapeHtml($translate('Styles')) . '</legend>'; // @translate
$html .= '<div class="field"><div class="field-meta">';
$html .= '<label>' . $renderer->escapeHtml($translate('Style management')) . '</label>'; // @translate
$html .= '</div><div class="inputs">';
$html .= '<a class="button" href="' . $renderer->escapeHtmlAttr($stylesUrl) . '">';
$html .= $renderer->escapeHtml($translate('Open styles page')); // @translate
$html .= '</a>';
$html .= '<p class="explanation">';
$html .= $renderer->escapeHtml($translate( // @translate
'Upload eXeLearning style packages, enable/disable built-in styles, '
. 'and control the "Block user-imported styles" policy from a dedicated page.'
));
$html .= '</p>';
$html .= '</div></div></fieldset>';
return $html;
}

/**
Expand Down
72 changes: 72 additions & 0 deletions config/module.config.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,29 @@
Controller\ApiController::class => Controller\ApiControllerFactory::class,
Controller\EditorController::class => Controller\EditorControllerFactory::class,
Controller\ContentController::class => Controller\ContentControllerFactory::class,
Controller\StylesServeController::class => Controller\StylesServeControllerFactory::class,
Controller\Admin\StylesController::class => Controller\Admin\StylesControllerFactory::class,
],
'aliases' => [
'ExeLearning\Controller\Editor' => Controller\EditorController::class,
'ExeLearning\Controller\Api' => Controller\ApiController::class,
'ExeLearning\Controller\Content' => Controller\ContentController::class,
'ExeLearning\Controller\StylesServe' => Controller\StylesServeController::class,
'ExeLearning\Controller\Admin\Styles' => Controller\Admin\StylesController::class,
],
],

'service_manager' => [
'factories' => [
Service\ElpFileService::class => Service\ElpFileServiceFactory::class,
Service\StylesService::class => Service\StylesServiceFactory::class,
],
],

'form_elements' => [
'invokables' => [
Form\ConfigForm::class => Form\ConfigForm::class,
Form\StylesUploadForm::class => Form\StylesUploadForm::class,
],
],

Expand Down Expand Up @@ -74,6 +80,19 @@
],
],
],
'exelearning-styles-serve' => [
'type' => Regex::class,
'options' => [
'regex' => '/exelearning/styles/(?<slug>[a-z0-9-]+)(?:/(?<file>.*))?',
'spec' => '/exelearning/styles/%slug%/%file%',
'defaults' => [
'__NAMESPACE__' => 'ExeLearning\Controller',
'controller' => 'StylesServe',
'action' => 'serve',
'file' => 'style.css',
],
],
],
'exelearning-api' => [
'type' => Literal::class,
'options' => [
Expand Down Expand Up @@ -180,11 +199,64 @@
],
],
],
'exelearning-styles' => [
'type' => Literal::class,
'options' => [
'route' => '/exelearning/styles',
'defaults' => [
'__NAMESPACE__' => 'ExeLearning\Controller\Admin',
'controller' => 'Styles',
'action' => 'index',
],
],
'may_terminate' => true,
'child_routes' => [
'toggle-builtin' => [
'type' => Literal::class,
'options' => [
'route' => '/toggle-builtin',
'defaults' => ['action' => 'toggleBuiltin'],
],
],
'toggle-uploaded' => [
'type' => Literal::class,
'options' => [
'route' => '/toggle-uploaded',
'defaults' => ['action' => 'toggleUploaded'],
],
],
'delete' => [
'type' => Literal::class,
'options' => [
'route' => '/delete',
'defaults' => ['action' => 'delete'],
],
],
'toggle-block-import' => [
'type' => Literal::class,
'options' => [
'route' => '/toggle-block-import',
'defaults' => ['action' => 'toggleBlockImport'],
],
],
],
],
],
],
],
],

'navigation' => [
'AdminModule' => [
[
'label' => 'eXeLearning styles', // @translate
'route' => 'admin/exelearning-styles',
'resource' => 'ExeLearning\Controller\Admin\Styles',
'privilege' => 'index',
],
],
],

'translator' => [
'translation_file_patterns' => [
[
Expand Down
8 changes: 8 additions & 0 deletions data/nginx-exelearning.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ location ^~ /exelearning/content/ {
try_files $uri /index.php$is_args$args;
}

# Route admin-uploaded style asset requests to the PHP serve controller.
# Without this prefix location, the default static-files regex that
# catches .css/.js/.png in the Omeka nginx vhost short-circuits these
# URLs to the filesystem and 404s before they reach Laminas.
location ^~ /exelearning/styles/ {
try_files $uri /index.php$is_args$args;
}

# SECURITY: Block direct access to extracted eXeLearning files
location ^~ /files/exelearning/ {
return 403;
Expand Down
Binary file modified language/es.mo
Binary file not shown.
126 changes: 126 additions & 0 deletions language/es.po
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,129 @@ msgstr "No se pudo hacer copia de seguridad de la instalación actual del editor
#: src/Service/StaticEditorInstaller.php
msgid "Failed to copy editor files to the module directory."
msgstr "Error al copiar los archivos del editor al directorio del módulo."

#: view/exelearning/admin/styles/index.phtml
msgid "eXeLearning styles"
msgstr "Estilos de eXeLearning"

#: view/exelearning/admin/styles/index.phtml
msgid "Upload eXeLearning style packages and control which styles the embedded editor exposes. Disabled built-ins are hidden from the editor selector; uploaded styles can be enabled, disabled, or deleted at any time."
msgstr "Sube paquetes de estilos de eXeLearning y controla qué estilos expone el editor integrado. Los estilos integrados deshabilitados quedan ocultos en el selector del editor; los estilos subidos se pueden habilitar, deshabilitar o eliminar en cualquier momento."

#: view/exelearning/admin/styles/index.phtml
msgid "Import policy"
msgstr "Política de importación"

#: view/exelearning/admin/styles/index.phtml
#: src/Controller/Admin/StylesController.php
msgid "Block user-imported styles"
msgstr "Bloquear estilos importados por el usuario"

#: view/exelearning/admin/styles/index.phtml
msgid "When enabled, the embedded editor hides the \"User styles\" tab and silently refuses to install a style bundled inside an imported .elpx project. This mirrors the eXeLearning ONLINE_THEMES_INSTALL=false behavior."
msgstr "Cuando está activado, el editor integrado oculta la pestaña «Estilos del usuario» y rechaza de forma silenciosa instalar un estilo incluido en un proyecto .elpx importado. Equivale al comportamiento de eXeLearning ONLINE_THEMES_INSTALL=false."

#: view/exelearning/admin/styles/index.phtml
msgid "Currently blocking — click to allow imports"
msgstr "Actualmente bloqueando — pulsa para permitir importaciones"

#: view/exelearning/admin/styles/index.phtml
msgid "Currently allowing — click to block imports"
msgstr "Actualmente permitiendo — pulsa para bloquear importaciones"

#: view/exelearning/admin/styles/index.phtml
msgid "Upload a new style"
msgstr "Subir un estilo nuevo"

#: src/Form/StylesUploadForm.php
msgid "Style ZIP package(s)"
msgstr "Paquete(s) ZIP de estilo"

#: src/Form/StylesUploadForm.php
msgid "Select one or more .zip files containing a valid config.xml."
msgstr "Selecciona uno o más archivos .zip con un config.xml válido."

#: src/Form/StylesUploadForm.php
msgid "Upload styles"
msgstr "Subir estilos"

#: view/exelearning/admin/styles/index.phtml
msgid "Maximum file size: %s. Only .zip packages containing a valid config.xml are accepted."
msgstr "Tamaño máximo: %s. Solo se aceptan paquetes .zip con un config.xml válido."

#: view/exelearning/admin/styles/index.phtml
msgid "Uploaded styles"
msgstr "Estilos subidos"

#: view/exelearning/admin/styles/index.phtml
msgid "No uploaded styles yet."
msgstr "Todavía no hay estilos subidos."

#: view/exelearning/admin/styles/index.phtml
msgid "Built-in styles"
msgstr "Estilos integrados"

#: view/exelearning/admin/styles/index.phtml
msgid "Built-in styles are not available because the embedded editor is not installed."
msgstr "Los estilos integrados no están disponibles porque el editor integrado no está instalado."

#: view/exelearning/admin/styles/index.phtml
msgid "Title"
msgstr "Título"

#: view/exelearning/admin/styles/index.phtml
msgid "Id"
msgstr "Id"

#: view/exelearning/admin/styles/index.phtml
msgid "Version"
msgstr "Versión"

#: view/exelearning/admin/styles/index.phtml
msgid "Enabled"
msgstr "Habilitado"

#: view/exelearning/admin/styles/index.phtml
msgid "Actions"
msgstr "Acciones"

#: view/exelearning/admin/styles/index.phtml
msgid "Enable"
msgstr "Habilitar"

#: view/exelearning/admin/styles/index.phtml
msgid "Disable"
msgstr "Deshabilitar"

#: view/exelearning/admin/styles/index.phtml
msgid "Delete"
msgstr "Eliminar"

#: view/exelearning/admin/styles/index.phtml
msgid "Delete this style? This cannot be undone."
msgstr "¿Eliminar este estilo? Esta acción no se puede deshacer."

#: src/Controller/Admin/StylesController.php
msgid "Style \"%s\" installed."
msgstr "Estilo «%s» instalado."

#: src/Controller/Admin/StylesController.php
msgid "Style deleted."
msgstr "Estilo eliminado."

#: Module.php
msgid "Styles"
msgstr "Estilos"

#: Module.php
msgid "Style management"
msgstr "Gestión de estilos"

#: Module.php
msgid "Open styles page"
msgstr "Abrir página de estilos"

#: Module.php
msgid "Upload eXeLearning style packages, enable/disable built-in styles, and control the \"Block user-imported styles\" policy from a dedicated page."
msgstr "Sube paquetes de estilos de eXeLearning, habilita o deshabilita los estilos integrados y controla la política «Bloquear estilos importados por el usuario» desde una página dedicada."

Loading