Process plugins administration page through Slim controllers
This commit is contained in:
parent
78657347c5
commit
1b8620b1ad
13 changed files with 312 additions and 62 deletions
|
@ -88,7 +88,12 @@ public function build(): ShaarliContainer
|
||||||
};
|
};
|
||||||
|
|
||||||
$container['pluginManager'] = function (ShaarliContainer $container): PluginManager {
|
$container['pluginManager'] = function (ShaarliContainer $container): PluginManager {
|
||||||
return new PluginManager($container->conf);
|
$pluginManager = new PluginManager($container->conf);
|
||||||
|
|
||||||
|
// FIXME! Configuration is already injected
|
||||||
|
$pluginManager->load($container->conf->get('general.enabled_plugins'));
|
||||||
|
|
||||||
|
return $pluginManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
$container['formatterFactory'] = function (ShaarliContainer $container): FormatterFactory {
|
$container['formatterFactory'] = function (ShaarliContainer $container): FormatterFactory {
|
||||||
|
|
98
application/front/controller/admin/PluginsController.php
Normal file
98
application/front/controller/admin/PluginsController.php
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Shaarli\Front\Controller\Admin;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use Slim\Http\Request;
|
||||||
|
use Slim\Http\Response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PluginsController
|
||||||
|
*
|
||||||
|
* Slim controller used to handle Shaarli plugins configuration page (display + save new config).
|
||||||
|
*/
|
||||||
|
class PluginsController extends ShaarliAdminController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* GET /admin/plugins - Displays the configuration page
|
||||||
|
*/
|
||||||
|
public function index(Request $request, Response $response): Response
|
||||||
|
{
|
||||||
|
$pluginMeta = $this->container->pluginManager->getPluginsMeta();
|
||||||
|
|
||||||
|
// Split plugins into 2 arrays: ordered enabled plugins and disabled.
|
||||||
|
$enabledPlugins = array_filter($pluginMeta, function ($v) {
|
||||||
|
return ($v['order'] ?? false) !== false;
|
||||||
|
});
|
||||||
|
$enabledPlugins = load_plugin_parameter_values($enabledPlugins, $this->container->conf->get('plugins', []));
|
||||||
|
uasort(
|
||||||
|
$enabledPlugins,
|
||||||
|
function ($a, $b) {
|
||||||
|
return $a['order'] - $b['order'];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
$disabledPlugins = array_filter($pluginMeta, function ($v) {
|
||||||
|
return ($v['order'] ?? false) === false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->assignView('enabledPlugins', $enabledPlugins);
|
||||||
|
$this->assignView('disabledPlugins', $disabledPlugins);
|
||||||
|
$this->assignView(
|
||||||
|
'pagetitle',
|
||||||
|
t('Plugin Administration') .' - '. $this->container->conf->get('general.title', 'Shaarli')
|
||||||
|
);
|
||||||
|
|
||||||
|
return $response->write($this->render('pluginsadmin'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST /admin/plugins - Update Shaarli's configuration
|
||||||
|
*/
|
||||||
|
public function save(Request $request, Response $response): Response
|
||||||
|
{
|
||||||
|
$this->checkToken($request);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$parameters = $request->getParams() ?? [];
|
||||||
|
|
||||||
|
$this->executeHooks($parameters);
|
||||||
|
|
||||||
|
if (isset($parameters['parameters_form'])) {
|
||||||
|
unset($parameters['parameters_form']);
|
||||||
|
foreach ($parameters as $param => $value) {
|
||||||
|
$this->container->conf->set('plugins.'. $param, escape($value));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->container->conf->set('general.enabled_plugins', save_plugin_config($parameters));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->container->conf->write($this->container->loginManager->isLoggedIn());
|
||||||
|
$this->container->history->updateSettings();
|
||||||
|
|
||||||
|
$this->saveSuccessMessage(t('Setting successfully saved.'));
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->saveErrorMessage(
|
||||||
|
t('ERROR while saving plugin configuration: ') . PHP_EOL . $e->getMessage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->redirect($response, '/admin/plugins');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed[] $data Variables passed to the template engine
|
||||||
|
*
|
||||||
|
* @return mixed[] Template data after active plugins render_picwall hook execution.
|
||||||
|
*/
|
||||||
|
protected function executeHooks(array $data): array
|
||||||
|
{
|
||||||
|
$this->container->pluginManager->executeHooks(
|
||||||
|
'save_plugin_parameters',
|
||||||
|
$data
|
||||||
|
);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,7 @@ class PluginManager
|
||||||
*
|
*
|
||||||
* @var array $authorizedPlugins
|
* @var array $authorizedPlugins
|
||||||
*/
|
*/
|
||||||
private $authorizedPlugins;
|
private $authorizedPlugins = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of loaded plugins.
|
* List of loaded plugins.
|
||||||
|
|
|
@ -43,7 +43,7 @@ http://<replace_domain>/admin/export
|
||||||
http://<replace_domain>/admin/import
|
http://<replace_domain>/admin/import
|
||||||
http://<replace_domain>/login
|
http://<replace_domain>/login
|
||||||
http://<replace_domain>/picture-wall
|
http://<replace_domain>/picture-wall
|
||||||
http://<replace_domain>/?do=pluginadmin
|
http://<replace_domain>/admin/plugins
|
||||||
http://<replace_domain>/tags/cloud
|
http://<replace_domain>/tags/cloud
|
||||||
http://<replace_domain>/tags/list
|
http://<replace_domain>/tags/list
|
||||||
```
|
```
|
||||||
|
|
54
index.php
54
index.php
|
@ -584,60 +584,14 @@ function renderPage($conf, $pluginManager, $bookmarkService, $history, $sessionM
|
||||||
|
|
||||||
// Plugin administration page
|
// Plugin administration page
|
||||||
if ($targetPage == Router::$PAGE_PLUGINSADMIN) {
|
if ($targetPage == Router::$PAGE_PLUGINSADMIN) {
|
||||||
$pluginMeta = $pluginManager->getPluginsMeta();
|
header('Location: ./admin/plugins');
|
||||||
|
|
||||||
// Split plugins into 2 arrays: ordered enabled plugins and disabled.
|
|
||||||
$enabledPlugins = array_filter($pluginMeta, function ($v) {
|
|
||||||
return $v['order'] !== false;
|
|
||||||
});
|
|
||||||
// Load parameters.
|
|
||||||
$enabledPlugins = load_plugin_parameter_values($enabledPlugins, $conf->get('plugins', array()));
|
|
||||||
uasort(
|
|
||||||
$enabledPlugins,
|
|
||||||
function ($a, $b) {
|
|
||||||
return $a['order'] - $b['order'];
|
|
||||||
}
|
|
||||||
);
|
|
||||||
$disabledPlugins = array_filter($pluginMeta, function ($v) {
|
|
||||||
return $v['order'] === false;
|
|
||||||
});
|
|
||||||
|
|
||||||
$PAGE->assign('enabledPlugins', $enabledPlugins);
|
|
||||||
$PAGE->assign('disabledPlugins', $disabledPlugins);
|
|
||||||
$PAGE->assign('pagetitle', t('Plugin administration') .' - '. $conf->get('general.title', 'Shaarli'));
|
|
||||||
$PAGE->renderPage('pluginsadmin');
|
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plugin administration form action
|
// Plugin administration form action
|
||||||
if ($targetPage == Router::$PAGE_SAVE_PLUGINSADMIN) {
|
if ($targetPage == Router::$PAGE_SAVE_PLUGINSADMIN) {
|
||||||
try {
|
// This route is no longer supported in legacy mode
|
||||||
if (isset($_POST['parameters_form'])) {
|
header('Location: ./admin/plugins');
|
||||||
$pluginManager->executeHooks('save_plugin_parameters', $_POST);
|
|
||||||
unset($_POST['parameters_form']);
|
|
||||||
foreach ($_POST as $param => $value) {
|
|
||||||
$conf->set('plugins.'. $param, escape($value));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$conf->set('general.enabled_plugins', save_plugin_config($_POST));
|
|
||||||
}
|
|
||||||
$conf->write($loginManager->isLoggedIn());
|
|
||||||
$history->updateSettings();
|
|
||||||
} catch (Exception $e) {
|
|
||||||
error_log(
|
|
||||||
'ERROR while saving plugin configuration:.' . PHP_EOL .
|
|
||||||
$e->getMessage()
|
|
||||||
);
|
|
||||||
|
|
||||||
// TODO: do not handle exceptions/errors in JS.
|
|
||||||
echo '<script>alert("'
|
|
||||||
. $e->getMessage()
|
|
||||||
.'");document.location=\'./?do='
|
|
||||||
. Router::$PAGE_PLUGINSADMIN
|
|
||||||
.'\';</script>';
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
header('Location: ./?do='. Router::$PAGE_PLUGINSADMIN);
|
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1022,6 +976,8 @@ function install($conf, $sessionManager, $loginManager)
|
||||||
$this->post('/admin/export', '\Shaarli\Front\Controller\Admin\ExportController:export');
|
$this->post('/admin/export', '\Shaarli\Front\Controller\Admin\ExportController:export');
|
||||||
$this->get('/admin/import', '\Shaarli\Front\Controller\Admin\ImportController:index');
|
$this->get('/admin/import', '\Shaarli\Front\Controller\Admin\ImportController:index');
|
||||||
$this->post('/admin/import', '\Shaarli\Front\Controller\Admin\ImportController:import');
|
$this->post('/admin/import', '\Shaarli\Front\Controller\Admin\ImportController:import');
|
||||||
|
$this->get('/admin/plugins', '\Shaarli\Front\Controller\Admin\PluginsController:index');
|
||||||
|
$this->post('/admin/plugins', '\Shaarli\Front\Controller\Admin\PluginsController:save');
|
||||||
|
|
||||||
$this->get('/links-per-page', '\Shaarli\Front\Controller\Admin\SessionFilterController:linksPerPage');
|
$this->get('/links-per-page', '\Shaarli\Front\Controller\Admin\SessionFilterController:linksPerPage');
|
||||||
$this->get('/visibility/{visibility}', '\Shaarli\Front\Controller\Admin\SessionFilterController:visibility');
|
$this->get('/visibility/{visibility}', '\Shaarli\Front\Controller\Admin\SessionFilterController:visibility');
|
||||||
|
|
|
@ -21,7 +21,7 @@ The directory structure should look like:
|
||||||
|
|
||||||
To enable the plugin, you can either:
|
To enable the plugin, you can either:
|
||||||
|
|
||||||
* enable it in the plugins administration page (`?do=pluginadmin`).
|
* enable it in the plugins administration page (`/admin/plugins`).
|
||||||
* add `wallabag` to your list of enabled plugins in `data/config.json.php` (`general.enabled_plugins` section).
|
* add `wallabag` to your list of enabled plugins in `data/config.json.php` (`general.enabled_plugins` section).
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
190
tests/front/controller/admin/PluginsControllerTest.php
Normal file
190
tests/front/controller/admin/PluginsControllerTest.php
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Shaarli\Front\Controller\Admin;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Shaarli\Config\ConfigManager;
|
||||||
|
use Shaarli\Front\Exception\WrongTokenException;
|
||||||
|
use Shaarli\Security\SessionManager;
|
||||||
|
use Slim\Http\Request;
|
||||||
|
use Slim\Http\Response;
|
||||||
|
|
||||||
|
class PluginsControllerTest extends TestCase
|
||||||
|
{
|
||||||
|
use FrontAdminControllerMockHelper;
|
||||||
|
|
||||||
|
/** @var PluginsController */
|
||||||
|
protected $controller;
|
||||||
|
|
||||||
|
public function setUp(): void
|
||||||
|
{
|
||||||
|
$this->createContainer();
|
||||||
|
|
||||||
|
$this->controller = new PluginsController($this->container);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test displaying plugins admin page
|
||||||
|
*/
|
||||||
|
public function testIndex(): void
|
||||||
|
{
|
||||||
|
$assignedVariables = [];
|
||||||
|
$this->assignTemplateVars($assignedVariables);
|
||||||
|
|
||||||
|
$request = $this->createMock(Request::class);
|
||||||
|
$response = new Response();
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'plugin1' => ['order' => 2, 'other' => 'field'],
|
||||||
|
'plugin2' => ['order' => 1],
|
||||||
|
'plugin3' => ['order' => false, 'abc' => 'def'],
|
||||||
|
'plugin4' => [],
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->container->pluginManager
|
||||||
|
->expects(static::once())
|
||||||
|
->method('getPluginsMeta')
|
||||||
|
->willReturn($data);
|
||||||
|
|
||||||
|
$result = $this->controller->index($request, $response);
|
||||||
|
|
||||||
|
static::assertSame(200, $result->getStatusCode());
|
||||||
|
static::assertSame('pluginsadmin', (string) $result->getBody());
|
||||||
|
|
||||||
|
static::assertSame('Plugin Administration - Shaarli', $assignedVariables['pagetitle']);
|
||||||
|
static::assertSame(
|
||||||
|
['plugin2' => $data['plugin2'], 'plugin1' => $data['plugin1']],
|
||||||
|
$assignedVariables['enabledPlugins']
|
||||||
|
);
|
||||||
|
static::assertSame(
|
||||||
|
['plugin3' => $data['plugin3'], 'plugin4' => $data['plugin4']],
|
||||||
|
$assignedVariables['disabledPlugins']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test save plugins admin page
|
||||||
|
*/
|
||||||
|
public function testSaveEnabledPlugins(): void
|
||||||
|
{
|
||||||
|
$parameters = [
|
||||||
|
'plugin1' => 'on',
|
||||||
|
'order_plugin1' => '2',
|
||||||
|
'plugin2' => 'on',
|
||||||
|
];
|
||||||
|
|
||||||
|
$request = $this->createMock(Request::class);
|
||||||
|
$request
|
||||||
|
->expects(static::atLeastOnce())
|
||||||
|
->method('getParams')
|
||||||
|
->willReturnCallback(function () use ($parameters): array {
|
||||||
|
return $parameters;
|
||||||
|
})
|
||||||
|
;
|
||||||
|
$response = new Response();
|
||||||
|
|
||||||
|
$this->container->pluginManager
|
||||||
|
->expects(static::once())
|
||||||
|
->method('executeHooks')
|
||||||
|
->with('save_plugin_parameters', $parameters)
|
||||||
|
;
|
||||||
|
$this->container->conf
|
||||||
|
->expects(static::atLeastOnce())
|
||||||
|
->method('set')
|
||||||
|
->with('general.enabled_plugins', ['plugin1', 'plugin2'])
|
||||||
|
;
|
||||||
|
|
||||||
|
$result = $this->controller->save($request, $response);
|
||||||
|
|
||||||
|
static::assertSame(302, $result->getStatusCode());
|
||||||
|
static::assertSame(['/subfolder/admin/plugins'], $result->getHeader('location'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test save plugin parameters
|
||||||
|
*/
|
||||||
|
public function testSavePluginParameters(): void
|
||||||
|
{
|
||||||
|
$parameters = [
|
||||||
|
'parameters_form' => true,
|
||||||
|
'parameter1' => 'blip',
|
||||||
|
'parameter2' => 'blop',
|
||||||
|
];
|
||||||
|
|
||||||
|
$request = $this->createMock(Request::class);
|
||||||
|
$request
|
||||||
|
->expects(static::atLeastOnce())
|
||||||
|
->method('getParams')
|
||||||
|
->willReturnCallback(function () use ($parameters): array {
|
||||||
|
return $parameters;
|
||||||
|
})
|
||||||
|
;
|
||||||
|
$response = new Response();
|
||||||
|
|
||||||
|
$this->container->pluginManager
|
||||||
|
->expects(static::once())
|
||||||
|
->method('executeHooks')
|
||||||
|
->with('save_plugin_parameters', $parameters)
|
||||||
|
;
|
||||||
|
$this->container->conf
|
||||||
|
->expects(static::atLeastOnce())
|
||||||
|
->method('set')
|
||||||
|
->withConsecutive(['plugins.parameter1', 'blip'], ['plugins.parameter2', 'blop'])
|
||||||
|
;
|
||||||
|
|
||||||
|
$result = $this->controller->save($request, $response);
|
||||||
|
|
||||||
|
static::assertSame(302, $result->getStatusCode());
|
||||||
|
static::assertSame(['/subfolder/admin/plugins'], $result->getHeader('location'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test save plugin parameters - error encountered
|
||||||
|
*/
|
||||||
|
public function testSaveWithError(): void
|
||||||
|
{
|
||||||
|
$request = $this->createMock(Request::class);
|
||||||
|
$response = new Response();
|
||||||
|
|
||||||
|
$this->container->conf = $this->createMock(ConfigManager::class);
|
||||||
|
$this->container->conf
|
||||||
|
->expects(static::atLeastOnce())
|
||||||
|
->method('write')
|
||||||
|
->willThrowException(new \Exception($message = 'error message'))
|
||||||
|
;
|
||||||
|
|
||||||
|
$this->container->sessionManager = $this->createMock(SessionManager::class);
|
||||||
|
$this->container->sessionManager->method('checkToken')->willReturn(true);
|
||||||
|
$this->container->sessionManager
|
||||||
|
->expects(static::once())
|
||||||
|
->method('setSessionParameter')
|
||||||
|
->with(
|
||||||
|
SessionManager::KEY_ERROR_MESSAGES,
|
||||||
|
['ERROR while saving plugin configuration: ' . PHP_EOL . $message]
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
$result = $this->controller->save($request, $response);
|
||||||
|
|
||||||
|
static::assertSame(302, $result->getStatusCode());
|
||||||
|
static::assertSame(['/subfolder/admin/plugins'], $result->getHeader('location'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test save plugin parameters - wrong token
|
||||||
|
*/
|
||||||
|
public function testSaveWrongToken(): void
|
||||||
|
{
|
||||||
|
$this->container->sessionManager = $this->createMock(SessionManager::class);
|
||||||
|
$this->container->sessionManager->method('checkToken')->willReturn(false);
|
||||||
|
|
||||||
|
$request = $this->createMock(Request::class);
|
||||||
|
$response = new Response();
|
||||||
|
|
||||||
|
$this->expectException(WrongTokenException::class);
|
||||||
|
|
||||||
|
$this->controller->save($request, $response);
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,10 +12,10 @@
|
||||||
<link type="text/css" rel="stylesheet" href="{$asset_path}/css/markdown.min.css?v={$version_hash}#" />
|
<link type="text/css" rel="stylesheet" href="{$asset_path}/css/markdown.min.css?v={$version_hash}#" />
|
||||||
{/if}
|
{/if}
|
||||||
{loop="$plugins_includes.css_files"}
|
{loop="$plugins_includes.css_files"}
|
||||||
<link type="text/css" rel="stylesheet" href="{$value}?v={$version_hash}#"/>
|
<link type="text/css" rel="stylesheet" href="{$base_path}/{$value}?v={$version_hash}#"/>
|
||||||
{/loop}
|
{/loop}
|
||||||
{if="is_file('data/user.css')"}
|
{if="is_file('data/user.css')"}
|
||||||
<link type="text/css" rel="stylesheet" href="data/user.css#" />
|
<link type="text/css" rel="stylesheet" href="{$base_path}/data/user.css#" />
|
||||||
{/if}
|
{/if}
|
||||||
<link rel="search" type="application/opensearchdescription+xml" href="{$base_path}/open-search#"
|
<link rel="search" type="application/opensearchdescription+xml" href="{$base_path}/open-search#"
|
||||||
title="Shaarli search - {$shaarlititle}" />
|
title="Shaarli search - {$shaarlititle}" />
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
{/loop}
|
{/loop}
|
||||||
|
|
||||||
{loop="$plugins_footer.js_files"}
|
{loop="$plugins_footer.js_files"}
|
||||||
<script src="{$value}#"></script>
|
<script src="{$base_path}/{$value}#"></script>
|
||||||
{/loop}
|
{/loop}
|
||||||
|
|
||||||
<div id="js-translations" class="hidden">
|
<div id="js-translations" class="hidden">
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
</noscript>
|
</noscript>
|
||||||
|
|
||||||
<form method="POST" action="{$base_path}/?do=save_pluginadmin" name="pluginform" id="pluginform" class="pluginform-container">
|
<form method="POST" action="{$base_path}/admin/plugins" name="pluginform" id="pluginform" class="pluginform-container">
|
||||||
<div class="pure-g">
|
<div class="pure-g">
|
||||||
<div class="pure-u-lg-1-8 pure-u-1-24"></div>
|
<div class="pure-u-lg-1-8 pure-u-1-24"></div>
|
||||||
<div class="pure-u-lg-3-4 pure-u-22-24 page-form page-form-complete">
|
<div class="pure-u-lg-3-4 pure-u-22-24 page-form page-form-complete">
|
||||||
|
@ -127,7 +127,7 @@ <h3 class="window-subtitle">{'Disabled Plugins'|t}</h3>
|
||||||
<input type="hidden" name="token" value="{$token}">
|
<input type="hidden" name="token" value="{$token}">
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<form action="{$base_path}/?do=save_pluginadmin" method="POST">
|
<form action="{$base_path}/admin/plugins" method="POST">
|
||||||
<div class="pure-g">
|
<div class="pure-g">
|
||||||
<div class="pure-u-lg-1-8 pure-u-1-24"></div>
|
<div class="pure-u-lg-1-8 pure-u-1-24"></div>
|
||||||
<div class="pure-u-lg-3-4 pure-u-22-24 page-form page-form-light">
|
<div class="pure-u-lg-3-4 pure-u-22-24 page-form page-form-light">
|
||||||
|
@ -173,6 +173,7 @@ <h3 class="window-subtitle">{function="str_replace('_', ' ', $key)"}</h3>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<input type="hidden" name="token" value="{$token}">
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{include="page.footer"}
|
{include="page.footer"}
|
||||||
|
|
|
@ -16,7 +16,7 @@ <h2 class="window-title">{'Settings'|t}</h2>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="tools-item">
|
<div class="tools-item">
|
||||||
<a href="{$base_path}/?do=pluginadmin" title="{'Enable, disable and configure plugins'|t}">
|
<a href="{$base_path}/admin/plugins" title="{'Enable, disable and configure plugins'|t}">
|
||||||
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Plugin administration'|t}</span>
|
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Plugin administration'|t}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
</noscript>
|
</noscript>
|
||||||
|
|
||||||
<div id="pluginsadmin">
|
<div id="pluginsadmin">
|
||||||
<form action="{$base_path}/?do=save_pluginadmin" method="POST">
|
<form action="{$base_path}/admin/plugins" method="POST">
|
||||||
<section id="enabled_plugins">
|
<section id="enabled_plugins">
|
||||||
<h1>Enabled Plugins</h1>
|
<h1>Enabled Plugins</h1>
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ <h1>Disabled Plugins</h1>
|
||||||
</section>
|
</section>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<form action="{$base_path}/?do=save_pluginadmin" method="POST">
|
<form action="{$base_path}/admin/plugins" method="POST">
|
||||||
<section id="plugin_parameters">
|
<section id="plugin_parameters">
|
||||||
<h1>Enabled Plugin Parameters</h1>
|
<h1>Enabled Plugin Parameters</h1>
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<div id="toolsdiv">
|
<div id="toolsdiv">
|
||||||
<a href="{$base_path}/admin/configure"><b>Configure your Shaarli</b><span>: Change Title, timezone...</span></a>
|
<a href="{$base_path}/admin/configure"><b>Configure your Shaarli</b><span>: Change Title, timezone...</span></a>
|
||||||
<br><br>
|
<br><br>
|
||||||
<a href="{$base_path}/?do=pluginadmin"><b>Plugin administration</b><span>: Enable, disable and configure plugins.</span></a>
|
<a href="{$base_path}/admin/plugins"><b>Plugin administration</b><span>: Enable, disable and configure plugins.</span></a>
|
||||||
<br><br>
|
<br><br>
|
||||||
{if="!$openshaarli"}<a href="{$base_path}/admin/password"><b>Change password</b><span>: Change your password.</span></a>
|
{if="!$openshaarli"}<a href="{$base_path}/admin/password"><b>Change password</b><span>: Change your password.</span></a>
|
||||||
<br><br>{/if}
|
<br><br>{/if}
|
||||||
|
|
Loading…
Reference in a new issue