mirror of
https://github.com/grocy/grocy.git
synced 2025-04-29 17:45:39 +00:00
Locales: use http-accept-language or cookie (#976)
* Locales: use http-accept-language or "language"-cookie * Add user-setting "locale" Rename CULTURE to DEFAULT_LOCALE * Use LocaleMiddleware also in dev mode * CORS: don't require authentication on OPTIONS * Use a standard user-settings-control and start a new generic user settings page, not a separate page for the locale setting * Fixed (broken by myself) link-return handling * Clarify language settings * Removed unneeded files * Better user settings icon * Added localization hints Co-authored-by: Bernd Bestel <bernd@berrnd.de>
This commit is contained in:
parent
4a030b7ffc
commit
6f8ad9b76e
@ -7,4 +7,5 @@ copy /Y localization\en\component_translations.po localization\en_GB\component_t
|
||||
copy /Y localization\en\chore_period_types.po localization\en_GB\chore_period_types.po
|
||||
copy /Y localization\en\chore_assignment_types.po localization\en_GB\chore_assignment_types.po
|
||||
copy /Y localization\en\permissions.po localization\en_GB\permissions.po
|
||||
copy /Y localization\en\locales.po localization\en_GB\locales.po
|
||||
popd
|
||||
|
@ -48,3 +48,9 @@ file_filter = localization/<lang>/permissions.po
|
||||
source_file = localization/permissions.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[grocy.locales]
|
||||
file_filter = localization/<lang>/locales.po
|
||||
source_file = localization/locales.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
@ -43,7 +43,7 @@ If you run grocy on Linux, there is also `update.sh` (remember to make the scrip
|
||||
## Localization
|
||||
grocy is fully localizable - the default language is English (integrated into code), a German localization is always maintained by me.
|
||||
You can easily help translating grocy at https://www.transifex.com/grocy/grocy, if your language is incomplete or not available yet.
|
||||
(Language can be changed in `data/config.php`, e. g. `Setting('CULTURE', 'it');`)
|
||||
(The default language can be set in `data/config.php`, e. g. `Setting('DEFAULT_LOCALE', 'it');` and there is also a user setting (see the user settings page) to set a different language per user)
|
||||
|
||||
The [pre-release demo](https://demo-prerelease.grocy.info) is available for any translation which is at least 80 % complete and will pull the translations from Transifex 10 minutes past every hour, so you can have a kind of instant preview of your contributed translations. Thank you!
|
||||
|
||||
|
12
app.php
12
app.php
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use Grocy\Middleware\CorsMiddleware;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Container\ContainerInterface as Container;
|
||||
@ -63,6 +64,16 @@ if (!empty(GROCY_BASE_PATH))
|
||||
$app->setBasePath(GROCY_BASE_PATH);
|
||||
}
|
||||
|
||||
if (GROCY_MODE === 'production' || GROCY_MODE === 'dev')
|
||||
{
|
||||
$app->add(new \Grocy\Middleware\LocaleMiddleware($container));
|
||||
}
|
||||
else {
|
||||
define('GROCY_LOCALE', GROCY_DEFAULT_LOCALE);
|
||||
}
|
||||
|
||||
$authMiddlewareClass = GROCY_AUTH_CLASS;
|
||||
$app->add(new $authMiddlewareClass($container, $app->getResponseFactory()));
|
||||
// Add default middleware
|
||||
$app->addRoutingMiddleware();
|
||||
$errorMiddleware = $app->addErrorMiddleware(true, false, false);
|
||||
@ -70,4 +81,5 @@ $errorMiddleware->setDefaultErrorHandler(
|
||||
new \Grocy\Controllers\ExceptionController($app, $container)
|
||||
);
|
||||
|
||||
$app->add(new CorsMiddleware($app->getResponseFactory()));
|
||||
$app->run();
|
||||
|
@ -21,7 +21,7 @@ Setting('MODE', 'production');
|
||||
|
||||
# Either "en" or "de" or the directory name of
|
||||
# one of the other available localization folders in the "/localization" directory
|
||||
Setting('CULTURE', 'en');
|
||||
Setting('DEFAULT_LOCALE', 'en');
|
||||
|
||||
# This is used to define the first day of a week for calendar views in the frontend,
|
||||
# leave empty to use the locale default
|
||||
|
@ -110,7 +110,7 @@ class BaseController
|
||||
|
||||
protected function getLocalizationService()
|
||||
{
|
||||
return LocalizationService::getInstance(GROCY_CULTURE);
|
||||
return LocalizationService::getInstance(GROCY_LOCALE);
|
||||
}
|
||||
|
||||
protected function getApplicationservice()
|
||||
|
@ -44,4 +44,16 @@ class UsersController extends BaseController
|
||||
->where('parent IS NULL')->where('user_id', $args['userId']),
|
||||
]);
|
||||
}
|
||||
|
||||
public function UserSettings(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->renderPage($response, 'usersettings', [
|
||||
'languages' => array_filter(scandir(__DIR__.'/../localization'), function ($item){
|
||||
if($item == "." || $item == "..")
|
||||
return false;
|
||||
return is_dir(__DIR__.'/../localization/'.$item);
|
||||
})
|
||||
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
79
localization/en/locales.po
Normal file
79
localization/en/locales.po
Normal file
@ -0,0 +1,79 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: http://www.transifex.com/grocy/grocy/language/en\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"POT-Creation-Date: 2019-05-01T17:59:17+00:00\n"
|
||||
"PO-Revision-Date: 2019-05-01T17:59:17+00:00\n"
|
||||
"Language: en\n"
|
||||
"X-Domain: grocy/locales\n"
|
||||
|
||||
msgid "cs"
|
||||
msgstr "Czech"
|
||||
|
||||
msgid "da"
|
||||
msgstr "Danish"
|
||||
|
||||
msgid "de"
|
||||
msgstr "German"
|
||||
|
||||
msgid "el_GR"
|
||||
msgstr "Greek"
|
||||
|
||||
msgid "en"
|
||||
msgstr "English"
|
||||
|
||||
msgid "en_GB"
|
||||
msgstr "English (Great Britain)"
|
||||
|
||||
msgid "es"
|
||||
msgstr "Spanish"
|
||||
|
||||
msgid "fr"
|
||||
msgstr "French"
|
||||
|
||||
msgid "hu"
|
||||
msgstr "Hungarian"
|
||||
|
||||
msgid "it"
|
||||
msgstr "Italian"
|
||||
|
||||
msgid "ja"
|
||||
msgstr "Japanese"
|
||||
|
||||
msgid "ko_KR"
|
||||
msgstr "Korean"
|
||||
|
||||
msgid "nl"
|
||||
msgstr "Dutch"
|
||||
|
||||
msgid "no"
|
||||
msgstr "Norwegian"
|
||||
|
||||
msgid "pl"
|
||||
msgstr "Polish"
|
||||
|
||||
msgid "pt_BR"
|
||||
msgstr "Portuguese (Brazil)"
|
||||
|
||||
msgid "pt_PT"
|
||||
msgstr "Portuguese (Portugal)"
|
||||
|
||||
msgid "ru"
|
||||
msgstr "Russian"
|
||||
|
||||
msgid "sk_SK"
|
||||
msgstr "Slovak"
|
||||
|
||||
msgid "sv_SE"
|
||||
msgstr "Swedish"
|
||||
|
||||
msgid "tr"
|
||||
msgstr "Turkish"
|
||||
|
||||
msgid "zh_TW"
|
||||
msgstr "Chinese (Taiwan)"
|
101
localization/locales.pot
Normal file
101
localization/locales.pot
Normal file
@ -0,0 +1,101 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: http://www.transifex.com/grocy/grocy/language/en\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"POT-Creation-Date: 2019-05-01T17:59:17+00:00\n"
|
||||
"PO-Revision-Date: 2019-05-01T17:59:17+00:00\n"
|
||||
"Language: en\n"
|
||||
"X-Domain: grocy/locales\n"
|
||||
|
||||
# Czech
|
||||
msgid "cs"
|
||||
msgstr ""
|
||||
|
||||
# Danish
|
||||
msgid "da"
|
||||
msgstr ""
|
||||
|
||||
# German
|
||||
msgid "de"
|
||||
msgstr ""
|
||||
|
||||
# Greek
|
||||
msgid "el_GR"
|
||||
msgstr ""
|
||||
|
||||
# English
|
||||
msgid "en"
|
||||
msgstr ""
|
||||
|
||||
# English (Great Britain)
|
||||
msgid "en_GB"
|
||||
msgstr ""
|
||||
|
||||
# Spanish
|
||||
msgid "es"
|
||||
msgstr ""
|
||||
|
||||
# French
|
||||
msgid "fr"
|
||||
msgstr ""
|
||||
|
||||
# Hungarian
|
||||
msgid "hu"
|
||||
msgstr ""
|
||||
|
||||
# Italian
|
||||
msgid "it"
|
||||
msgstr ""
|
||||
|
||||
# Japanese
|
||||
msgid "ja"
|
||||
msgstr ""
|
||||
|
||||
# Korean
|
||||
msgid "ko_KR"
|
||||
msgstr ""
|
||||
|
||||
# Dutch
|
||||
msgid "nl"
|
||||
msgstr ""
|
||||
|
||||
# Norwegian
|
||||
msgid "no"
|
||||
msgstr ""
|
||||
|
||||
# Polish
|
||||
msgid "pl"
|
||||
msgstr ""
|
||||
|
||||
# Portuguese (Brazil)
|
||||
msgid "pt_BR"
|
||||
msgstr ""
|
||||
|
||||
# Portuguese (Portugal)
|
||||
msgid "pt_PT"
|
||||
msgstr ""
|
||||
|
||||
# Russian
|
||||
msgid "ru"
|
||||
msgstr ""
|
||||
|
||||
# Slovak
|
||||
msgid "sk_SK"
|
||||
msgstr ""
|
||||
|
||||
# Swedish
|
||||
msgid "sv_SE"
|
||||
msgstr ""
|
||||
|
||||
# Turkish
|
||||
msgid "tr"
|
||||
msgstr ""
|
||||
|
||||
# Chinese (Taiwan)
|
||||
msgid "zh_TW"
|
||||
msgstr ""
|
@ -1891,3 +1891,12 @@ msgstr ""
|
||||
|
||||
msgid "If you think this is a bug, please report it"
|
||||
msgstr ""
|
||||
|
||||
msgid "Language"
|
||||
msgstr ""
|
||||
|
||||
msgid "User settings"
|
||||
msgstr ""
|
||||
|
||||
msgid "Default"
|
||||
msgstr ""
|
||||
|
@ -2,28 +2,40 @@
|
||||
|
||||
namespace Grocy\Middleware;
|
||||
|
||||
use Psr\Http\Message\ResponseFactoryInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Slim\Routing\RouteContext;
|
||||
|
||||
class CorsMiddleware extends BaseMiddleware
|
||||
class CorsMiddleware
|
||||
{
|
||||
/**
|
||||
* @var ResponseFactoryInterface
|
||||
*/
|
||||
private $responseFactory;
|
||||
|
||||
public function __construct(ResponseFactoryInterface $responseFactory)
|
||||
{
|
||||
$this->responseFactory = $responseFactory;
|
||||
}
|
||||
|
||||
public function __invoke(Request $request, RequestHandler $handler): Response
|
||||
{
|
||||
$response = $handler->handle($request);
|
||||
if ($request->getMethod() == "OPTIONS")
|
||||
$response = $this->responseFactory->createResponse(200);
|
||||
else {
|
||||
$response = $handler->handle($request);
|
||||
|
||||
}
|
||||
//$routeContext = RouteContext::fromRequest($request);
|
||||
//$routingResults = $routeContext->getRoutingResults();
|
||||
//$methods = $routingResults->getAllowedMethods();
|
||||
//$requestHeaders = $request->getHeaderLine('Access-Control-Request-Headers');
|
||||
|
||||
$response = $handler->handle($request);
|
||||
|
||||
$response = $response->withHeader('Access-Control-Allow-Origin', '*');
|
||||
$response = $response->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
||||
$response = $response->withHeader('Access-Control-Allow-Headers', '*');
|
||||
$response = $response->withStatus(204);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
67
middleware/LocaleMiddleware.php
Normal file
67
middleware/LocaleMiddleware.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Grocy\Middleware;
|
||||
|
||||
|
||||
use Grocy\Services\UsersService;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
|
||||
|
||||
class LocaleMiddleware extends BaseMiddleware
|
||||
{
|
||||
|
||||
public function __invoke(Request $request, RequestHandler $handler): Response
|
||||
{
|
||||
$locale = $this->getLocale($request);
|
||||
define('GROCY_LOCALE', $locale);
|
||||
return $handler->handle($request);
|
||||
}
|
||||
|
||||
protected function getLocale(Request $request)
|
||||
{
|
||||
if(GROCY_AUTHENTICATED)
|
||||
{
|
||||
$locale = UsersService::getInstance()->GetUserSetting(GROCY_USER_ID, 'locale');
|
||||
if (isset($locale) && !empty($locale)) {
|
||||
if (in_array($locale, scandir(__DIR__ . '/../localization'))) {
|
||||
return $locale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$langs = join(',', $request->getHeader('Accept-Language'));
|
||||
|
||||
// src: https://gist.github.com/spolischook/0cde9c6286415cddc088
|
||||
$prefLocales = array_reduce(
|
||||
explode(',', $langs),
|
||||
function ($res, $el) {
|
||||
list($l, $q) = array_merge(explode(';q=', $el), [1]);
|
||||
$res[$l] = (float) $q;
|
||||
return $res;
|
||||
}, []);
|
||||
arsort($prefLocales);
|
||||
|
||||
$availableLocales = scandir(__DIR__ . '/../localization');
|
||||
foreach ($prefLocales as $locale => $q) {
|
||||
if(in_array($locale, $availableLocales))
|
||||
{
|
||||
return $locale;
|
||||
}
|
||||
// e.g. en_GB
|
||||
if(in_array(substr($locale, 0, 5), $availableLocales))
|
||||
{
|
||||
return substr($locale, 0, 5);
|
||||
}
|
||||
// e.g: cs
|
||||
// or en
|
||||
// or de
|
||||
if(in_array(substr($locale, 0, 2), $availableLocales))
|
||||
{
|
||||
return substr($locale, 0, 2);
|
||||
}
|
||||
}
|
||||
return GROCY_DEFAULT_LOCALE;
|
||||
}
|
||||
}
|
@ -670,3 +670,29 @@ $(Grocy.UserPermissions).each(function(index, item)
|
||||
$('.permission-' + item.permission_name).addClass('disabled').addClass('not-allowed');
|
||||
}
|
||||
});
|
||||
$('a.link-return').not(".btn").each(function () {
|
||||
var base = $(this).data('href');
|
||||
if(base.contains('?'))
|
||||
{
|
||||
$(this).attr('href', base + '&returnto' + encodeURIComponent(location.pathname));
|
||||
}
|
||||
else{
|
||||
$(this).attr('href', base + '?returnto=' + encodeURIComponent(location.pathname));
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
$(document).on("click", "a.btn.link-return", function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
var link = GetUriParam("returnto");
|
||||
if (!link || !link.length > 0)
|
||||
{
|
||||
location.href = $(e.currentTarget).attr("href");
|
||||
}
|
||||
else
|
||||
{
|
||||
location.href = U(link);
|
||||
}
|
||||
});
|
||||
|
1
public/viewjs/usersettings.js
Normal file
1
public/viewjs/usersettings.js
Normal file
@ -0,0 +1 @@
|
||||
$("#locale").val(Grocy.UserSettings.locale);
|
12
routes.php
12
routes.php
@ -6,9 +6,7 @@ use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Slim\Routing\RouteCollectorProxy;
|
||||
|
||||
use Grocy\Middleware\JsonMiddleware;
|
||||
use Grocy\Middleware\CorsMiddleware;
|
||||
|
||||
$authMiddlewareClass = GROCY_AUTH_CLASS;
|
||||
|
||||
$app->group('', function(RouteCollectorProxy $group)
|
||||
{
|
||||
@ -34,6 +32,7 @@ $app->group('', function(RouteCollectorProxy $group)
|
||||
$group->get('/users', '\Grocy\Controllers\UsersController:UsersList');
|
||||
$group->get('/user/{userId}', '\Grocy\Controllers\UsersController:UserEditForm');
|
||||
$group->get('/user/{userId}/permissions', '\Grocy\Controllers\UsersController:PermissionList');
|
||||
$group->get('/usersettings', '\Grocy\Controllers\UsersController:UserSettings');
|
||||
|
||||
// Stock routes
|
||||
if (GROCY_FEATURE_FLAG_STOCK)
|
||||
@ -136,7 +135,7 @@ $app->group('', function(RouteCollectorProxy $group)
|
||||
$group->get('/api', '\Grocy\Controllers\OpenApiController:DocumentationUi');
|
||||
$group->get('/manageapikeys', '\Grocy\Controllers\OpenApiController:ApiKeysList');
|
||||
$group->get('/manageapikeys/new', '\Grocy\Controllers\OpenApiController:CreateNewApiKey');
|
||||
})->add(new $authMiddlewareClass($container, $app->getResponseFactory()));
|
||||
});
|
||||
|
||||
$app->group('/api', function(RouteCollectorProxy $group)
|
||||
{
|
||||
@ -259,11 +258,10 @@ $app->group('/api', function(RouteCollectorProxy $group)
|
||||
$group->get('/calendar/ical', '\Grocy\Controllers\CalendarApiController:Ical')->setName('calendar-ical');
|
||||
$group->get('/calendar/ical/sharing-link', '\Grocy\Controllers\CalendarApiController:IcalSharingLink');
|
||||
}
|
||||
})->add(JsonMiddleware::class)
|
||||
->add(new $authMiddlewareClass($container, $app->getResponseFactory()));
|
||||
})->add(JsonMiddleware::class);
|
||||
|
||||
// Handle CORS preflight OPTIONS requests
|
||||
$app->options('/api/{routes:.+}', function(Request $request, Response $response): Response
|
||||
{
|
||||
return $response;
|
||||
})->add(CorsMiddleware::class);
|
||||
return $response->withStatus(204);
|
||||
});
|
||||
|
@ -35,7 +35,7 @@ class BaseService
|
||||
|
||||
protected function getLocalizationService()
|
||||
{
|
||||
return LocalizationService::getInstance(GROCY_CULTURE);
|
||||
return LocalizationService::getInstance(GROCY_LOCALE);
|
||||
}
|
||||
|
||||
protected function getStockservice()
|
||||
|
@ -22,7 +22,7 @@ class DatabaseService
|
||||
{
|
||||
if (GROCY_MODE === 'demo' || GROCY_MODE === 'prerelease')
|
||||
{
|
||||
return GROCY_DATAPATH . '/grocy_' . GROCY_CULTURE . '.db';
|
||||
return GROCY_DATAPATH . '/grocy_' . GROCY_DEFAULT_LOCALE . '.db';
|
||||
}
|
||||
|
||||
return GROCY_DATAPATH . '/grocy.db';
|
||||
|
@ -9,7 +9,7 @@ class DemoDataGeneratorService extends BaseService
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->LocalizationService = new LocalizationService(GROCY_CULTURE);
|
||||
$this->LocalizationService = new LocalizationService(GROCY_DEFAULT_LOCALE);
|
||||
}
|
||||
|
||||
protected $LocalizationService;
|
||||
|
@ -61,6 +61,8 @@ class LocalizationService
|
||||
$this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/strings.pot'));
|
||||
$this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/userfield_types.pot'));
|
||||
$this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/permissions.pot'));
|
||||
$this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/locales.pot'));
|
||||
|
||||
|
||||
if (GROCY_MODE !== 'production')
|
||||
{
|
||||
@ -96,6 +98,10 @@ class LocalizationService
|
||||
{
|
||||
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/permissions.po"));
|
||||
}
|
||||
if (file_exists(__DIR__ . "/../localization/$culture/locales.po"))
|
||||
{
|
||||
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/locales.po"));
|
||||
}
|
||||
if (GROCY_MODE !== 'production' && file_exists(__DIR__ . "/../localization/$culture/demo_data.po"))
|
||||
{
|
||||
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/demo_data.po"));
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ GROCY_CULTURE }}">
|
||||
<html lang="{{ GROCY_LOCALE }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
@ -52,7 +52,7 @@
|
||||
Grocy.BaseUrl = '{{ $U('/') }}';
|
||||
Grocy.CurrentUrlRelative = "/" + window.location.href.split('?')[0].replace(Grocy.BaseUrl, "");
|
||||
Grocy.ActiveNav = '@yield('activeNav', '')';
|
||||
Grocy.Culture = '{{ GROCY_CULTURE }}';
|
||||
Grocy.Culture = '{{ GROCY_LOCALE }}';
|
||||
Grocy.Currency = '{{ GROCY_CURRENCY }}';
|
||||
Grocy.CalendarFirstDayOfWeek = '{{ GROCY_CALENDAR_FIRST_DAY_OF_WEEK }}';
|
||||
Grocy.CalendarShowWeekNumbers = {{ BoolToString(GROCY_CALENDAR_SHOW_WEEK_OF_YEAR) }};
|
||||
@ -416,6 +416,9 @@
|
||||
@if(GROCY_FEATURE_FLAG_TASKS)
|
||||
<a class="dropdown-item discrete-link permission-TASKS" href="{{ $U('/taskssettings') }}"><i class="fas fa-tasks"></i> {{ $__t('Tasks settings') }}</a>
|
||||
@endif
|
||||
<a data-href="{{ $U('/usersettings') }}" class="dropdown-item discrete-link link-return">
|
||||
<i class="fas fa-user-cog"></i> {{ $__t('User settings') }}
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
@if(GROCY_SHOW_AUTH_VIEWS)
|
||||
<a class="dropdown-item discrete-link permission-USERS_READ" href="{{ $U('/users') }}"><i class="fas fa-users"></i> {{ $__t('Manage users') }}</a>
|
||||
|
30
views/usersettings.blade.php
Normal file
30
views/usersettings.blade.php
Normal file
@ -0,0 +1,30 @@
|
||||
@extends('layout.default')
|
||||
|
||||
@section('title', $__t('User settings'))
|
||||
@section('activeNav', '')
|
||||
@section('viewJsName', 'usersettings')
|
||||
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h2 class="title">@yield('title')</h2>
|
||||
<hr>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-xs-12">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="locale">{{ $__t('Language') }}</label>
|
||||
<select class="form-control user-setting-control" id="locale" data-setting-key="locale">
|
||||
<option value="">{{ $__t('Default') }}</option>
|
||||
@foreach($languages as $lang)
|
||||
<option value="{{ $lang }}" @if(GROCY_LOCALE == $lang) checked @endif>{{ $__t($lang) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<a href="{{ $U('/') }}" class="btn btn-success link-return">{{ $__t('OK') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
Loading…
x
Reference in New Issue
Block a user