Upgrade to 3.0.3

This commit is contained in:
Bastian Allgeier
2019-03-05 10:55:03 +01:00
parent 8e3d86a590
commit 418db4b09b
40 changed files with 704 additions and 144 deletions

View File

@@ -4,7 +4,7 @@
* Validate the PHP version to already * Validate the PHP version to already
* stop at older versions * stop at older versions
*/ */
if (version_compare(phpversion(), '7.1.0', '>') === false) { if (version_compare(phpversion(), '7.1.0', '>=') === false) {
die(include __DIR__ . '/views/php.php'); die(include __DIR__ . '/views/php.php');
} }

View File

@@ -1,7 +1,7 @@
{ {
"name": "getkirby/cms", "name": "getkirby/cms",
"description": "The Kirby 3 core", "description": "The Kirby 3 core",
"version": "3.0.2", "version": "3.0.3",
"license": "proprietary", "license": "proprietary",
"keywords": ["kirby", "cms", "core"], "keywords": ["kirby", "cms", "core"],
"homepage": "https://getkirby.com", "homepage": "https://getkirby.com",

12
kirby/composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "b4bfa5287bd05b9d23be8ff5411080ff", "content-hash": "87a0387e02a6e94d8d89b88d8113176a",
"packages": [ "packages": [
{ {
"name": "claviska/simpleimage", "name": "claviska/simpleimage",
@@ -108,16 +108,16 @@
}, },
{ {
"name": "getkirby/composer-installer", "name": "getkirby/composer-installer",
"version": "1.1.3", "version": "1.1.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/getkirby/composer-installer.git", "url": "https://github.com/getkirby/composer-installer.git",
"reference": "162497e4d9465fae95cb44b6135506eac54c9a05" "reference": "2d6b8f5601a31caeeea45623e1643fbb437eb94e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/getkirby/composer-installer/zipball/162497e4d9465fae95cb44b6135506eac54c9a05", "url": "https://api.github.com/repos/getkirby/composer-installer/zipball/2d6b8f5601a31caeeea45623e1643fbb437eb94e",
"reference": "162497e4d9465fae95cb44b6135506eac54c9a05", "reference": "2d6b8f5601a31caeeea45623e1643fbb437eb94e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -142,7 +142,7 @@
], ],
"description": "Kirby's custom Composer installer for the Kirby CMS and for Kirby plugins", "description": "Kirby's custom Composer installer for the Kirby CMS and for Kirby plugins",
"homepage": "https://getkirby.com", "homepage": "https://getkirby.com",
"time": "2019-02-06T09:15:26+00:00" "time": "2019-02-11T20:27:36+00:00"
}, },
{ {
"name": "league/color-extractor", "name": "league/color-extractor",

View File

@@ -22,6 +22,12 @@ return [
// be lowercase as well. // be lowercase as well.
return array_change_key_case($columns); return array_change_key_case($columns);
}, },
/**
* The placeholder text if no items have been added yet
*/
'empty' => function ($empty = null) {
return I18n::translate($empty, $empty);
},
/** /**
* Fields setup for the structure form. Works just like fields in regular forms. * Fields setup for the structure form. Works just like fields in regular forms.
*/ */

View File

@@ -27,6 +27,12 @@ return [
return $this->toUsers($default); return $this->toUsers($default);
}, },
/**
* The placeholder text if no users have been selected yet
*/
'empty' => function ($empty = null) {
return I18n::translate($empty, $empty);
},
/** /**
* The minimum number of required selected users * The minimum number of required selected users
*/ */

View File

@@ -148,7 +148,12 @@ return function ($kirby) {
'method' => 'ALL', 'method' => 'ALL',
'env' => 'site', 'env' => 'site',
'action' => function (string $path) use ($kirby) { 'action' => function (string $path) use ($kirby) {
if ($page = $kirby->page($path)) {
// check for content representations or files
$extension = F::extension($path);
// try to redirect prefixed pages
if (empty($extension) === true && $page = $kirby->page($path)) {
$url = $kirby->request()->url([ $url = $kirby->request()->url([
'query' => null, 'query' => null,
'params' => null, 'params' => null,
@@ -160,9 +165,9 @@ return function ($kirby) {
->response() ->response()
->redirect($page->url()); ->redirect($page->url());
} }
return $kirby->resolve($path, $kirby->defaultLanguage()->code());
} }
return $kirby->resolve($path, $kirby->defaultLanguage()->code());
} }
]; ];
} else { } else {

View File

@@ -109,11 +109,15 @@ return [
]; ];
} }
// the drag text needs to be absolute when the files come from
// a different parent model
$dragTextAbsolute = $this->model->is($this->parent) === false;
foreach ($this->files as $file) { foreach ($this->files as $file) {
$image = $file->panelImage($this->image, $thumb); $image = $file->panelImage($this->image, $thumb);
$data[] = [ $data[] = [
'dragText' => $file->dragText($this->dragTextType), 'dragText' => $file->dragText($this->dragTextType, $dragTextAbsolute),
'filename' => $file->filename(), 'filename' => $file->filename(),
'id' => $file->id(), 'id' => $file->id(),
'text' => $file->toString($this->text), 'text' => $file->toString($this->text),

View File

@@ -5,8 +5,8 @@ return [
/** /**
* Sets the text for the empty state box * Sets the text for the empty state box
*/ */
'empty' => function (string $empty = null) { 'empty' => function ($empty = null) {
return I18n::translate($empty); return I18n::translate($empty, $empty);
} }
], ],
'methods' => [ 'methods' => [

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -107,6 +107,9 @@ class App
'users' 'users'
]); ]);
// set the singleton
Model::$kirby = static::$instance = $this;
// setup the I18n class with the translation loader // setup the I18n class with the translation loader
$this->i18n(); $this->i18n();
@@ -120,9 +123,6 @@ class App
// handle those damn errors // handle those damn errors
$this->handleErrors(); $this->handleErrors();
// set the singleton
Model::$kirby = static::$instance = $this;
// bake config // bake config
Config::$data = $this->options; Config::$data = $this->options;
} }
@@ -226,15 +226,17 @@ class App
*/ */
public function call(string $path = null, string $method = null) public function call(string $path = null, string $method = null)
{ {
$path = $path ?? $this->path(); $router = $this->router();
$method = $method ?? $this->request()->method();
$route = $this->router()->find($path, $method);
$this->trigger('route:before', $route, $path, $method); $router::$beforeEach = function ($route, $path, $method) {
$result = $route->action()->call($route, ...$route->arguments()); $this->trigger('route:before', $route, $path, $method);
$this->trigger('route:after', $route, $path, $method, $result); };
return $result; $router::$afterEach = function ($route, $path, $method, $result) {
$this->trigger('route:after', $route, $path, $method, $result);
};
return $router->call($path ?? $this->path(), $method ?? $this->request()->method());
} }
/** /**
@@ -807,33 +809,32 @@ class App
// the site is needed a couple times here // the site is needed a couple times here
$site = $this->site(); $site = $this->site();
// use the home page
if ($path === null) { if ($path === null) {
return $site->homePage(); return $site->homePage();
} }
if ($page = $site->find($path)) { // search for the page by path
return $page; $page = $site->find($path);
}
if ($draft = $site->draft($path)) { // search for a draft if the page cannot be found
if (!$page && $draft = $site->draft($path)) {
if ($this->user() || $draft->isVerified(get('token'))) { if ($this->user() || $draft->isVerified(get('token'))) {
return $draft; $page = $draft;
} }
} }
// try to resolve content representations if the path has an extension // try to resolve content representations if the path has an extension
$extension = F::extension($path); $extension = F::extension($path);
// remove the extension from the path // no content representation? then return the page
$path = Str::rtrim($path, '.' . $extension);
// stop when there's no extension
if (empty($extension) === true) { if (empty($extension) === true) {
return null; return $page;
} }
// try to find the page for the representation // only try to return a representation
if ($page = $site->find($path)) { // when the page has been found
if ($page) {
try { try {
return $this return $this
->response() ->response()
@@ -845,7 +846,7 @@ class App
} }
$id = dirname($path); $id = dirname($path);
$filename = basename($path) . '.' . $extension; $filename = basename($path);
// try to resolve image urls for pages and drafts // try to resolve image urls for pages and drafts
if ($page = $site->findPageOrDraft($id)) { if ($page = $site->findPageOrDraft($id)) {

View File

@@ -58,7 +58,8 @@ trait AppTranslations
*/ */
public function setCurrentLanguage(string $languageCode = null) public function setCurrentLanguage(string $languageCode = null)
{ {
if ($languageCode === null) { if ($this->multilang() === false) {
$this->setLocale($this->option('locale', 'en_US.utf-8'));
return $this->language = null; return $this->language = null;
} }
@@ -69,7 +70,7 @@ trait AppTranslations
} }
if ($this->language) { if ($this->language) {
setlocale(LC_ALL, $this->language->locale()); $this->setLocale($this->language->locale());
} }
return $this->language; return $this->language;
@@ -86,6 +87,22 @@ trait AppTranslations
I18n::$locale = $translationCode ?? 'en'; I18n::$locale = $translationCode ?? 'en';
} }
/**
* Set locale settings
*
* @param string|array $locale
*/
public function setLocale($locale)
{
if (is_array($locale) === true) {
foreach ($locale as $key => $value) {
setlocale($key, $value);
}
} else {
setlocale(LC_ALL, $locale);
}
}
/** /**
* Load a specific translation by locale * Load a specific translation by locale
* *

View File

@@ -222,23 +222,27 @@ class File extends ModelWithContent
* used in the panel, when the file * used in the panel, when the file
* gets dragged onto a textarea * gets dragged onto a textarea
* *
* @param string $type
* @param bool $absolute
* @return string * @return string
*/ */
public function dragText($type = 'kirbytext'): string public function dragText($type = 'kirbytext', bool $absolute = false): string
{ {
$url = $absolute ? $this->id() : $this->filename();
switch ($type) { switch ($type) {
case 'kirbytext': case 'kirbytext':
if ($this->type() === 'image') { if ($this->type() === 'image') {
return '(image: ' . $this->filename() . ')'; return '(image: ' . $url . ')';
} else { } else {
return '(file: ' . $this->filename() . ')'; return '(file: ' . $url . ')';
} }
// no break // no break
case 'markdown': case 'markdown':
if ($this->type() === 'image') { if ($this->type() === 'image') {
return '![' . $this->alt() . '](./' . $this->filename() . ')'; return '![' . $this->alt() . '](' . $url . ')';
} else { } else {
return '[' . $this->filename() . '](./' . $this->filename() . ')'; return '[' . $this->filename() . '](' . $url . ')';
} }
} }
} }

View File

@@ -99,12 +99,19 @@ trait FileModifications
* could potentially also be a CDN or any other * could potentially also be a CDN or any other
* place. * place.
* *
* @param array|null $options * @param array|null|string $options
* @return FileVersion|File * @return FileVersion|File
*/ */
public function thumb(array $options = null) public function thumb($options = null)
{ {
// thumb presets
if (empty($options) === true) { if (empty($options) === true) {
$options = $this->kirby()->option('thumbs.presets.default');
} elseif (is_string($options) === true) {
$options = $this->kirby()->option('thumbs.presets.' . $options);
}
if (empty($options) === true || is_array($options) === false) {
return $this; return $this;
} }

View File

@@ -510,6 +510,10 @@ class Page extends ModelWithContent
public function is($page): bool public function is($page): bool
{ {
if (is_a($page, Page::class) === false) { if (is_a($page, Page::class) === false) {
if (is_string($page) === false) {
return false;
}
$page = $this->kirby()->page($page); $page = $this->kirby()->page($page);
} }
@@ -757,7 +761,7 @@ class Page extends ModelWithContent
*/ */
public function isUnlisted(): bool public function isUnlisted(): bool
{ {
return $this->num() === null; return $this->isListed() === false;
} }
/** /**

View File

@@ -2,6 +2,8 @@
namespace Kirby\Cms; namespace Kirby\Cms;
use Kirby\Toolkit\F;
/** /**
* The Pages collection contains * The Pages collection contains
* any number and mixture of page objects * any number and mixture of page objects
@@ -199,18 +201,33 @@ class Pages extends Collection
*/ */
public function findById($id) public function findById($id)
{ {
$id = trim($id, '/'); // remove trailing or leading slashes
$page = $this->get($id); $id = trim($id, '/');
// strip extensions from the id
if (strpos($id, '.') !== false) {
$info = pathinfo($id);
if ($info['dirname'] !== '.') {
$id = $info['dirname'] . '/' . $info['filename'];
} else {
$id = $info['filename'];
}
}
// try the obvious way
if ($page = $this->get($id)) {
return $page;
}
$multiLang = App::instance()->multilang(); $multiLang = App::instance()->multilang();
if ($multiLang === true) { if ($multiLang === true && $page = $this->findBy('slug', $id)) {
$page = $this->findBy('slug', $id); return $page;
} }
if (!$page) { $start = is_a($this->parent, 'Kirby\Cms\Page') === true ? $this->parent->id() : '';
$start = is_a($this->parent, 'Kirby\Cms\Page') === true ? $this->parent->id() : ''; $page = $this->findByIdRecursive($id, $start, $multiLang);
$page = $this->findByIdRecursive($id, $start, $multiLang);
}
return $page; return $page;
} }

View File

@@ -4,6 +4,7 @@ namespace Kirby\Cms;
use Exception; use Exception;
use Kirby\Http\Response; use Kirby\Http\Response;
use Kirby\Http\Uri;
use Kirby\Toolkit\Dir; use Kirby\Toolkit\Dir;
use Kirby\Toolkit\F; use Kirby\Toolkit\F;
use Kirby\Toolkit\View; use Kirby\Toolkit\View;
@@ -62,12 +63,15 @@ class Panel
try { try {
if (static::link($kirby) === true) { if (static::link($kirby) === true) {
usleep(1); usleep(1);
go($kirby->request()->url()); go($kirby->url('index') . '/' . $kirby->path());
} }
} catch (Throwable $e) { } catch (Throwable $e) {
die('The panel assets cannot be installed properly. Please check permissions of your media folder.'); die('The panel assets cannot be installed properly. Please check permissions of your media folder.');
} }
// get the uri object for the panel url
$uri = new Uri($url = $kirby->url('panel'));
$view = new View($kirby->root('kirby') . '/views/panel.php', [ $view = new View($kirby->root('kirby') . '/views/panel.php', [
'kirby' => $kirby, 'kirby' => $kirby,
'config' => $kirby->option('panel'), 'config' => $kirby->option('panel'),
@@ -75,7 +79,7 @@ class Panel
'pluginCss' => $kirby->url('media') . '/plugins/index.css', 'pluginCss' => $kirby->url('media') . '/plugins/index.css',
'pluginJs' => $kirby->url('media') . '/plugins/index.js', 'pluginJs' => $kirby->url('media') . '/plugins/index.js',
'icons' => F::read($kirby->root('panel') . '/dist/img/icons.svg'), 'icons' => F::read($kirby->root('panel') . '/dist/img/icons.svg'),
'panelUrl' => $url = $kirby->url('panel'), 'panelUrl' => $uri->path()->toString(true) . '/',
'options' => [ 'options' => [
'url' => $url, 'url' => $url,
'site' => $kirby->url('index'), 'site' => $kirby->url('index'),

View File

@@ -13,7 +13,7 @@ class R extends Facade
/** /**
* @return Request * @return Request
*/ */
protected static function instance() public static function instance()
{ {
return App::instance()->request(); return App::instance()->request();
} }

View File

@@ -6,6 +6,7 @@ use Exception;
use Kirby\Data\Data; use Kirby\Data\Data;
use Kirby\Exception\NotFoundException; use Kirby\Exception\NotFoundException;
use Kirby\Toolkit\F; use Kirby\Toolkit\F;
use Kirby\Toolkit\I18n;
/** /**
* Represents a User role with attached * Represents a User role with attached
@@ -92,10 +93,8 @@ class Role extends Model
public static function load(string $file, array $inject = []): self public static function load(string $file, array $inject = []): self
{ {
$name = F::name($file);
$data = Data::read($file); $data = Data::read($file);
$data['name'] = $name; $data['name'] = F::name($file);
return static::factory($data, $inject); return static::factory($data, $inject);
} }
@@ -119,9 +118,9 @@ class Role extends Model
return $this->permissions; return $this->permissions;
} }
protected function setDescription(string $description = null): self protected function setDescription($description = null): self
{ {
$this->description = $description; $this->description = I18n::translate($description, $description);
return $this; return $this;
} }
@@ -139,7 +138,7 @@ class Role extends Model
protected function setTitle($title = null): self protected function setTitle($title = null): self
{ {
$this->title = $title; $this->title = I18n::translate($title, $title);
return $this; return $this;
} }

View File

@@ -13,7 +13,7 @@ class S extends Facade
/** /**
* @return Session * @return Session
*/ */
protected static function instance() public static function instance()
{ {
return App::instance()->session(); return App::instance()->session();
} }

View File

@@ -324,6 +324,17 @@ class Site extends ModelWithContent
); );
} }
/**
* Compares the current object with the given site object
*
* @param Site $site
* @return bool
*/
public function is(Site $site): bool
{
return $this === $site;
}
/** /**
* Returns the root to the media folder for the site * Returns the root to the media folder for the site
* *

View File

@@ -334,7 +334,7 @@ class System
*/ */
public function php(): bool public function php(): bool
{ {
return version_compare(phpversion(), '7.1.0', '>'); return version_compare(phpversion(), '7.1.0', '>=');
} }
/** /**

View File

@@ -10,6 +10,10 @@ class UserBlueprint extends Blueprint
{ {
public function __construct(array $props) public function __construct(array $props)
{ {
// normalize and translate the description
$props['description'] = $this->i18n($props['description'] ?? null);
// register the other props
parent::__construct($props); parent::__construct($props);
// normalize all available page options // normalize all available page options

View File

@@ -12,7 +12,7 @@ class Visitor extends Facade
/** /**
* @return \Kirby\Http\Visitor * @return \Kirby\Http\Visitor
*/ */
protected static function instance() public static function instance()
{ {
return App::instance()->visitor(); return App::instance()->visitor();
} }

View File

@@ -29,7 +29,7 @@ class Yaml extends Handler
$locale = setlocale(LC_NUMERIC, 0); $locale = setlocale(LC_NUMERIC, 0);
// change to english numerics to avoid issues with floats // change to english numerics to avoid issues with floats
setlocale(LC_NUMERIC, 'en_US'); setlocale(LC_NUMERIC, 'C');
// $data, $indent, $wordwrap, $no_opening_dashes // $data, $indent, $wordwrap, $no_opening_dashes
$yaml = Spyc::YAMLDump($data, false, false, true); $yaml = Spyc::YAMLDump($data, false, false, true);

View File

@@ -0,0 +1,7 @@
<?php
namespace Kirby\Http\Exceptions;
class NextRouteException extends \Exception
{
}

View File

@@ -152,6 +152,17 @@ class Route
return $this->attributes['name'] ?? null; return $this->attributes['name'] ?? null;
} }
/**
* Throws a specific exception to tell
* the router to jump to the next route
*
* @return void
*/
public function next()
{
throw new Exceptions\NextRouteException('next');
}
/** /**
* Getter for the pattern * Getter for the pattern
* *

View File

@@ -14,6 +14,8 @@ use InvalidArgumentException;
*/ */
class Router class Router
{ {
public static $beforeEach;
public static $afterEach;
/** /**
* Store for the current route, * Store for the current route,
@@ -84,10 +86,30 @@ class Router
*/ */
public function call(string $path = '', string $method = 'GET') public function call(string $path = '', string $method = 'GET')
{ {
return $this $ignore = [];
->find($path, $method) $result = null;
->action() $loop = true;
->call($this->route, ...$this->route->arguments());
while ($loop === true) {
$route = $this->find($path, $method, $ignore);
if (is_a(static::$beforeEach, 'Closure') === true) {
(static::$beforeEach)($route, $path, $method);
}
try {
$result = $route->action()->call($route, ...$route->arguments());
$loop = false;
} catch (Exceptions\NextRouteException $e) {
$ignore[] = $route;
}
if (is_a(static::$afterEach, 'Closure') === true) {
(static::$afterEach)($route, $path, $method, $result);
}
}
return $result;
} }
/** /**
@@ -98,9 +120,10 @@ class Router
* *
* @param string $path * @param string $path
* @param string $method * @param string $method
* @param array $ignore
* @return Route|null * @return Route|null
*/ */
public function find(string $path, string $method) public function find(string $path, string $method, array $ignore = null)
{ {
if (isset($this->routes[$method]) === false) { if (isset($this->routes[$method]) === false) {
throw new InvalidArgumentException('Invalid routing method: ' . $method, 400); throw new InvalidArgumentException('Invalid routing method: ' . $method, 400);
@@ -113,7 +136,9 @@ class Router
$arguments = $route->parse($route->pattern(), $path); $arguments = $route->parse($route->pattern(), $path);
if ($arguments !== false) { if ($arguments !== false) {
return $this->route = $route; if (empty($ignore) === true || in_array($route, $ignore) === false) {
return $this->route = $route;
}
} }
} }

View File

@@ -15,7 +15,7 @@ abstract class Facade
* *
* @return mixed * @return mixed
*/ */
abstract protected static function instance(); abstract public static function instance();
/** /**
* Proxy for all public instance calls * Proxy for all public instance calls

View File

@@ -336,8 +336,14 @@ class Html
*/ */
public static function rel(string $rel = null, string $target = null) public static function rel(string $rel = null, string $target = null)
{ {
$rel = trim($rel);
if ($target === '_blank') { if ($target === '_blank') {
return trim($rel . ' noopener noreferrer'); if (empty($rel) === false) {
return $rel;
}
return trim($rel . ' noopener noreferrer', ' ');
} }
return $rel; return $rel;

View File

@@ -346,8 +346,8 @@ class Str
public static function float($value): string public static function float($value): string
{ {
$value = str_replace(',', '.', $value); $value = str_replace(',', '.', $value);
$decimal = strlen(substr(strrchr($value, "."), 1)); $decimal = strlen(substr(strrchr($value, '.'), 1));
return number_format((float)$value, $decimal); return number_format((float)$value, $decimal, '.', false);
} }
/** /**

View File

@@ -22,7 +22,7 @@
"days.wed": "st", "days.wed": "st",
"delete": "Smazat", "delete": "Smazat",
"dimensions": "Velikosti", "dimensions": "Rozměry",
"discard": "Zahodit", "discard": "Zahodit",
"edit": "Upravit", "edit": "Upravit",
@@ -70,7 +70,7 @@
"error.page.changeStatus.incomplete": "error.page.changeStatus.incomplete":
"Stránka obsahuje chyby a nemohla být zveřejněna", "Stránka obsahuje chyby a nemohla být zveřejněna",
"error.page.changeStatus.permission": "error.page.changeStatus.permission":
"Stav této stránky nelze změnit", "Status této stránky nelze změnit",
"error.page.changeStatus.toDraft.invalid": "error.page.changeStatus.toDraft.invalid":
"Stránka \"{slug}\" nemůže být převedena na koncept", "Stránka \"{slug}\" nemůže být převedena na koncept",
"error.page.changeTemplate.invalid": "error.page.changeTemplate.invalid":
@@ -307,8 +307,8 @@
"page.changeSlug": "Zm\u011bnit URL", "page.changeSlug": "Zm\u011bnit URL",
"page.changeSlug.fromTitle": "Vytvo\u0159it z n\u00e1zvu", "page.changeSlug.fromTitle": "Vytvo\u0159it z n\u00e1zvu",
"page.changeStatus": "Změnit stav", "page.changeStatus": "Změnit status",
"page.changeStatus.position": "Vybrte prosím pozici", "page.changeStatus.position": "Vyberte prosím pozici",
"page.changeStatus.select": "Vybrat nový status", "page.changeStatus.select": "Vybrat nový status",
"page.changeTemplate": "Změnit šablonu", "page.changeTemplate": "Změnit šablonu",
"page.delete.confirm": "page.delete.confirm":
@@ -321,16 +321,16 @@
"page.status.draft": "Koncept", "page.status.draft": "Koncept",
"page.status.draft.description": "page.status.draft.description":
"Stránka je ve stavu konceptu a je viditelná pouze pro přihlášené editory", "Stránka je ve stavu konceptu a je viditelná pouze pro přihlášené editory",
"page.status.listed": "Veřejný", "page.status.listed": "Veřejná",
"page.status.listed.description": "Stránka je zveřejněná pro všechny", "page.status.listed.description": "Stránka je zveřejněná pro všechny",
"page.status.unlisted": "Nevypsané", "page.status.unlisted": "Neveřejná",
"page.status.unlisted.description": "Tato stránka je dostupná pouze přes adresu URL", "page.status.unlisted.description": "Tato stránka je dostupná pouze přes adresu URL",
"pages": "Stránky", "pages": "Stránky",
"pages.empty": "Zatím žádné stránky", "pages.empty": "Zatím žádné stránky",
"pages.status.draft": "Koncepty", "pages.status.draft": "Koncepty",
"pages.status.listed": "Zveřejněno", "pages.status.listed": "Zveřejněno",
"pages.status.unlisted": "Nevypsané", "pages.status.unlisted": "Neveřejná",
"password": "Heslo", "password": "Heslo",
"pixel": "Pixel", "pixel": "Pixel",

View File

@@ -62,7 +62,7 @@
"error.file.type.forbidden": "Δεν επιτρέπεται η μεταφόρτωση αρχείων {type}", "error.file.type.forbidden": "Δεν επιτρέπεται η μεταφόρτωση αρχείων {type}",
"error.file.undefined": "Δεν ήταν δυνατή η εύρεση του αρχείου", "error.file.undefined": "Δεν ήταν δυνατή η εύρεση του αρχείου",
"error.form.incomplete": "Επιδιορθώστε όλα τα σφάλματα της φόρμας ...", "error.form.incomplete": "Παρακαλώ διορθώστε τα σφάλματα στη φόρμα...",
"error.form.notSaved": "Δεν ήταν δυνατή η αποθήκευση της φόρμας", "error.form.notSaved": "Δεν ήταν δυνατή η αποθήκευση της φόρμας",
"error.page.changeSlug.permission": "error.page.changeSlug.permission":

409
kirby/translations/es_419.json Executable file
View File

@@ -0,0 +1,409 @@
{
"add": "Agregar",
"avatar": "Foto de perfil",
"back": "Regresar",
"cancel": "Cancelar",
"change": "Cambiar",
"close": "Cerrar",
"confirm": "De acuerdo",
"copy": "Copiar",
"create": "Crear",
"date": "Fecha",
"date.select": "Selecciona una fecha",
"day": "Día",
"days.fri": "Vie",
"days.mon": "Lun",
"days.sat": "S\u00e1b",
"days.sun": "Dom",
"days.thu": "Jue",
"days.tue": "Mar",
"days.wed": "Mi\u00e9",
"delete": "Eliminar",
"dimensions": "Dimensiones",
"discard": "Descartar",
"edit": "Editar",
"email": "Correo Electrónico",
"email.placeholder": "correo@ejemplo.com",
"error.access.login": "Ingreso inválido",
"error.access.panel": "No tienes permitido acceder al panel.",
"error.avatar.create.fail": "No se pudo subir la foto de perfil.",
"error.avatar.delete.fail": "No se pudo eliminar la foto de perfil.",
"error.avatar.dimensions.invalid":
"Por favor, mantén el ancho y la altura de la imagen de perfil por debajo de 3000 pixeles.",
"error.avatar.mime.forbidden":
"La foto de perfil debe de ser un archivo JPG o PNG.",
"error.blueprint.notFound": "El blueprint \"{name}\" no se pudo cargar.",
"error.email.preset.notFound": "El preajuste de email \"{name}\" no se pudo encontrar.",
"error.field.converter.invalid": "Convertidor inválido \"{converter}\"",
"error.file.changeName.permission":
"No tienes permitido cambiar el nombre de \"{filename}\"",
"error.file.duplicate": "Ya existe un archivo con el nombre \"{filename}\".",
"error.file.extension.forbidden":
"La extensión \"{extension}\" no está permitida.",
"error.file.extension.missing":
"Falta la extensión para \"{filename}\".",
"error.file.mime.differs":
"El archivo cargado debe ser del mismo tipo mime \"{mime}\".",
"error.file.mime.forbidden": "El tipo de medios \"{mime}\" no está permitido.",
"error.file.mime.missing":
"No se puede detectar el tipo de medio para \"{filename}\".",
"error.file.name.missing": "El nombre del archivo no debe estar vacío.",
"error.file.notFound": "El archivo \"{filename}\" no pudo ser encontrado.",
"error.file.type.forbidden": "No está permitido subir archivos {type}.",
"error.file.undefined": "El archivo no se puede encontrar.",
"error.form.incomplete": "Por favor, corrige todos los errores del formulario...",
"error.form.notSaved": "No se pudo guardar el formulario.",
"error.page.changeSlug.permission":
"No está permitido cambiar el apéndice de URL para \"{slug}\".",
"error.page.changeStatus.incomplete":
"La página tiene errores y no puede ser publicada.",
"error.page.changeStatus.permission":
"El estado de esta página no se puede cambiar.",
"error.page.changeStatus.toDraft.invalid":
"La página \"{slug}\" no se puede convertir en un borrador",
"error.page.changeTemplate.invalid":
"La plantilla para la página \"{slug}\" no se puede cambiar",
"error.page.changeTemplate.permission":
"No está permitido cambiar la plantilla para \"{slug}\"",
"error.page.changeTitle.empty": "El título no debe estar vacío.",
"error.page.changeTitle.permission":
"No tienes permiso para cambiar el título de \"{slug}\"",
"error.page.create.permission": "No tienes permiso para crear \"{slug}\"",
"error.page.delete": "La página \"{slug}\" no se puede eliminar",
"error.page.delete.confirm": "Por favor, introduce el título de la página para confirmar",
"error.page.delete.hasChildren":
"La página tiene subpáginas y no se puede eliminar",
"error.page.delete.permission": "No tienes permiso para borrar \"{slug}\"",
"error.page.draft.duplicate":
"Ya existe un borrador de página con el apéndice de URL \"{slug}\"",
"error.page.duplicate":
"Ya existe una página con el apéndice de URL \"{slug}\"",
"error.page.notFound": "La página \"{slug}\" no se encuentra",
"error.page.num.invalid":
"Por favor, introduce un número de posición válido. Los números no deben ser negativos.",
"error.page.slug.invalid": "Por favor ingresa un prefijo de URL válido",
"error.page.sort.permission": "La página \"{slug}\" no se puede ordenar",
"error.page.status.invalid": "Por favor, establece una estado de página válido",
"error.page.undefined": "La p\u00e1gina no fue encontrada",
"error.page.update.permission": "No tienes permiso para actualizar \"{slug}\"",
"error.section.files.max.plural":
"No debes agregar más de {max} archivos a la sección \"{section}\"",
"error.section.files.max.singular":
"No debes agregar más de un archivo a la sección \"{section}\"",
"error.section.files.min.plural":
"Agrega al menos {min} archivos a la sección \"{section}\"",
"error.section.files.min.singular":
"Agrega al menos un archivo a la sección \"{section}\"",
"error.section.pages.max.plural":
"No debes agregar más de {max} páginas a la sección \"{section}\"",
"error.section.pages.max.singular":
"No debes agregar más de una página a la sección \"{section}\"",
"error.section.pages.min.plural":
"Agrega al menos {min} páginas a la sección \"{section}\"",
"error.section.pages.min.singular":
"Agrega al menos una página a la sección \"{section}\"",
"error.section.notLoaded": "La sección \"{name}\" no se pudo cargar",
"error.section.type.invalid": "La sección \"{type}\" no es valida",
"error.site.changeTitle.permission":
"No tienes permiso para cambiar el título del sitio",
"error.site.update.permission": "No tienes permiso de actualizar el sitio",
"error.template.default.notFound": "La plantilla predeterminada no existe",
"error.user.changeEmail.permission":
"No tienes permiso para cambiar el email del usuario \"{name}\"",
"error.user.changeLanguage.permission":
"No tienes permiso para cambiar el idioma del usuario \"{name}\"",
"error.user.changeName.permission":
"No tienes permiso para cambiar el nombre del usuario \"{name}\"",
"error.user.changePassword.permission":
"No tienes permiso para cambiar la contraseña del usuario \"{name}\"",
"error.user.changeRole.lastAdmin":
"El rol del último administrador no puede ser cambiado",
"error.user.changeRole.permission":
"No tienes permiso para cambiar el rol del usuario \"{name}\"",
"error.user.create.permission": "No tienes permiso de crear este usuario",
"error.user.delete": "El ususario no pudo ser eliminado",
"error.user.delete.lastAdmin": "Usted no puede borrar el \u00faltimo administrador",
"error.user.delete.lastUser": "El último usuario no puede ser borrado",
"error.user.delete.permission":
"Usted no tiene permitido borrar este usuario",
"error.user.duplicate":
"Ya existe un usuario con el email \"{email}\"",
"error.user.email.invalid": "Por favor ingresa un correo electrónico valido",
"error.user.language.invalid": "Por favor ingresa un idioma valido",
"error.user.notFound": "El usuario no pudo ser encontrado",
"error.user.password.invalid":
"Por favor ingresa una contraseña valida. Las contraseñas deben tener al menos 8 caracteres de largo.",
"error.user.password.notSame": "Por favor confirma la contrase\u00f1a",
"error.user.password.undefined": "El usuario no tiene contraseña",
"error.user.role.invalid": "Por favor ingresa un rol valido",
"error.user.undefined": "El usuario no pudo ser encontrado",
"error.user.update.permission":
"No tienes permiso para actualizar al usuario \"{name}\"",
"error.validation.accepted": "Por favor, confirma",
"error.validation.alpha": "Por favor ingrese solo caracteres entre a-z",
"error.validation.alphanum":
"Por favor ingrese solo caracteres entre a-z o números entre 0-9",
"error.validation.between":
"Por favor ingrese valores entre \"{min}\" y \"{max}\"",
"error.validation.boolean": "Por favor confirme o niegue",
"error.validation.contains":
"Por favor ingrese valores que contengan \"{needle}\"",
"error.validation.date": "Por favor ingresa una fecha válida",
"error.validation.denied": "Por favor niegue",
"error.validation.different": "EL valor no debe ser \"{other}\"",
"error.validation.email": "Por favor ingresa un correo electrónico valido",
"error.validation.endswith": "El valor no debe terminar con \"{end}\"",
"error.validation.filename": "Por favor ingresa un nombre de archivo válido",
"error.validation.in": "Por favor ingresa uno de los siguientes: ({in})",
"error.validation.integer": "Por favor ingresa un entero válido",
"error.validation.ip": "Por favor ingresa una dirección IP válida",
"error.validation.less": "Por favor ingresa un valor menor a {max}",
"error.validation.match": "El valor no coincide con el patrón esperado",
"error.validation.max": "Por favor ingresa un valor menor o igual a {max}",
"error.validation.maxlength":
"Por favor ingresa un valor mas corto. (max. {max} caracteres)",
"error.validation.maxwords": "Por favor ingresa no mas de {max} palabra(s)",
"error.validation.min": "Por favor ingresa un valor mayor o igual a {min}",
"error.validation.minlength":
"Por favor ingresa un valor mas largo. (min. {min} caracteres)",
"error.validation.minwords": "Por favor ingresa al menos {min} palabra(s)",
"error.validation.more": "Por favor ingresa un valor mayor a {min}",
"error.validation.notcontains":
"Por favor ingresa un valor que no contenga \"{needle}\"",
"error.validation.notin":
"Por favor no ingreses ninguno de las siguientes: ({notIn})",
"error.validation.option": "Por favor selecciona una de las opciones válidas",
"error.validation.num": "Por favor ingresa un numero válido",
"error.validation.required": "Por favor ingresa algo",
"error.validation.same": "Por favor ingresa \"{other}\"",
"error.validation.size": "El tamaño del valor debe ser \"{size}\"",
"error.validation.startswith": "El valor debe comenzar con \"{start}\"",
"error.validation.time": "Por favor ingresa una hora válida",
"error.validation.url": "Por favor ingresa un URL válido",
"field.files.empty": "Aún no ha seleccionado ningún archivo",
"field.pages.empty": "Aún no ha seleccionado ningúna pagina",
"field.structure.delete.confirm": "\u00bfEn realidad desea borrar esta entrada?",
"field.structure.empty": "A\u00fan no existen entradas.",
"field.users.empty": "Aún no ha seleccionado ningún usuario",
"file.delete.confirm":
"\u00bfEst\u00e1s seguro que deseas eliminar este archivo?",
"files": "Archivos",
"files.empty": "Aún no existen archivos",
"hour": "Hora",
"insert": "Insertar",
"install": "Instalar",
"installation": "Instalación",
"installation.completed": "El panel ha sido instalado.",
"installation.disabled": "El instalador del panel está deshabilitado en servidores públicos por defecto. Ejecute el instalador en una máquina local o habilítelo con la opción panel.install.",
"installation.issues.accounts":
"La carpeta <code>/site/accounts</code> no existe o no posee permisos de escritura.",
"installation.issues.content":
"La carpeta <code>/content</code> no existe o no posee permisos de escritura.",
"installation.issues.curl": "Se requiere la extensión <code>CURL</code>.",
"installation.issues.headline": "El panel no puede ser instalado.",
"installation.issues.mbstring":
"Se requiere la extensión <code>MB String</code>.",
"installation.issues.media":
"La carpeta <code>/media</code> no existe o no posee permisos de escritura.",
"installation.issues.php": "Asegurese de estar usando <code>PHP 7+</code>",
"installation.issues.server":
"Kirby requiere <code>Apache</code>, <code>Nginx</code>, <code>Caddy</code>",
"installation.issues.sessions": "La carpeta <code>/site/sessions</code> no existe o no posee permisos de escritura.",
"language": "Idioma",
"language.code": "Código",
"language.convert": "Hacer por defecto",
"language.convert.confirm":
"<p>Realmente deseas convertir <strong>{name}</strong> al idioma por defecto? Esta acción no se puede deshacer.</p><p>Si <strong>{name}</strong> tiene contenido sin traducir, no habrá vuelta atras y tu sitio puede quedar con partes sin contenido.</p>",
"language.create": "Añadir nuevo idioma",
"language.delete.confirm":
"<p> ",
"language.deleted": "El idioma ha sido borrado",
"language.direction": "Dirección de lectura",
"language.direction.ltr": "De Izquierda a derecha",
"language.direction.rtl": "De derecha a izquierda",
"language.locale": "Cadena de localización PHP",
"language.name": "Nombre",
"language.updated": "El idioma a sido actualizado",
"languages": "Idiomas",
"languages.default": "Idioma por defecto",
"languages.empty": "Todavía no hay idiomas",
"languages.secondary": "Idiomas secundarios",
"languages.secondary.empty": "Todavía no hay idiomas secundarios",
"license": "Licencia",
"license.buy": "Comprar una licencia",
"license.register": "Registrar",
"license.register.help":
"Recibió su código de licencia después de la compra por correo electrónico. Por favor copie y pegue para registrarse.",
"license.register.label": "Por favor, ingresa tu código de licencia",
"license.register.success": "Gracias por apoyar a Kirby",
"license.unregistered": "Este es un demo no registrado de Kirby",
"link": "Enlace",
"link.text": "Texto de Enlace",
"loading": "Cargando",
"login": "Iniciar sesi\u00f3n",
"login.remember": "Mantener mi sesión iniciada",
"logout": "Cerrar sesi\u00f3n",
"menu": "Menù",
"meridiem": "AM/PM",
"mime": "Tipos de medios",
"minutes": "Minutos",
"month": "Mes",
"months.april": "Abril",
"months.august": "Agosto",
"months.december": "Diciembre",
"months.february": "Febrero",
"months.january": "Enero",
"months.july": "Julio",
"months.june": "Junio",
"months.march": "Marzo",
"months.may": "Mayo",
"months.november": "Noviembre",
"months.october": "Octubre",
"months.september": "Septiembre",
"more": "Màs",
"name": "Nombre",
"next": "Siguiente",
"open": "Abrir",
"options": "Opciones",
"orientation": "Orientación",
"orientation.landscape": "Paisaje",
"orientation.portrait": "Retrato",
"orientation.square": "Diapositiva",
"page.changeSlug": "Cambiar URL",
"page.changeSlug.fromTitle": "Crear a partir del t\u00edtulo",
"page.changeStatus": "Cambiar estado",
"page.changeStatus.position": "Por favor selecciona una posición",
"page.changeStatus.select": "Selecciona un nuevo estado",
"page.changeTemplate": "Cambiar plantilla",
"page.delete.confirm":
"¿Estás seguro que deseas eliminar <strong>{title}</strong>?",
"page.delete.confirm.subpages":
"<strong>Esta página tiene subpáginas</strong>. <br>Todas las súbpaginas serán eliminadas también.",
"page.delete.confirm.title": "Introduce el título de la página para confirmar",
"page.draft.create": "Crear borrador",
"page.status": "Estado",
"page.status.draft": "Borrador",
"page.status.draft.description":
"La página está en modo de borrador y sólo es visible para los editores registrados",
"page.status.listed": "Pública",
"page.status.listed.description": "La página es pública para cualquiera",
"page.status.unlisted": "No publicada",
"page.status.unlisted.description": "La página sólo es accesible vía URL",
"pages": "Páginas",
"pages.empty": "No hay páginas aún",
"pages.status.draft": "Borradores",
"pages.status.listed": "Publicado",
"pages.status.unlisted": "No publicado",
"password": "Contrase\u00f1a",
"pixel": "Pixel",
"prev": "Anterior",
"remove": "Eliminar",
"rename": "Renombrar",
"replace": "Reemplazar",
"retry": "Reintentar",
"revert": "Revertir",
"role": "Rol",
"role.all": "Todos",
"role.empty": "No hay usuarios con este rol",
"role.description.placeholder": "Sin descripción",
"save": "Guardar",
"search": "Buscar",
"select": "Seleccionar",
"settings": "Ajustes",
"size": "Tamaño",
"slug": "Apéndice URL",
"sort": "Ordenar",
"title": "Título",
"template": "Plantilla",
"today": "Hoy",
"toolbar.button.code": "Código",
"toolbar.button.bold": "Negrita",
"toolbar.button.email": "Email",
"toolbar.button.headings": "Encabezados",
"toolbar.button.heading.1": "Encabezado 1",
"toolbar.button.heading.2": "Encabezado 2",
"toolbar.button.heading.3": "Encabezado 3",
"toolbar.button.italic": "Texto en It\u00e1licas",
"toolbar.button.link": "Enlace",
"toolbar.button.ol": "Lista en orden",
"toolbar.button.ul": "Lista de viñetas",
"translation.author": "Equipo Kirby",
"translation.direction": "ltr",
"translation.name": "Inglés",
"upload": "Subir",
"upload.errors": "Error",
"upload.progress": "Subiendo...",
"url": "Url",
"url.placeholder": "https://ejemplo.com",
"user": "Usuario",
"user.blueprint":
"Puedes definir secciones adicionales y campos de formulario para este rol de usuario en <strong>/site/blueprints/users/{role}.yml</strong>",
"user.changeEmail": "Cambiar correo electrónico",
"user.changeLanguage": "Cambiar idioma",
"user.changeName": "Renombrar este usuario",
"user.changePassword": "Cambiar la contraseña",
"user.changePassword.new": "Nueva contraseña",
"user.changePassword.new.confirm": "Confirma la nueva contraseña...",
"user.changeRole": "Cambiar rol",
"user.changeRole.select": "Selecciona un nuevo rol",
"user.create": "Agregar un nuevo usuario",
"user.delete": "Eliminar este usuario",
"user.delete.confirm":
"¿Estás seguro que deseas eliminar <br><strong>{email}</strong>?",
"version": "Versión",
"view.account": "Tu cuenta",
"view.installation": "Instalaci\u00f3n",
"view.settings": "Ajustes",
"view.site": "Sitio",
"view.users": "Usuarios",
"welcome": "Bienvenido",
"year": "Año"
}

View File

@@ -56,13 +56,13 @@
"فایل آپلود شده باید از همان نوع باشد «{mime}»", "فایل آپلود شده باید از همان نوع باشد «{mime}»",
"error.file.mime.forbidden": "فرمت فایل «{mime}» غیرمجاز است", "error.file.mime.forbidden": "فرمت فایل «{mime}» غیرمجاز است",
"error.file.mime.missing": "error.file.mime.missing":
"فرنت فایل «{filename}» قابل شناسایی نیست", "فرمت فایل «{filename}» قابل شناسایی نیست",
"error.file.name.missing": "نام فایل اجباری است", "error.file.name.missing": "نام فایل اجباری است",
"error.file.notFound": "فایل «{filename}» پیدا نشد.", "error.file.notFound": "فایل «{filename}» پیدا نشد.",
"error.file.type.forbidden": "شما اجازه بارگزاری فایلهای «{type}» را ندارید", "error.file.type.forbidden": "شما اجازه بارگذاری فایلهای «{type}» را ندارید",
"error.file.undefined": "\u0641\u0627\u06cc\u0644 \u0645\u0648\u0631\u062f \u0646\u0638\u0631 \u067e\u06cc\u062f\u0627 \u0646\u0634\u062f.", "error.file.undefined": "\u0641\u0627\u06cc\u0644 \u0645\u0648\u0631\u062f \u0646\u0638\u0631 \u067e\u06cc\u062f\u0627 \u0646\u0634\u062f.",
"error.form.incomplete": "لطفا کلیه خطاهای فرم را اصلاح کنید", "error.form.incomplete": "لطفا کلیه خطاهای فرم را برطرف کنید",
"error.form.notSaved": "امکان دخیره فرم وجود ندارد", "error.form.notSaved": "امکان دخیره فرم وجود ندارد",
"error.page.changeSlug.permission": "error.page.changeSlug.permission":
@@ -84,7 +84,7 @@
"error.page.delete": "حذف صفحه «{slug}» ممکن نیست", "error.page.delete": "حذف صفحه «{slug}» ممکن نیست",
"error.page.delete.confirm": "جهت ادامه عنوان صفحه را وارد کنید", "error.page.delete.confirm": "جهت ادامه عنوان صفحه را وارد کنید",
"error.page.delete.hasChildren": "error.page.delete.hasChildren":
"این صفحه جاوی زیرصفحه است و نمی تواند حذف شود.", "این صفحه جاوی زیرصفحه است و نمی تواند حذف شود",
"error.page.delete.permission": "شما اجازه حذف «{slug}» را ندارید", "error.page.delete.permission": "شما اجازه حذف «{slug}» را ندارید",
"error.page.draft.duplicate": "error.page.draft.duplicate":
"صفحه پیش‌نویسی با پسوند Url مشابه «{slug}» هم اکنون موجود است", "صفحه پیش‌نویسی با پسوند Url مشابه «{slug}» هم اکنون موجود است",
@@ -96,7 +96,7 @@
"error.page.slug.invalid": "لطفا یک پیشوند Url صحیح وارد کنید", "error.page.slug.invalid": "لطفا یک پیشوند Url صحیح وارد کنید",
"error.page.sort.permission": "امکان مرتب‌سازی «{slug}» نیست", "error.page.sort.permission": "امکان مرتب‌سازی «{slug}» نیست",
"error.page.status.invalid": "لطفا وضعیت صحیحی برای صفحه انتخاب کنید", "error.page.status.invalid": "لطفا وضعیت صحیحی برای صفحه انتخاب کنید",
"error.page.undefined": "\u0635\u0641\u062d\u0647 \u0645\u0648\u0631\u062f \u0646\u0638\u0631 \u067e\u06cc\u062f\u0627 \u0646\u0634\u062f.", "error.page.undefined": "صفحه مورد نظر پیدا نشد",
"error.page.update.permission": "شما اجازه بروزرسانی «{slug}» را ندارید", "error.page.update.permission": "شما اجازه بروزرسانی «{slug}» را ندارید",
"error.section.files.max.plural": "error.section.files.max.plural":
@@ -117,7 +117,7 @@
"error.section.pages.min.singular": "error.section.pages.min.singular":
"حداقل یک صفحه به بخش «{section}» اضافه کنید", "حداقل یک صفحه به بخش «{section}» اضافه کنید",
"error.section.notLoaded": "بخش «{name}» پیدا نشد", "error.section.notLoaded": "بخش «{name}» قابل بارکذاری نیست",
"error.section.type.invalid": "نوع بخش «{type}» غیرمجاز است", "error.section.type.invalid": "نوع بخش «{type}» غیرمجاز است",
"error.site.changeTitle.permission": "error.site.changeTitle.permission":

View File

@@ -43,20 +43,20 @@
"error.email.preset.notFound": "기본 이메일 주소({name})가 없습니다.", "error.email.preset.notFound": "기본 이메일 주소({name})가 없습니다.",
"error.field.converter.invalid": "컨버터({converter})가 잘못되었습니다.", "error.field.converter.invalid": "컨버터({converter})가 올바르지 않습니다.",
"error.file.changeName.permission": "error.file.changeName.permission":
"파일명({filename})을 변경할 권한이 없습니다.", "파일명({filename})을 변경할 권한이 없습니다.",
"error.file.duplicate": "이름이 같은 파일({filename})이 있습니다.", "error.file.duplicate": "파일명이 같은 파일({filename})이 있습니다.",
"error.file.extension.forbidden": "error.file.extension.forbidden":
"이 확장자({extension})는 업로드할 수 없습니다.", "이 확장자({extension})는 업로드할 수 없습니다.",
"error.file.extension.missing": "error.file.extension.missing":
"파일({filename})에 확장자가 없습니다.", "파일({filename})에 확장자가 없습니다.",
"error.file.mime.differs": "error.file.mime.differs":
"기존 파일과 MIME 형식({mime})이 다릅니다.", "기존 파일과 MIME 형식({mime})이 다릅니다.",
"error.file.mime.forbidden": "The media type \"{mime}\" is not allowed", "error.file.mime.forbidden": "이 MIME 형식({mime})은 업로드할 수 없습니다.",
"error.file.mime.missing": "error.file.mime.missing":
"The media type for \"{filename}\" cannot be detected", "파일({filename})의 형식을 알 수 없습니다.",
"error.file.name.missing": "파일명을 입력하세요.", "error.file.name.missing": "파일명을 입력하세요.",
"error.file.notFound": "파일({filename})이 없습니다.", "error.file.notFound": "파일({filename})이 없습니다.",
"error.file.type.forbidden": "이 형식({type})의 파일을 업로드할 권한이 없습니다.", "error.file.type.forbidden": "이 형식({type})의 파일을 업로드할 권한이 없습니다.",
@@ -92,7 +92,7 @@
"고유 주소({slug})가 같은 페이지가 있습니다.", "고유 주소({slug})가 같은 페이지가 있습니다.",
"error.page.notFound": "페이지({slug})가 없습니다.", "error.page.notFound": "페이지({slug})가 없습니다.",
"error.page.num.invalid": "error.page.num.invalid":
"정수를 입력하세요.", "올바른 정수를 입력하세요.",
"error.page.slug.invalid": "올바른 접두사를 입력하세요.", "error.page.slug.invalid": "올바른 접두사를 입력하세요.",
"error.page.sort.permission": "페이지({slug})를 정렬할 수 없습니다.", "error.page.sort.permission": "페이지({slug})를 정렬할 수 없습니다.",
"error.page.status.invalid": "올바른 상태를 설정하세요.", "error.page.status.invalid": "올바른 상태를 설정하세요.",
@@ -100,7 +100,7 @@
"error.page.update.permission": "페이지({slug})를 변경할 권한이 없습니다.", "error.page.update.permission": "페이지({slug})를 변경할 권한이 없습니다.",
"error.section.files.max.plural": "error.section.files.max.plural":
"이 섹션({section})에 파일을 {max}개 이상 추가할 수 없습니다.", "이 섹션({section})에 파일을 {max}개 이상 추가할 수 없습니다.",
"error.section.files.max.singular": "error.section.files.max.singular":
"이 섹션({section})에는 파일을 하나 이상 추가할 수 없습니다.", "이 섹션({section})에는 파일을 하나 이상 추가할 수 없습니다.",
"error.section.files.min.plural": "error.section.files.min.plural":
@@ -121,7 +121,7 @@
"error.section.type.invalid": "섹션의 형식({type})이 올바르지 않습니다.", "error.section.type.invalid": "섹션의 형식({type})이 올바르지 않습니다.",
"error.site.changeTitle.permission": "error.site.changeTitle.permission":
"사이트의 제목을 변경할 권한이 없습니다.", "사이트을 변경할 권한이 없습니다.",
"error.site.update.permission": "사이트의 정보를 변경할 권한이 없습니다.", "error.site.update.permission": "사이트의 정보를 변경할 권한이 없습니다.",
"error.template.default.notFound": "기본 템플릿이 없습니다.", "error.template.default.notFound": "기본 템플릿이 없습니다.",
@@ -164,39 +164,39 @@
"알파벳 또는 숫자만 입력할 수 있습니다.", "알파벳 또는 숫자만 입력할 수 있습니다.",
"error.validation.between": "error.validation.between":
"{min}과 {max} 사이의 값을 입력하세요.", "{min}과 {max} 사이의 값을 입력하세요.",
"error.validation.boolean": "Please confirm or deny", "error.validation.boolean": "확인하거나 취소하세요.",
"error.validation.contains": "error.validation.contains":
"{needle}에 포함된 값을 입력하세요.", "{needle}에 포함된 값을 입력하세요.",
"error.validation.date": "올바른 날짜를 입력하세요.", "error.validation.date": "올바른 날짜를 입력하세요.",
"error.validation.denied": "Please deny", "error.validation.denied": "취소하세요.",
"error.validation.different": "The value must not be \"{other}\"", "error.validation.different": "{other}에 포함된 값은 입력할 수 없습니다.",
"error.validation.email": "올바른 이메일 주소를 입력하세요.", "error.validation.email": "올바른 이메일 주소를 입력하세요.",
"error.validation.endswith": "The value must end with \"{end}\"", "error.validation.endswith": "값은 {end}(으)로 끝나야 합니다.",
"error.validation.filename": "올바른 파일명을 입력하세요.", "error.validation.filename": "올바른 파일명을 입력하세요.",
"error.validation.in": "Please enter one of the following: ({in})", "error.validation.in": "{in}에 포함된 값을 입력하세요.",
"error.validation.integer": "올바른 정수를 입력하세요.", "error.validation.integer": "올바른 정수를 입력하세요.",
"error.validation.ip": "올바른 IP 주소를 입력하세요.", "error.validation.ip": "올바른 IP 주소를 입력하세요.",
"error.validation.less": "{max}보다 작은 값을 입력하세요.", "error.validation.less": "{max}보다 작은 값을 입력하세요.",
"error.validation.match": "The value does not match the expected pattern", "error.validation.match": "입력한 값이 예상 패턴과 일치하지 않습니다.",
"error.validation.max": "Please enter a value equal to or lower than {max}", "error.validation.max": "{max} 이하의 값을 입력하세요.",
"error.validation.maxlength": "error.validation.maxlength":
"Please enter a shorter value. (max. {max} characters)", "{max} 이하의 값을 입력하세요.",
"error.validation.maxwords": "Please enter no more than {max} word(s)", "error.validation.maxwords": "{max}자 이하의 값을 입력하세요.",
"error.validation.min": "Please enter a value equal to or greater than {min}", "error.validation.min": "{min} 이상의 값을 입력하세요.",
"error.validation.minlength": "error.validation.minlength":
"Please enter a longer value. (min. {min} characters)", "{min} 이상의 값을 입력하세요.",
"error.validation.minwords": "Please enter at least {min} word(s)", "error.validation.minwords": "{min}자 이상의 값을 입력하세요.",
"error.validation.more": "Please enter a greater value than {min}", "error.validation.more": "{min} 이상의 값을 입력하세요.",
"error.validation.notcontains": "error.validation.notcontains":
"Please enter a value that does not contain \"{needle}\"", "{needle}에 포함된 값은 입력할 수 없습니다.",
"error.validation.notin": "error.validation.notin":
"Please don't enter any of the following: ({notIn})", "{notIn}에 포함된 값은 입력할 수 없습니다.",
"error.validation.option": "올바른 옵션을 선택하세요.", "error.validation.option": "올바른 옵션을 선택하세요.",
"error.validation.num": "올바른 숫자를 입력하세요.", "error.validation.num": "올바른 숫자를 입력하세요.",
"error.validation.required": "아무거나 입력하세요.", "error.validation.required": "아무거나 입력하세요.",
"error.validation.same": "다음을 입력하세요. {other}", "error.validation.same": "{other}를(을) 입력하세요.",
"error.validation.size": "The size of the value must be \"{size}\"", "error.validation.size": "값은 {size}과(와) 같아야 합니다.",
"error.validation.startswith": "{start}’으(로) 시작해야 합니다.", "error.validation.startswith": "값은 {start}(으)로 시작해야 합니다.",
"error.validation.time": "올바른 시간을 입력하세요.", "error.validation.time": "올바른 시간을 입력하세요.",
"error.validation.url": "올바른 URL을 입력하세요.", "error.validation.url": "올바른 URL을 입력하세요.",
@@ -218,37 +218,37 @@
"installation": "설치", "installation": "설치",
"installation.completed": "패널을 설치했습니다.", "installation.completed": "패널을 설치했습니다.",
"installation.disabled": "The panel installer is disabled on public servers by default. Please run the installer on a local machine or enable it with the <code>panel.install</code> option.", "installation.disabled": "패널 설치 관리자는 로컬 서버에서 실행하거나 <code>panel.install</code> 옵션을 설정하세요.",
"installation.issues.accounts": "installation.issues.accounts":
"<code>/site/accounts</code> 폴더에 쓰기 권한이 없습니다.", "폴더(/site/accounts)에 쓰기 권한이 없습니다.",
"installation.issues.content": "installation.issues.content":
"<code>/content</code> 폴더에 쓰기 권한이 없습니다.", "폴더(/content)에 쓰기 권한이 없습니다.",
"installation.issues.curl": "<code>cURL</code> 확장 기능이 필요합니다.", "installation.issues.curl": "<code>cURL</code> 확장 기능이 필요합니다.",
"installation.issues.headline": "패널을 설치할 수 없습니다.", "installation.issues.headline": "패널을 설치할 수 없습니다.",
"installation.issues.mbstring": "installation.issues.mbstring":
"<code>MB String</code> 확장 기능이 필요합니다.", "<code>MB String</code> 확장 기능이 필요합니다.",
"installation.issues.media": "installation.issues.media":
"<code>/media</code> 폴더에 쓰기 권한이 없습니다.", "폴더(/media)에 쓰기 권한이 없습니다.",
"installation.issues.php": "<code>PHP</code> 버전이 7 이상인지 확인하세요.", "installation.issues.php": "<code>PHP</code> 버전이 7 이상인지 확인하세요.",
"installation.issues.server": "installation.issues.server":
"<code>Apache</code>, <code>Nginx</code>, 또는 <code>Caddy</code>가 필요합니다.", "<code>Apache</code>, <code>Nginx</code>, 또는 <code>Caddy</code>가 필요합니다.",
"installation.issues.sessions": "The <code>/site/sessions</code> folder does not exist or is not writable", "installation.issues.sessions": "폴더(/site/sessions)에 쓰기 권한이 없습니다.",
"language": "\uc5b8\uc5b4", "language": "\uc5b8\uc5b4",
"language.code": "코드", "language.code": "코드",
"language.convert": "기본 언어로 설정", "language.convert": "기본 언어로 설정",
"language.convert.confirm": "language.convert.confirm":
"<p>이 <strong>언어({name})</strong>를 기본 언어로 설정할까요? 설정한 뒤에는 복할 수 없습니다.</p><p>번역되지 않은 항목은 올바르게 표시되지 않습니다.</p>", "언어({name})를 기본 언어로 설정할까요? 설정한 뒤에는 복할 수 없습니다. 번역되지 않은 항목은 올바르게 표시되지 않을 수 있습니다.",
"language.create": "새 언어 추가", "language.create": "새 언어 추가",
"language.delete.confirm": "language.delete.confirm":
"언어({name})를 삭제할까요? 삭제한 뒤에는 복할 수 없습니다.", "언어({name})를 삭제할까요? 삭제한 뒤에는 복할 수 없습니다.",
"language.deleted": "언어 삭제되었습니다.", "language.deleted": "언어 삭제습니다.",
"language.direction": "읽기 방향", "language.direction": "읽기 방향",
"language.direction.ltr": "왼쪽에서 오른쪽", "language.direction.ltr": "왼쪽에서 오른쪽",
"language.direction.rtl": "오른쪽에서 왼쪽", "language.direction.rtl": "오른쪽에서 왼쪽",
"language.locale": "PHP 로캘 문자열", "language.locale": "PHP 로캘 문자열",
"language.name": "이름", "language.name": "이름",
"language.updated": "언어 변경되었습니다.", "language.updated": "언어 변경습니다.",
"languages": "언어", "languages": "언어",
"languages.default": "기본 언어", "languages.default": "기본 언어",
@@ -260,7 +260,7 @@
"license.buy": "라이선스 구매", "license.buy": "라이선스 구매",
"license.register": "등록", "license.register": "등록",
"license.register.help": "license.register.help":
"입력하신 이메일 주소로 라이선스 코드를 전송합니다. 라이선스 코드를 입력해 등록하세요.", "입력 이메일 주소로 라이선스 코드를 전송합니다. Kirby를 등록하려면 라이선스 코드를 입력하세요.",
"license.register.label": "라이선스 코드를 입력하세요.", "license.register.label": "라이선스 코드를 입력하세요.",
"license.register.success": "Kirby를 구입해주셔서 감사합니다.", "license.register.success": "Kirby를 구입해주셔서 감사합니다.",
"license.unregistered": "Kirby가 등록되지 않았습니다.", "license.unregistered": "Kirby가 등록되지 않았습니다.",
@@ -300,9 +300,9 @@
"open": "열기", "open": "열기",
"options": "옵션", "options": "옵션",
"orientation": "형태", "orientation": "비율",
"orientation.landscape": "직사각형(가로)", "orientation.landscape": "가로로 긴 사각형",
"orientation.portrait": "직사각형(세로)", "orientation.portrait": "세로로 긴 사각형",
"orientation.square": "정사각형", "orientation.square": "정사각형",
"page.changeSlug": "고유 주소 변경", "page.changeSlug": "고유 주소 변경",
@@ -336,7 +336,7 @@
"pixel": "픽셀", "pixel": "픽셀",
"prev": "이전", "prev": "이전",
"remove": "삭제", "remove": "삭제",
"rename": "이름 변경", "rename": "제목 변경",
"replace": "\uad50\uccb4", "replace": "\uad50\uccb4",
"retry": "\ub2e4\uc2dc \uc2dc\ub3c4", "retry": "\ub2e4\uc2dc \uc2dc\ub3c4",
"revert": "복원", "revert": "복원",

View File

@@ -35,6 +35,7 @@ return array(
'Kirby\\Cms\\FileActions' => $baseDir . '/src/Cms/FileActions.php', 'Kirby\\Cms\\FileActions' => $baseDir . '/src/Cms/FileActions.php',
'Kirby\\Cms\\FileBlueprint' => $baseDir . '/src/Cms/FileBlueprint.php', 'Kirby\\Cms\\FileBlueprint' => $baseDir . '/src/Cms/FileBlueprint.php',
'Kirby\\Cms\\FileFoundation' => $baseDir . '/src/Cms/FileFoundation.php', 'Kirby\\Cms\\FileFoundation' => $baseDir . '/src/Cms/FileFoundation.php',
'Kirby\\Cms\\FileModifications' => $baseDir . '/src/Cms/FileModifications.php',
'Kirby\\Cms\\FilePermissions' => $baseDir . '/src/Cms/FilePermissions.php', 'Kirby\\Cms\\FilePermissions' => $baseDir . '/src/Cms/FilePermissions.php',
'Kirby\\Cms\\FileRules' => $baseDir . '/src/Cms/FileRules.php', 'Kirby\\Cms\\FileRules' => $baseDir . '/src/Cms/FileRules.php',
'Kirby\\Cms\\FileVersion' => $baseDir . '/src/Cms/FileVersion.php', 'Kirby\\Cms\\FileVersion' => $baseDir . '/src/Cms/FileVersion.php',
@@ -130,6 +131,7 @@ return array(
'Kirby\\Form\\OptionsQuery' => $baseDir . '/src/Form/OptionsQuery.php', 'Kirby\\Form\\OptionsQuery' => $baseDir . '/src/Form/OptionsQuery.php',
'Kirby\\Form\\Validations' => $baseDir . '/src/Form/Validations.php', 'Kirby\\Form\\Validations' => $baseDir . '/src/Form/Validations.php',
'Kirby\\Http\\Cookie' => $baseDir . '/src/Http/Cookie.php', 'Kirby\\Http\\Cookie' => $baseDir . '/src/Http/Cookie.php',
'Kirby\\Http\\Exceptions\\NextRouteException' => $baseDir . '/src/Http/Exceptions/NextRouteException.php',
'Kirby\\Http\\Header' => $baseDir . '/src/Http/Header.php', 'Kirby\\Http\\Header' => $baseDir . '/src/Http/Header.php',
'Kirby\\Http\\Idn' => $baseDir . '/src/Http/Idn.php', 'Kirby\\Http\\Idn' => $baseDir . '/src/Http/Idn.php',
'Kirby\\Http\\Params' => $baseDir . '/src/Http/Params.php', 'Kirby\\Http\\Params' => $baseDir . '/src/Http/Params.php',

View File

@@ -125,6 +125,7 @@ class ComposerStaticInit12091bebabd81c9aba88b2aeec22c8d7
'Kirby\\Cms\\FileActions' => __DIR__ . '/../..' . '/src/Cms/FileActions.php', 'Kirby\\Cms\\FileActions' => __DIR__ . '/../..' . '/src/Cms/FileActions.php',
'Kirby\\Cms\\FileBlueprint' => __DIR__ . '/../..' . '/src/Cms/FileBlueprint.php', 'Kirby\\Cms\\FileBlueprint' => __DIR__ . '/../..' . '/src/Cms/FileBlueprint.php',
'Kirby\\Cms\\FileFoundation' => __DIR__ . '/../..' . '/src/Cms/FileFoundation.php', 'Kirby\\Cms\\FileFoundation' => __DIR__ . '/../..' . '/src/Cms/FileFoundation.php',
'Kirby\\Cms\\FileModifications' => __DIR__ . '/../..' . '/src/Cms/FileModifications.php',
'Kirby\\Cms\\FilePermissions' => __DIR__ . '/../..' . '/src/Cms/FilePermissions.php', 'Kirby\\Cms\\FilePermissions' => __DIR__ . '/../..' . '/src/Cms/FilePermissions.php',
'Kirby\\Cms\\FileRules' => __DIR__ . '/../..' . '/src/Cms/FileRules.php', 'Kirby\\Cms\\FileRules' => __DIR__ . '/../..' . '/src/Cms/FileRules.php',
'Kirby\\Cms\\FileVersion' => __DIR__ . '/../..' . '/src/Cms/FileVersion.php', 'Kirby\\Cms\\FileVersion' => __DIR__ . '/../..' . '/src/Cms/FileVersion.php',
@@ -220,6 +221,7 @@ class ComposerStaticInit12091bebabd81c9aba88b2aeec22c8d7
'Kirby\\Form\\OptionsQuery' => __DIR__ . '/../..' . '/src/Form/OptionsQuery.php', 'Kirby\\Form\\OptionsQuery' => __DIR__ . '/../..' . '/src/Form/OptionsQuery.php',
'Kirby\\Form\\Validations' => __DIR__ . '/../..' . '/src/Form/Validations.php', 'Kirby\\Form\\Validations' => __DIR__ . '/../..' . '/src/Form/Validations.php',
'Kirby\\Http\\Cookie' => __DIR__ . '/../..' . '/src/Http/Cookie.php', 'Kirby\\Http\\Cookie' => __DIR__ . '/../..' . '/src/Http/Cookie.php',
'Kirby\\Http\\Exceptions\\NextRouteException' => __DIR__ . '/../..' . '/src/Http/Exceptions/NextRouteException.php',
'Kirby\\Http\\Header' => __DIR__ . '/../..' . '/src/Http/Header.php', 'Kirby\\Http\\Header' => __DIR__ . '/../..' . '/src/Http/Header.php',
'Kirby\\Http\\Idn' => __DIR__ . '/../..' . '/src/Http/Idn.php', 'Kirby\\Http\\Idn' => __DIR__ . '/../..' . '/src/Http/Idn.php',
'Kirby\\Http\\Params' => __DIR__ . '/../..' . '/src/Http/Params.php', 'Kirby\\Http\\Params' => __DIR__ . '/../..' . '/src/Http/Params.php',

View File

@@ -42,7 +42,16 @@ class CmsInstaller extends Installer
} }
// use path from configuration, otherwise fall back to default // use path from configuration, otherwise fall back to default
$path = $extra['kirby-cms-path'] ?? 'kirby'; if (isset($extra['kirby-cms-path'])) {
$path = $extra['kirby-cms-path'];
} else {
$path = 'kirby';
}
// if explicitly set to something invalid (e.g. `false`), install to vendor dir
if (!is_string($path)) {
return parent::getInstallPath($package);
}
// don't allow unsafe directories // don't allow unsafe directories
$vendorDir = $this->composer->getConfig()->get('vendor-dir', Config::RELATIVE_PATHS) ?? 'vendor'; $vendorDir = $this->composer->getConfig()->get('vendor-dir', Config::RELATIVE_PATHS) ?? 'vendor';