Update Composer packages

This commit is contained in:
Paul Nicoué 2022-12-19 16:26:24 +01:00
parent df93324906
commit 45bdef9a3b
378 changed files with 28466 additions and 28852 deletions

214
composer.lock generated
View file

@ -8,21 +8,21 @@
"packages": [ "packages": [
{ {
"name": "amteich/kirby-twig", "name": "amteich/kirby-twig",
"version": "4.1.6", "version": "4.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/amteich/kirby-twig.git", "url": "https://github.com/amteich/kirby-twig.git",
"reference": "d7f5535a24211702a76bde5c7f59aaf23904efab" "reference": "7cdc1e5d78a19e8e395c1d3516fe90bf512c20fb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/amteich/kirby-twig/zipball/d7f5535a24211702a76bde5c7f59aaf23904efab", "url": "https://api.github.com/repos/amteich/kirby-twig/zipball/7cdc1e5d78a19e8e395c1d3516fe90bf512c20fb",
"reference": "d7f5535a24211702a76bde5c7f59aaf23904efab", "reference": "7cdc1e5d78a19e8e395c1d3516fe90bf512c20fb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"getkirby/composer-installer": "^1.1", "getkirby/composer-installer": "^1.1",
"twig/twig": "^3.0" "twig/twig": "^3.4"
}, },
"type": "kirby-plugin", "type": "kirby-plugin",
"autoload": { "autoload": {
@ -47,9 +47,9 @@
"description": "Twig templating support for Kirby CMS", "description": "Twig templating support for Kirby CMS",
"support": { "support": {
"issues": "https://github.com/amteich/kirby-twig/issues", "issues": "https://github.com/amteich/kirby-twig/issues",
"source": "https://github.com/amteich/kirby-twig/tree/4.1.6" "source": "https://github.com/amteich/kirby-twig/tree/4.2.0"
}, },
"time": "2022-01-03T09:07:58+00:00" "time": "2022-12-09T21:39:13+00:00"
}, },
{ {
"name": "claviska/simpleimage", "name": "claviska/simpleimage",
@ -101,17 +101,98 @@
"time": "2022-07-05T13:18:44+00:00" "time": "2022-07-05T13:18:44+00:00"
}, },
{ {
"name": "filp/whoops", "name": "composer/semver",
"version": "2.14.5", "version": "3.3.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/filp/whoops.git", "url": "https://github.com/composer/semver.git",
"reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc" "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/filp/whoops/zipball/a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9",
"reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9",
"shasum": ""
},
"require": {
"php": "^5.3.2 || ^7.0 || ^8.0"
},
"require-dev": {
"phpstan/phpstan": "^1.4",
"symfony/phpunit-bridge": "^4.2 || ^5"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Composer\\Semver\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nils Adermann",
"email": "naderman@naderman.de",
"homepage": "http://www.naderman.de"
},
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "http://seld.be"
},
{
"name": "Rob Bast",
"email": "rob.bast@gmail.com",
"homepage": "http://robbast.nl"
}
],
"description": "Semver library that offers utilities, version constraint parsing and validation.",
"keywords": [
"semantic",
"semver",
"validation",
"versioning"
],
"support": {
"irc": "irc://irc.freenode.org/composer",
"issues": "https://github.com/composer/semver/issues",
"source": "https://github.com/composer/semver/tree/3.3.2"
},
"funding": [
{
"url": "https://packagist.com",
"type": "custom"
},
{
"url": "https://github.com/composer",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
"type": "tidelift"
}
],
"time": "2022-04-01T19:23:25+00:00"
},
{
"name": "filp/whoops",
"version": "2.14.6",
"source": {
"type": "git",
"url": "https://github.com/filp/whoops.git",
"reference": "f7948baaa0330277c729714910336383286305da"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/filp/whoops/zipball/f7948baaa0330277c729714910336383286305da",
"reference": "f7948baaa0330277c729714910336383286305da",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -161,7 +242,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/filp/whoops/issues", "issues": "https://github.com/filp/whoops/issues",
"source": "https://github.com/filp/whoops/tree/2.14.5" "source": "https://github.com/filp/whoops/tree/2.14.6"
}, },
"funding": [ "funding": [
{ {
@ -169,24 +250,25 @@
"type": "github" "type": "github"
} }
], ],
"time": "2022-01-07T12:00:00+00:00" "time": "2022-11-02T16:23:29+00:00"
}, },
{ {
"name": "getkirby/cms", "name": "getkirby/cms",
"version": "3.7.5", "version": "3.8.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/getkirby/kirby.git", "url": "https://github.com/getkirby/kirby.git",
"reference": "021561f7444896fc9917eccb52768a6e715e9a74" "reference": "41719bd54310dfc2e321a75a8549da98ccf5cd1d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/getkirby/kirby/zipball/021561f7444896fc9917eccb52768a6e715e9a74", "url": "https://api.github.com/repos/getkirby/kirby/zipball/41719bd54310dfc2e321a75a8549da98ccf5cd1d",
"reference": "021561f7444896fc9917eccb52768a6e715e9a74", "reference": "41719bd54310dfc2e321a75a8549da98ccf5cd1d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"claviska/simpleimage": "3.7.0", "claviska/simpleimage": "3.7.0",
"composer/semver": "3.3.2",
"ext-ctype": "*", "ext-ctype": "*",
"ext-curl": "*", "ext-curl": "*",
"ext-dom": "*", "ext-dom": "*",
@ -198,12 +280,12 @@
"ext-mbstring": "*", "ext-mbstring": "*",
"ext-openssl": "*", "ext-openssl": "*",
"ext-simplexml": "*", "ext-simplexml": "*",
"filp/whoops": "2.14.5", "filp/whoops": "2.14.6",
"getkirby/composer-installer": "^1.2.1", "getkirby/composer-installer": "^1.2.1",
"laminas/laminas-escaper": "2.10.0", "laminas/laminas-escaper": "2.12.0",
"michelf/php-smartypants": "1.8.1", "michelf/php-smartypants": "1.8.1",
"php": ">=7.4.0 <8.2.0", "php": ">=8.0.0 <8.2.0",
"phpmailer/phpmailer": "6.6.4", "phpmailer/phpmailer": "6.6.5",
"symfony/polyfill-intl-idn": "1.26.0", "symfony/polyfill-intl-idn": "1.26.0",
"symfony/polyfill-mbstring": "1.26.0" "symfony/polyfill-mbstring": "1.26.0"
}, },
@ -268,7 +350,7 @@
"type": "custom" "type": "custom"
} }
], ],
"time": "2022-08-30T18:27:48+00:00" "time": "2022-12-06T14:31:06+00:00"
}, },
{ {
"name": "getkirby/composer-installer", "name": "getkirby/composer-installer",
@ -356,32 +438,32 @@
}, },
{ {
"name": "laminas/laminas-escaper", "name": "laminas/laminas-escaper",
"version": "2.10.0", "version": "2.12.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laminas/laminas-escaper.git", "url": "https://github.com/laminas/laminas-escaper.git",
"reference": "58af67282db37d24e584a837a94ee55b9c7552be" "reference": "ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/58af67282db37d24e584a837a94ee55b9c7552be", "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490",
"reference": "58af67282db37d24e584a837a94ee55b9c7552be", "reference": "ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-ctype": "*", "ext-ctype": "*",
"ext-mbstring": "*", "ext-mbstring": "*",
"php": "^7.4 || ~8.0.0 || ~8.1.0" "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0"
}, },
"conflict": { "conflict": {
"zendframework/zend-escaper": "*" "zendframework/zend-escaper": "*"
}, },
"require-dev": { "require-dev": {
"infection/infection": "^0.26.6", "infection/infection": "^0.26.6",
"laminas/laminas-coding-standard": "~2.3.0", "laminas/laminas-coding-standard": "~2.4.0",
"maglnet/composer-require-checker": "^3.8.0", "maglnet/composer-require-checker": "^3.8.0",
"phpunit/phpunit": "^9.5.18", "phpunit/phpunit": "^9.5.18",
"psalm/plugin-phpunit": "^0.16.1", "psalm/plugin-phpunit": "^0.17.0",
"vimeo/psalm": "^4.22.0" "vimeo/psalm": "^4.22.0"
}, },
"type": "library", "type": "library",
@ -414,7 +496,7 @@
"type": "community_bridge" "type": "community_bridge"
} }
], ],
"time": "2022-03-08T20:15:36+00:00" "time": "2022-10-10T10:11:09+00:00"
}, },
{ {
"name": "league/color-extractor", "name": "league/color-extractor",
@ -530,16 +612,16 @@
}, },
{ {
"name": "mullema/k3-image-clip", "name": "mullema/k3-image-clip",
"version": "3.1.0", "version": "3.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/mullema/k3-image-clip.git", "url": "https://github.com/mullema/k3-image-clip.git",
"reference": "c2e01f2ceb9eb5bc56895177359d398a3a2dbcf4" "reference": "66e5c2147fd6736f48878aaed6eef9ffe08cdd21"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/mullema/k3-image-clip/zipball/c2e01f2ceb9eb5bc56895177359d398a3a2dbcf4", "url": "https://api.github.com/repos/mullema/k3-image-clip/zipball/66e5c2147fd6736f48878aaed6eef9ffe08cdd21",
"reference": "c2e01f2ceb9eb5bc56895177359d398a3a2dbcf4", "reference": "66e5c2147fd6736f48878aaed6eef9ffe08cdd21",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -566,22 +648,22 @@
"description": "Visual image clip for Kirby 3", "description": "Visual image clip for Kirby 3",
"support": { "support": {
"issues": "https://github.com/mullema/k3-image-clip/issues", "issues": "https://github.com/mullema/k3-image-clip/issues",
"source": "https://github.com/mullema/k3-image-clip/tree/3.1.0" "source": "https://github.com/mullema/k3-image-clip/tree/3.2.0"
}, },
"time": "2022-06-26T08:59:46+00:00" "time": "2022-11-05T10:49:35+00:00"
}, },
{ {
"name": "phpmailer/phpmailer", "name": "phpmailer/phpmailer",
"version": "v6.6.4", "version": "v6.6.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git", "url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b" "reference": "8b6386d7417526d1ea4da9edb70b8352f7543627"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a94fdebaea6bd17f51be0c2373ab80d3d681269b", "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/8b6386d7417526d1ea4da9edb70b8352f7543627",
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b", "reference": "8b6386d7417526d1ea4da9edb70b8352f7543627",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -605,8 +687,8 @@
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
"league/oauth2-google": "Needed for Google XOAUTH2 authentication", "league/oauth2-google": "Needed for Google XOAUTH2 authentication",
"psr/log": "For optional PSR-3 debug logging", "psr/log": "For optional PSR-3 debug logging",
"stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@ -638,7 +720,7 @@
"description": "PHPMailer is a full-featured email creation and transfer class for PHP", "description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": { "support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues", "issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.4" "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.5"
}, },
"funding": [ "funding": [
{ {
@ -646,7 +728,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2022-08-22T09:22:00+00:00" "time": "2022-10-07T12:23:10+00:00"
}, },
{ {
"name": "psr/log", "name": "psr/log",
@ -738,16 +820,16 @@
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",
"version": "v1.26.0", "version": "v1.27.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git", "url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" "reference": "5bbc823adecdae860bb64756d639ecfec17b050a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a",
"reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", "reference": "5bbc823adecdae860bb64756d639ecfec17b050a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -762,7 +844,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.26-dev" "dev-main": "1.27-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -800,7 +882,7 @@
"portable" "portable"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0" "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0"
}, },
"funding": [ "funding": [
{ {
@ -816,7 +898,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-05-24T11:49:31+00:00" "time": "2022-11-03T14:55:06+00:00"
}, },
{ {
"name": "symfony/polyfill-intl-idn", "name": "symfony/polyfill-intl-idn",
@ -907,16 +989,16 @@
}, },
{ {
"name": "symfony/polyfill-intl-normalizer", "name": "symfony/polyfill-intl-normalizer",
"version": "v1.26.0", "version": "v1.27.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "219aa369ceff116e673852dce47c3a41794c14bd" "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6",
"reference": "219aa369ceff116e673852dce47c3a41794c14bd", "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -928,7 +1010,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.26-dev" "dev-main": "1.27-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -971,7 +1053,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0"
}, },
"funding": [ "funding": [
{ {
@ -987,7 +1069,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-05-24T11:49:31+00:00" "time": "2022-11-03T14:55:06+00:00"
}, },
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
@ -1074,16 +1156,16 @@
}, },
{ {
"name": "twig/twig", "name": "twig/twig",
"version": "v3.4.2", "version": "v3.4.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/twigphp/Twig.git", "url": "https://github.com/twigphp/Twig.git",
"reference": "e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077" "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077", "url": "https://api.github.com/repos/twigphp/Twig/zipball/c38fd6b0b7f370c198db91ffd02e23b517426b58",
"reference": "e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077", "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1134,7 +1216,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/twigphp/Twig/issues", "issues": "https://github.com/twigphp/Twig/issues",
"source": "https://github.com/twigphp/Twig/tree/v3.4.2" "source": "https://github.com/twigphp/Twig/tree/v3.4.3"
}, },
"funding": [ "funding": [
{ {
@ -1146,7 +1228,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-08-12T06:47:24+00:00" "time": "2022-09-28T08:42:51+00:00"
} }
], ],
"packages-dev": [], "packages-dev": [],

View file

@ -5,7 +5,7 @@
* stop at older or too recent versions * stop at older or too recent versions
*/ */
if ( if (
version_compare(PHP_VERSION, '7.4.0', '>=') === false || version_compare(PHP_VERSION, '8.0.0', '>=') === false ||
version_compare(PHP_VERSION, '8.2.0', '<') === false version_compare(PHP_VERSION, '8.2.0', '<') === false
) { ) {
die(include __DIR__ . '/views/php.php'); die(include __DIR__ . '/views/php.php');
@ -16,11 +16,15 @@ if (is_file($autoloader = dirname(__DIR__) . '/vendor/autoload.php')) {
* Always prefer a site-wide Composer autoloader * Always prefer a site-wide Composer autoloader
* if it exists, it means that the user has probably * if it exists, it means that the user has probably
* installed additional packages * installed additional packages
*
* @psalm-suppress MissingFile
*/ */
include $autoloader; include $autoloader;
} elseif (is_file($autoloader = __DIR__ . '/vendor/autoload.php')) { } elseif (is_file($autoloader = __DIR__ . '/vendor/autoload.php')) {
/** /**
* Fall back to the local autoloader if that exists * Fall back to the local autoloader if that exists
*
* @psalm-suppress MissingFile
*/ */
include $autoloader; include $autoloader;
} else { } else {

View file

@ -1,7 +1,7 @@
## ##
## Bundle of CA Root Certificates ## Bundle of CA Root Certificates
## ##
## Certificate data from Mozilla as of: Tue Jul 19 03:12:06 2022 GMT ## Certificate data from Mozilla as of: Tue Oct 11 03:12:05 2022 GMT
## ##
## This is a bundle of X.509 certificates of public Certificate Authorities ## This is a bundle of X.509 certificates of public Certificate Authorities
## (CA). These were automatically extracted from Mozilla's root certificates ## (CA). These were automatically extracted from Mozilla's root certificates
@ -14,7 +14,7 @@
## Just configure this file as the SSLCACertificateFile. ## Just configure this file as the SSLCACertificateFile.
## ##
## Conversion done with mk-ca-bundle.pl version 1.29. ## Conversion done with mk-ca-bundle.pl version 1.29.
## SHA256: 9bf3799611fb58197f61d45e71ce3dc19f30e7dd73731915872ce5108a7bb066 ## SHA256: 3ff8bd209b5f2e739b9f2b96eacb694a774114685b02978257824f37ff528f71
## ##
@ -3458,3 +3458,49 @@ zPUwHQYDVR0OBBYEFP+CMXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO
PQQDAwNpADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/67W4W PQQDAwNpADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/67W4W
Aie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFxvmjkI6TZraE3 Aie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFxvmjkI6TZraE3
-----END CERTIFICATE----- -----END CERTIFICATE-----
Security Communication RootCA3
==============================
-----BEGIN CERTIFICATE-----
MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNVBAYTAkpQMSUw
IwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScwJQYDVQQDEx5TZWN1cml0eSBD
b21tdW5pY2F0aW9uIFJvb3RDQTMwHhcNMTYwNjE2MDYxNzE2WhcNMzgwMTE4MDYxNzE2WjBdMQsw
CQYDVQQGEwJKUDElMCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UE
AxMeU2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
MIICCgKCAgEA48lySfcw3gl8qUCBWNO0Ot26YQ+TUG5pPDXC7ltzkBtnTCHsXzW7OT4rCmDvu20r
hvtxosis5FaU+cmvsXLUIKx00rgVrVH+hXShuRD+BYD5UpOzQD11EKzAlrenfna84xtSGc4RHwsE
NPXY9Wk8d/Nk9A2qhd7gCVAEF5aEt8iKvE1y/By7z/MGTfmfZPd+pmaGNXHIEYBMwXFAWB6+oHP2
/D5Q4eAvJj1+XCO1eXDe+uDRpdYMQXF79+qMHIjH7Iv10S9VlkZ8WjtYO/u62C21Jdp6Ts9EriGm
npjKIG58u4iFW/vAEGK78vknR+/RiTlDxN/e4UG/VHMgly1s2vPUB6PmudhvrvyMGS7TZ2crldtY
XLVqAvO4g160a75BflcJdURQVc1aEWEhCmHCqYj9E7wtiS/NYeCVvsq1e+F7NGcLH7YMx3weGVPK
p7FKFSBWFHA9K4IsD50VHUeAR/94mQ4xr28+j+2GaR57GIgUssL8gjMunEst+3A7caoreyYn8xrC
3PsXuKHqy6C0rtOUfnrQq8PsOC0RLoi/1D+tEjtCrI8Cbn3M0V9hvqG8OmpI6iZVIhZdXw3/JzOf
GAN0iltSIEdrRU0id4xVJ/CvHozJgyJUt5rQT9nO/NkuHJYosQLTA70lUhw0Zk8jq/R3gpYd0Vcw
CBEF/VfR2ccCAwEAAaNCMEAwHQYDVR0OBBYEFGQUfPxYchamCik0FW8qy7z8r6irMA4GA1UdDwEB
/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQDcAiMI4u8hOscNtybS
YpOnpSNyByCCYN8Y11StaSWSntkUz5m5UoHPrmyKO1o5yGwBQ8IibQLwYs1OY0PAFNr0Y/Dq9HHu
Tofjcan0yVflLl8cebsjqodEV+m9NU1Bu0soo5iyG9kLFwfl9+qd9XbXv8S2gVj/yP9kaWJ5rW4O
H3/uHWnlt3Jxs/6lATWUVCvAUm2PVcTJ0rjLyjQIUYWg9by0F1jqClx6vWPGOi//lkkZhOpn2ASx
YfQAW0q3nHE3GYV5v4GwxxMOdnE+OoAGrgYWp421wsTL/0ClXI2lyTrtcoHKXJg80jQDdwj98ClZ
XSEIx2C/pHF7uNkegr4Jr2VvKKu/S7XuPghHJ6APbw+LP6yVGPO5DtxnVW5inkYO0QR4ynKudtml
+LLfiAlhi+8kTtFZP1rUPcmTPCtk9YENFpb3ksP+MW/oKjJ0DvRMmEoYDjBU1cXrvMUVnuiZIesn
KwkK2/HmcBhWuwzkvvnoEKQTkrgc4NtnHVMDpCKn3F2SEDzq//wbEBrD2NCcnWXL0CsnMQMeNuE9
dnUM/0Umud1RvCPHX9jYhxBAEg09ODfnRDwYwFMJZI//1ZqmfHAuc1Uh6N//g7kdPjIe1qZ9LPFm
6Vwdp6POXiUyK+OVrCoHzrQoeIY8LaadTdJ0MN1kURXbg4NR16/9M51NZg==
-----END CERTIFICATE-----
Security Communication ECC RootCA1
==================================
-----BEGIN CERTIFICATE-----
MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYTAkpQMSUwIwYD
VQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYDVQQDEyJTZWN1cml0eSBDb21t
dW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYxNjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTEL
MAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNV
BAMTIlNlY3VyaXR5IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQA
IgNiAASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+CnnfdldB9sELLo
5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpKULGjQjBAMB0GA1UdDgQW
BBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAK
BggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3L
snNdo4gIxwwCMQDAqy0Obe0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70e
N9k=
-----END CERTIFICATE-----

View file

@ -3,7 +3,7 @@
"description": "The Kirby 3 core", "description": "The Kirby 3 core",
"license": "proprietary", "license": "proprietary",
"type": "kirby-cms", "type": "kirby-cms",
"version": "3.7.5", "version": "3.8.3",
"keywords": [ "keywords": [
"kirby", "kirby",
"cms", "cms",
@ -24,7 +24,7 @@
"source": "https://github.com/getkirby/kirby" "source": "https://github.com/getkirby/kirby"
}, },
"require": { "require": {
"php": ">=7.4.0 <8.2.0", "php": ">=8.0.0 <8.2.0",
"ext-SimpleXML": "*", "ext-SimpleXML": "*",
"ext-ctype": "*", "ext-ctype": "*",
"ext-curl": "*", "ext-curl": "*",
@ -37,11 +37,12 @@
"ext-mbstring": "*", "ext-mbstring": "*",
"ext-openssl": "*", "ext-openssl": "*",
"claviska/simpleimage": "3.7.0", "claviska/simpleimage": "3.7.0",
"filp/whoops": "2.14.5", "composer/semver": "3.3.2",
"filp/whoops": "2.14.6",
"getkirby/composer-installer": "^1.2.1", "getkirby/composer-installer": "^1.2.1",
"laminas/laminas-escaper": "2.10.0", "laminas/laminas-escaper": "2.12.0",
"michelf/php-smartypants": "1.8.1", "michelf/php-smartypants": "1.8.1",
"phpmailer/phpmailer": "6.6.4", "phpmailer/phpmailer": "6.6.5",
"symfony/polyfill-intl-idn": "1.26.0", "symfony/polyfill-intl-idn": "1.26.0",
"symfony/polyfill-mbstring": "1.26.0" "symfony/polyfill-mbstring": "1.26.0"
}, },
@ -76,7 +77,7 @@
}, },
"optimize-autoloader": true, "optimize-autoloader": true,
"platform": { "platform": {
"php": "7.4.0" "php": "8.0.0"
}, },
"platform-check": false "platform-check": false
}, },

167
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": "fb087946fb5ac5910e25a4d263905d99", "content-hash": "a2b48616382734757b5cf4a9bd73ccdb",
"packages": [ "packages": [
{ {
"name": "claviska/simpleimage", "name": "claviska/simpleimage",
@ -56,17 +56,98 @@
"time": "2022-07-05T13:18:44+00:00" "time": "2022-07-05T13:18:44+00:00"
}, },
{ {
"name": "filp/whoops", "name": "composer/semver",
"version": "2.14.5", "version": "3.3.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/filp/whoops.git", "url": "https://github.com/composer/semver.git",
"reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc" "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/filp/whoops/zipball/a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9",
"reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9",
"shasum": ""
},
"require": {
"php": "^5.3.2 || ^7.0 || ^8.0"
},
"require-dev": {
"phpstan/phpstan": "^1.4",
"symfony/phpunit-bridge": "^4.2 || ^5"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Composer\\Semver\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nils Adermann",
"email": "naderman@naderman.de",
"homepage": "http://www.naderman.de"
},
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "http://seld.be"
},
{
"name": "Rob Bast",
"email": "rob.bast@gmail.com",
"homepage": "http://robbast.nl"
}
],
"description": "Semver library that offers utilities, version constraint parsing and validation.",
"keywords": [
"semantic",
"semver",
"validation",
"versioning"
],
"support": {
"irc": "irc://irc.freenode.org/composer",
"issues": "https://github.com/composer/semver/issues",
"source": "https://github.com/composer/semver/tree/3.3.2"
},
"funding": [
{
"url": "https://packagist.com",
"type": "custom"
},
{
"url": "https://github.com/composer",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
"type": "tidelift"
}
],
"time": "2022-04-01T19:23:25+00:00"
},
{
"name": "filp/whoops",
"version": "2.14.6",
"source": {
"type": "git",
"url": "https://github.com/filp/whoops.git",
"reference": "f7948baaa0330277c729714910336383286305da"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/filp/whoops/zipball/f7948baaa0330277c729714910336383286305da",
"reference": "f7948baaa0330277c729714910336383286305da",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -116,7 +197,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/filp/whoops/issues", "issues": "https://github.com/filp/whoops/issues",
"source": "https://github.com/filp/whoops/tree/2.14.5" "source": "https://github.com/filp/whoops/tree/2.14.6"
}, },
"funding": [ "funding": [
{ {
@ -124,7 +205,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2022-01-07T12:00:00+00:00" "time": "2022-11-02T16:23:29+00:00"
}, },
{ {
"name": "getkirby/composer-installer", "name": "getkirby/composer-installer",
@ -175,32 +256,32 @@
}, },
{ {
"name": "laminas/laminas-escaper", "name": "laminas/laminas-escaper",
"version": "2.10.0", "version": "2.12.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laminas/laminas-escaper.git", "url": "https://github.com/laminas/laminas-escaper.git",
"reference": "58af67282db37d24e584a837a94ee55b9c7552be" "reference": "ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/58af67282db37d24e584a837a94ee55b9c7552be", "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490",
"reference": "58af67282db37d24e584a837a94ee55b9c7552be", "reference": "ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-ctype": "*", "ext-ctype": "*",
"ext-mbstring": "*", "ext-mbstring": "*",
"php": "^7.4 || ~8.0.0 || ~8.1.0" "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0"
}, },
"conflict": { "conflict": {
"zendframework/zend-escaper": "*" "zendframework/zend-escaper": "*"
}, },
"require-dev": { "require-dev": {
"infection/infection": "^0.26.6", "infection/infection": "^0.26.6",
"laminas/laminas-coding-standard": "~2.3.0", "laminas/laminas-coding-standard": "~2.4.0",
"maglnet/composer-require-checker": "^3.8.0", "maglnet/composer-require-checker": "^3.8.0",
"phpunit/phpunit": "^9.5.18", "phpunit/phpunit": "^9.5.18",
"psalm/plugin-phpunit": "^0.16.1", "psalm/plugin-phpunit": "^0.17.0",
"vimeo/psalm": "^4.22.0" "vimeo/psalm": "^4.22.0"
}, },
"type": "library", "type": "library",
@ -233,7 +314,7 @@
"type": "community_bridge" "type": "community_bridge"
} }
], ],
"time": "2022-03-08T20:15:36+00:00" "time": "2022-10-10T10:11:09+00:00"
}, },
{ {
"name": "league/color-extractor", "name": "league/color-extractor",
@ -349,16 +430,16 @@
}, },
{ {
"name": "phpmailer/phpmailer", "name": "phpmailer/phpmailer",
"version": "v6.6.4", "version": "v6.6.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git", "url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b" "reference": "8b6386d7417526d1ea4da9edb70b8352f7543627"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a94fdebaea6bd17f51be0c2373ab80d3d681269b", "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/8b6386d7417526d1ea4da9edb70b8352f7543627",
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b", "reference": "8b6386d7417526d1ea4da9edb70b8352f7543627",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -382,8 +463,8 @@
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
"league/oauth2-google": "Needed for Google XOAUTH2 authentication", "league/oauth2-google": "Needed for Google XOAUTH2 authentication",
"psr/log": "For optional PSR-3 debug logging", "psr/log": "For optional PSR-3 debug logging",
"stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@ -415,7 +496,7 @@
"description": "PHPMailer is a full-featured email creation and transfer class for PHP", "description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": { "support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues", "issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.4" "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.5"
}, },
"funding": [ "funding": [
{ {
@ -423,34 +504,34 @@
"type": "github" "type": "github"
} }
], ],
"time": "2022-08-22T09:22:00+00:00" "time": "2022-10-07T12:23:10+00:00"
}, },
{ {
"name": "psr/log", "name": "psr/log",
"version": "1.1.4", "version": "3.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/php-fig/log.git", "url": "https://github.com/php-fig/log.git",
"reference": "d49695b909c3b7628b6289db5479a1c204601f11" "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
"reference": "d49695b909c3b7628b6289db5479a1c204601f11", "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.3.0" "php": ">=8.0.0"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.1.x-dev" "dev-master": "3.x-dev"
} }
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"Psr\\Log\\": "Psr/Log/" "Psr\\Log\\": "src"
} }
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
@ -471,9 +552,9 @@
"psr-3" "psr-3"
], ],
"support": { "support": {
"source": "https://github.com/php-fig/log/tree/1.1.4" "source": "https://github.com/php-fig/log/tree/3.0.0"
}, },
"time": "2021-05-03T11:20:27+00:00" "time": "2021-07-14T16:46:02+00:00"
}, },
{ {
"name": "symfony/polyfill-intl-idn", "name": "symfony/polyfill-intl-idn",
@ -564,16 +645,16 @@
}, },
{ {
"name": "symfony/polyfill-intl-normalizer", "name": "symfony/polyfill-intl-normalizer",
"version": "v1.26.0", "version": "v1.27.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "219aa369ceff116e673852dce47c3a41794c14bd" "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6",
"reference": "219aa369ceff116e673852dce47c3a41794c14bd", "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -585,7 +666,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.26-dev" "dev-main": "1.27-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -628,7 +709,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0"
}, },
"funding": [ "funding": [
{ {
@ -644,7 +725,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-05-24T11:49:31+00:00" "time": "2022-11-03T14:55:06+00:00"
}, },
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
@ -737,7 +818,7 @@
"prefer-stable": false, "prefer-stable": false,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
"php": ">=7.4.0 <8.2.0", "php": ">=8.0.0 <8.2.0",
"ext-simplexml": "*", "ext-simplexml": "*",
"ext-ctype": "*", "ext-ctype": "*",
"ext-curl": "*", "ext-curl": "*",
@ -752,7 +833,7 @@
}, },
"platform-dev": [], "platform-dev": [],
"platform-overrides": { "platform-overrides": {
"php": "7.4.0" "php": "8.0.0"
}, },
"plugin-api-version": "2.3.0" "plugin-api-version": "2.3.0"
} }

View file

@ -46,7 +46,6 @@ return [
'cookie' => 'Kirby\Http\Cookie', 'cookie' => 'Kirby\Http\Cookie',
'header' => 'Kirby\Http\Header', 'header' => 'Kirby\Http\Header',
'remote' => 'Kirby\Http\Remote', 'remote' => 'Kirby\Http\Remote',
'server' => 'Kirby\Http\Server',
// image classes // image classes
'dimensions' => 'Kirby\Image\Dimensions', 'dimensions' => 'Kirby\Image\Dimensions',

View file

@ -57,6 +57,7 @@ return [
}, },
'type' => fn (File $file) => $file->type(), 'type' => fn (File $file) => $file->type(),
'url' => fn (File $file) => $file->url(), 'url' => fn (File $file) => $file->url(),
'uuid' => fn (File $file) => $file->uuid()?->toString()
], ],
'type' => 'Kirby\Cms\File', 'type' => 'Kirby\Cms\File',
'views' => [ 'views' => [
@ -79,7 +80,8 @@ return [
'size', 'size',
'template', 'template',
'type', 'type',
'url' 'url',
'uuid'
], ],
'compact' => [ 'compact' => [
'filename', 'filename',
@ -87,6 +89,7 @@ return [
'link', 'link',
'type', 'type',
'url', 'url',
'uuid'
], ],
'panel' => [ 'panel' => [
'blueprint', 'blueprint',
@ -109,7 +112,8 @@ return [
'prevWithTemplate' => 'compact', 'prevWithTemplate' => 'compact',
'template', 'template',
'type', 'type',
'url' 'url',
'uuid'
] ]
], ],
]; ];

View file

@ -1,6 +1,5 @@
<?php <?php
use Kirby\Cms\Helpers;
use Kirby\Cms\Page; use Kirby\Cms\Page;
use Kirby\Form\Form; use Kirby\Form\Form;
@ -21,54 +20,25 @@ return [
'hasFiles' => fn (Page $page) => $page->hasFiles(), 'hasFiles' => fn (Page $page) => $page->hasFiles(),
'id' => fn (Page $page) => $page->id(), 'id' => fn (Page $page) => $page->id(),
'isSortable' => fn (Page $page) => $page->isSortable(), 'isSortable' => fn (Page $page) => $page->isSortable(),
/**
* @deprecated 3.6.0
* @todo Remove in 3.8.0
* @codeCoverageIgnore
*/
'next' => function (Page $page) {
Helpers::deprecated('The API field page.next has been deprecated and will be removed in 3.8.0.');
return $page
->nextAll()
->filter('intendedTemplate', $page->intendedTemplate())
->filter('status', $page->status())
->filter('isReadable', true)
->first();
},
'num' => fn (Page $page) => $page->num(), 'num' => fn (Page $page) => $page->num(),
'options' => fn (Page $page) => $page->panel()->options(['preview']), 'options' => fn (Page $page) => $page->panel()->options(['preview']),
'panelImage' => fn (Page $page) => $page->panel()->image(), 'panelImage' => fn (Page $page) => $page->panel()->image(),
'parent' => fn (Page $page) => $page->parent(), 'parent' => fn (Page $page) => $page->parent(),
'parents' => fn (Page $page) => $page->parents()->flip(), 'parents' => fn (Page $page) => $page->parents()->flip(),
/**
* @deprecated 3.6.0
* @todo Remove in 3.8.0
* @codeCoverageIgnore
*/
'prev' => function (Page $page) {
Helpers::deprecated('The API field page.prev has been deprecated and will be removed in 3.8.0.');
return $page
->prevAll()
->filter('intendedTemplate', $page->intendedTemplate())
->filter('status', $page->status())
->filter('isReadable', true)
->last();
},
'previewUrl' => fn (Page $page) => $page->previewUrl(), 'previewUrl' => fn (Page $page) => $page->previewUrl(),
'siblings' => function (Page $page) { 'siblings' => function (Page $page) {
if ($page->isDraft() === true) { if ($page->isDraft() === true) {
return $page->parentModel()->children()->not($page); return $page->parentModel()->children()->not($page);
} else {
return $page->siblings();
} }
return $page->siblings();
}, },
'slug' => fn (Page $page) => $page->slug(), 'slug' => fn (Page $page) => $page->slug(),
'status' => fn (Page $page) => $page->status(), 'status' => fn (Page $page) => $page->status(),
'template' => fn (Page $page) => $page->intendedTemplate()->name(), 'template' => fn (Page $page) => $page->intendedTemplate()->name(),
'title' => fn (Page $page) => $page->title()->value(), 'title' => fn (Page $page) => $page->title()->value(),
'url' => fn (Page $page) => $page->url(), 'url' => fn (Page $page) => $page->url(),
'uuid' => fn (Page $page) => $page->uuid()?->toString()
], ],
'type' => 'Kirby\Cms\Page', 'type' => 'Kirby\Cms\Page',
'views' => [ 'views' => [
@ -76,7 +46,8 @@ return [
'id', 'id',
'title', 'title',
'url', 'url',
'num' 'num',
'uuid'
], ],
'default' => [ 'default' => [
'content', 'content',
@ -88,7 +59,8 @@ return [
'slug', 'slug',
'template', 'template',
'title', 'title',
'url' 'url',
'uuid'
], ],
'panel' => [ 'panel' => [
'id', 'id',
@ -102,7 +74,8 @@ return [
'previewUrl', 'previewUrl',
'slug', 'slug',
'title', 'title',
'url' 'url',
'uuid'
], ],
'selector' => [ 'selector' => [
'id', 'id',

View file

@ -32,28 +32,20 @@ return [
'slugs' => fn () => Str::$language, 'slugs' => fn () => Str::$language,
'title' => fn () => $this->site()->title()->value(), 'title' => fn () => $this->site()->title()->value(),
'translation' => function () { 'translation' => function () {
if ($user = $this->user()) { $code = $this->user()?->language() ??
$translationCode = $user->language(); $this->kirby()->panelLanguage();
} else {
$translationCode = $this->kirby()->panelLanguage();
}
if ($translation = $this->kirby()->translation($translationCode)) { return $this->kirby()->translation($code) ??
return $translation; $this->kirby()->translation('en');
} else {
return $this->kirby()->translation('en');
}
}, },
'kirbytext' => fn () => $this->kirby()->option('panel.kirbytext') ?? true, 'kirbytext' => fn () => $this->kirby()->option('panel.kirbytext') ?? true,
'user' => fn () => $this->user(), 'user' => fn () => $this->user(),
'version' => function () { 'version' => function () {
$user = $this->user(); if ($this->user()?->role()->permissions()->for('access', 'system') === true) {
if ($user && $user->role()->permissions()->for('access', 'system') === true) {
return $this->kirby()->version(); return $this->kirby()->version();
} else {
return null;
} }
return null;
} }
], ],
'type' => 'Kirby\Cms\System', 'type' => 'Kirby\Cms\System',

View file

@ -24,7 +24,8 @@ return [
'prev' => fn (User $user) => $user->prev(), 'prev' => fn (User $user) => $user->prev(),
'role' => fn (User $user) => $user->role(), 'role' => fn (User $user) => $user->role(),
'roles' => fn (User $user) => $user->roles(), 'roles' => fn (User $user) => $user->roles(),
'username' => fn (User $user) => $user->username() 'username' => fn (User $user) => $user->username(),
'uuid' => fn (User $user) => $user->uuid()?->toString()
], ],
'type' => 'Kirby\Cms\User', 'type' => 'Kirby\Cms\User',
'views' => [ 'views' => [
@ -39,7 +40,8 @@ return [
'options', 'options',
'prev' => 'compact', 'prev' => 'compact',
'role', 'role',
'username' 'username',
'uuid'
], ],
'compact' => [ 'compact' => [
'avatar' => 'compact', 'avatar' => 'compact',
@ -48,7 +50,8 @@ return [
'language', 'language',
'name', 'name',
'role' => 'compact', 'role' => 'compact',
'username' 'username',
'uuid'
], ],
'auth' => [ 'auth' => [
'avatar' => 'compact', 'avatar' => 'compact',
@ -72,6 +75,7 @@ return [
'prev' => ['id', 'name'], 'prev' => ['id', 'name'],
'role', 'role',
'username', 'username',
'uuid'
], ],
] ]
]; ];

View file

@ -70,13 +70,11 @@ return [
$user = $auth->login($email, $password, $long); $user = $auth->login($email, $password, $long);
} }
} else { } else {
if (isset($methods['code']) === true) { $mode = match (true) {
$mode = 'login'; isset($methods['code']) => 'login',
} elseif (isset($methods['password-reset']) === true) { isset($methods['password-reset']) => 'password-reset',
$mode = 'password-reset'; default => throw new InvalidArgumentException('Login without password is not enabled')
} else { };
throw new InvalidArgumentException('Login without password is not enabled');
}
$status = $auth->createChallenge($email, $long, $mode); $status = $auth->createChallenge($email, $long, $mode);
} }
@ -87,14 +85,14 @@ return [
'status' => 'ok', 'status' => 'ok',
'user' => $this->resolve($user)->view('auth')->toArray() 'user' => $this->resolve($user)->view('auth')->toArray()
]; ];
} else { }
return [ return [
'code' => 200, 'code' => 200,
'status' => 'ok', 'status' => 'ok',
'challenge' => $status->challenge() 'challenge' => $status->challenge()
]; ];
} }
}
], ],
[ [
'pattern' => 'auth/logout', 'pattern' => 'auth/logout',
@ -105,4 +103,14 @@ return [
return true; return true;
} }
], ],
[
'pattern' => 'auth/ping',
'method' => 'POST',
'auth' => false,
'action' => function () {
// refresh the session timeout
$this->kirby()->session();
return true;
}
],
]; ];

View file

@ -12,9 +12,7 @@ return [
'pattern' => $pattern . '/files/(:any)/sections/(:any)', 'pattern' => $pattern . '/files/(:any)/sections/(:any)',
'method' => 'GET', 'method' => 'GET',
'action' => function (string $path, string $filename, string $sectionName) { 'action' => function (string $path, string $filename, string $sectionName) {
if ($section = $this->file($path, $filename)->blueprint()->section($sectionName)) { return $this->file($path, $filename)->blueprint()->section($sectionName)?->toResponse();
return $section->toResponse();
}
} }
], ],
[ [
@ -60,9 +58,9 @@ return [
if ($this->requestMethod() === 'GET') { if ($this->requestMethod() === 'GET') {
return $files->search($this->requestQuery('q')); return $files->search($this->requestQuery('q'));
} else {
return $files->query($this->requestBody());
} }
return $files->query($this->requestBody());
} }
], ],
[ [
@ -86,16 +84,20 @@ return [
'pattern' => $pattern . '/files/(:any)', 'pattern' => $pattern . '/files/(:any)',
'method' => 'PATCH', 'method' => 'PATCH',
'action' => function (string $path, string $filename) { 'action' => function (string $path, string $filename) {
return $this->file($path, $filename)->update($this->requestBody(), $this->language(), true); return $this->file($path, $filename)->update(
$this->requestBody(),
$this->language(),
true
);
} }
], ],
[ [
'pattern' => $pattern . '/files/(:any)', 'pattern' => $pattern . '/files/(:any)',
'method' => 'POST', 'method' => 'POST',
'action' => function (string $path, string $filename) { 'action' => function (string $path, string $filename) {
return $this->upload(function ($source) use ($path, $filename) { return $this->upload(
return $this->file($path, $filename)->replace($source); fn ($source) => $this->file($path, $filename)->replace($source)
}); );
} }
], ],
[ [
@ -124,9 +126,9 @@ return [
if ($this->requestMethod() === 'GET') { if ($this->requestMethod() === 'GET') {
return $files->search($this->requestQuery('q')); return $files->search($this->requestQuery('q'));
} else {
return $files->query($this->requestBody());
} }
return $files->query($this->requestBody());
} }
], ],
]; ];

View file

@ -29,18 +29,14 @@ return [
'pattern' => 'languages/(:any)', 'pattern' => 'languages/(:any)',
'method' => 'PATCH', 'method' => 'PATCH',
'action' => function (string $code) { 'action' => function (string $code) {
if ($language = $this->kirby()->languages()->find($code)) { return $this->kirby()->languages()->find($code)?->update($this->requestBody());
return $language->update($this->requestBody());
}
} }
], ],
[ [
'pattern' => 'languages/(:any)', 'pattern' => 'languages/(:any)',
'method' => 'DELETE', 'method' => 'DELETE',
'action' => function (string $code) { 'action' => function (string $code) {
if ($language = $this->kirby()->languages()->find($code)) { return $this->kirby()->languages()->find($code)?->delete();
return $language->delete();
}
} }
] ]
]; ];

View file

@ -5,40 +5,41 @@
* Content Lock Routes * Content Lock Routes
*/ */
return [ return [
[
'pattern' => '(:all)/lock',
'method' => 'GET',
'action' => function (string $path) {
return [
'lock' => $this->parent($path)->lock()?->toArray() ?? false
];
}
],
[ [
'pattern' => '(:all)/lock', 'pattern' => '(:all)/lock',
'method' => 'PATCH', 'method' => 'PATCH',
'action' => function (string $path) { 'action' => function (string $path) {
if ($lock = $this->parent($path)->lock()) { return $this->parent($path)->lock()?->create();
return $lock->create();
}
} }
], ],
[ [
'pattern' => '(:all)/lock', 'pattern' => '(:all)/lock',
'method' => 'DELETE', 'method' => 'DELETE',
'action' => function (string $path) { 'action' => function (string $path) {
if ($lock = $this->parent($path)->lock()) { return $this->parent($path)->lock()?->remove();
return $lock->remove();
}
} }
], ],
[ [
'pattern' => '(:all)/unlock', 'pattern' => '(:all)/unlock',
'method' => 'PATCH', 'method' => 'PATCH',
'action' => function (string $path) { 'action' => function (string $path) {
if ($lock = $this->parent($path)->lock()) { return $this->parent($path)->lock()?->unlock();
return $lock->unlock();
}
} }
], ],
[ [
'pattern' => '(:all)/unlock', 'pattern' => '(:all)/unlock',
'method' => 'DELETE', 'method' => 'DELETE',
'action' => function (string $path) { 'action' => function (string $path) {
if ($lock = $this->parent($path)->lock()) { return $this->parent($path)->lock()?->resolve();
return $lock->resolve();
}
} }
], ],
]; ];

View file

@ -104,9 +104,7 @@ return [
'pattern' => 'pages/(:any)/sections/(:any)', 'pattern' => 'pages/(:any)/sections/(:any)',
'method' => 'GET', 'method' => 'GET',
'action' => function (string $id, string $sectionName) { 'action' => function (string $id, string $sectionName) {
if ($section = $this->page($id)->blueprint()->section($sectionName)) { return $this->page($id)->blueprint()->section($sectionName)?->toResponse();
return $section->toResponse();
}
} }
], ],
[ [

View file

@ -10,14 +10,11 @@ return [
'action' => function () { 'action' => function () {
$kirby = $this->kirby(); $kirby = $this->kirby();
switch ($kirby->request()->get('canBe')) { return match ($kirby->request()->get('canBe')) {
case 'changed': 'changed' => $kirby->roles()->canBeChanged(),
return $kirby->roles()->canBeChanged(); 'created' => $kirby->roles()->canBeCreated(),
case 'created': default => $kirby->roles()
return $kirby->roles()->canBeCreated(); };
default:
return $kirby->roles();
}
} }
], ],
[ [

View file

@ -79,18 +79,16 @@ return [
if ($this->requestMethod() === 'GET') { if ($this->requestMethod() === 'GET') {
return $pages->search($this->requestQuery('q')); return $pages->search($this->requestQuery('q'));
} else {
return $pages->query($this->requestBody());
} }
return $pages->query($this->requestBody());
} }
], ],
[ [
'pattern' => 'site/sections/(:any)', 'pattern' => 'site/sections/(:any)',
'method' => 'GET', 'method' => 'GET',
'action' => function (string $sectionName) { 'action' => function (string $sectionName) {
if ($section = $this->site()->blueprint()->section($sectionName)) { return $this->site()->blueprint()->section($sectionName)?->toResponse();
return $section->toResponse();
}
} }
], ],
[ [

View file

@ -17,20 +17,19 @@ return [
if ($this->kirby()->user()) { if ($this->kirby()->user()) {
return $system; return $system;
} else {
if ($system->isOk() === true) {
$info = $this->resolve($system)->view('login')->toArray();
} else {
$info = $this->resolve($system)->view('troubleshooting')->toArray();
} }
$info = match ($system->isOk()) {
true => $this->resolve($system)->view('login')->toArray(),
false => $this->resolve($system)->view('troubleshooting')->toArray()
};
return [ return [
'status' => 'ok', 'status' => 'ok',
'data' => $info, 'data' => $info,
'type' => 'model' 'type' => 'model'
]; ];
} }
}
], ],
[ [
'pattern' => 'system/register', 'pattern' => 'system/register',

View file

@ -26,9 +26,9 @@ return [
'action' => function () { 'action' => function () {
if ($this->requestMethod() === 'GET') { if ($this->requestMethod() === 'GET') {
return $this->users()->search($this->requestQuery('q')); return $this->users()->search($this->requestQuery('q'));
} else {
return $this->users()->query($this->requestBody());
} }
return $this->users()->query($this->requestBody());
} }
], ],
[ [
@ -79,17 +79,16 @@ return [
], ],
'method' => 'POST', 'method' => 'POST',
'action' => function (string $id) { 'action' => function (string $id) {
if ($avatar = $this->user($id)->avatar()) { $this->user($id)->avatar()?->delete();
$avatar->delete();
}
return $this->upload(function ($source, $filename) use ($id) { return $this->upload(
return $this->user($id)->createFile([ fn ($source, $filename) => $this->user($id)->createFile([
'filename' => 'profile.' . F::extension($filename), 'filename' => 'profile.' . F::extension($filename),
'template' => 'avatar', 'template' => 'avatar',
'source' => $source 'source' => $source
]); ]),
}, $single = true); single: true
);
} }
], ],
// @codeCoverageIgnoreEnd // @codeCoverageIgnoreEnd

View file

@ -1,6 +1,7 @@
<?php <?php
use Kirby\Cms\App; use Kirby\Cms\App;
use Kirby\Toolkit\I18n;
return [ return [
'system' => [ 'system' => [
@ -8,40 +9,83 @@ return [
'action' => function () { 'action' => function () {
$kirby = App::instance(); $kirby = App::instance();
$system = $kirby->system(); $system = $kirby->system();
$updateStatus = $system->updateStatus();
$license = $system->license(); $license = $system->license();
// @codeCoverageIgnoreStart $environment = [
if ($license === true) { [
// valid license, but user is not admin 'label' => $license ? I18n::translate('license') : I18n::translate('license.register.label'),
$license = 'Kirby 3'; 'value' => $license ? 'Kirby 3' : I18n::translate('license.unregistered.label'),
} elseif ($license === false) { 'theme' => $license ? null : 'negative',
// no valid license 'dialog' => $license ? 'license' : 'registration'
$license = null; ],
} [
// @codeCoverageIgnoreEnd 'label' => $updateStatus?->label() ?? I18n::translate('version'),
'value' => $kirby->version(),
'link' => (
$updateStatus ?
$updateStatus->url() :
'https://github.com/getkirby/kirby/releases/tag/' . $kirby->version()
),
'theme' => $updateStatus?->theme()
],
[
'label' => 'PHP',
'value' => phpversion()
],
[
'label' => I18n::translate('server'),
'value' => $system->serverSoftware() ?? '?'
]
];
$exceptions = $updateStatus?->exceptionMessages() ?? [];
$plugins = $system->plugins()->values(function ($plugin) use (&$exceptions) {
$authors = $plugin->authorsNames();
$updateStatus = $plugin->updateStatus();
$version = $updateStatus?->toArray() ?? $plugin->version() ?? '';
if ($updateStatus !== null) {
$exceptions = array_merge($exceptions, $updateStatus->exceptionMessages());
}
$plugins = $system->plugins()->values(function ($plugin) {
return [ return [
'author' => $plugin->authorsNames(), 'author' => empty($authors) ? '' : $authors,
'license' => $plugin->license(), 'license' => $plugin->license() ?? '',
'name' => [ 'name' => [
'text' => $plugin->name(), 'text' => $plugin->name() ?? '',
'href' => $plugin->link(), 'href' => $plugin->link(),
], ],
'version' => $plugin->version(), 'version' => $version,
]; ];
}); });
$security = $updateStatus?->messages() ?? [];
if ($kirby->option('debug', false) === true) {
$security[] = [
'id' => 'debug',
'text' => I18n::translate('system.issues.debug'),
'link' => 'https://getkirby.com/security/debug'
];
}
if ($kirby->environment()->https() !== true) {
$security[] = [
'id' => 'https',
'text' => I18n::translate('system.issues.https'),
'link' => 'https://getkirby.com/security/https'
];
}
return [ return [
'component' => 'k-system-view', 'component' => 'k-system-view',
'props' => [ 'props' => [
'debug' => $kirby->option('debug', false), 'environment' => $environment,
'license' => $license, 'exceptions' => $kirby->option('debug') === true ? $exceptions : [],
'plugins' => $plugins, 'plugins' => $plugins,
'php' => phpversion(), 'security' => $security,
'server' => $system->serverSoftware(),
'https' => $kirby->environment()->https(),
'version' => $kirby->version(),
'urls' => [ 'urls' => [
'content' => $system->exposedFileUrl('content'), 'content' => $system->exposedFileUrl('content'),
'git' => $system->exposedFileUrl('git'), 'git' => $system->exposedFileUrl('git'),

View file

@ -1,5 +1,10 @@
<?php /** @var \Kirby\Cms\Block $block */ ?> <?php
<figure> /** @var \Kirby\Cms\Block $block */
$caption = $block->caption();
$crop = $block->crop()->isTrue();
$ratio = $block->ratio()->or('auto');
?>
<figure<?= Html::attr(['data-ratio' => $ratio, 'data-crop' => $crop], null, ' ') ?>>
<ul> <ul>
<?php foreach ($block->images()->toFiles() as $image): ?> <?php foreach ($block->images()->toFiles() as $image): ?>
<li> <li>
@ -7,4 +12,9 @@
</li> </li>
<?php endforeach ?> <?php endforeach ?>
</ul> </ul>
<?php if ($caption->isNotEmpty()): ?>
<figcaption>
<?= $caption ?>
</figcaption>
<?php endif ?>
</figure> </figure>

View file

@ -14,3 +14,27 @@ fields:
template: blocks/image template: blocks/image
image: image:
ratio: 1/1 ratio: 1/1
caption:
label: field.blocks.image.caption
type: writer
icon: text
inline: true
ratio:
label: field.blocks.image.ratio
type: select
placeholder: Auto
width: 1/2
options:
1/1: "1:1"
16/9: "16:9"
10/8: "10:8"
21/9: "21:9"
7/5: "7:5"
4/3: "4:3"
5/3: "5:3"
3/2: "3:2"
3/1: "3:1"
crop:
label: field.blocks.image.crop
type: toggle
width: 1/2

View file

@ -4,8 +4,9 @@ use Kirby\Cms\App;
use Kirby\Cms\Collection; use Kirby\Cms\Collection;
use Kirby\Cms\File; use Kirby\Cms\File;
use Kirby\Cms\FileVersion; use Kirby\Cms\FileVersion;
use Kirby\Cms\Helpers; use Kirby\Cms\Page;
use Kirby\Cms\Template; use Kirby\Cms\Template;
use Kirby\Cms\User;
use Kirby\Data\Data; use Kirby\Data\Data;
use Kirby\Email\PHPMailer as Emailer; use Kirby\Email\PHPMailer as Emailer;
use Kirby\Filesystem\F; use Kirby\Filesystem\F;
@ -30,33 +31,6 @@ return [
*/ */
'css' => fn (App $kirby, string $url, $options = null): string => $url, 'css' => fn (App $kirby, string $url, $options = null): string => $url,
/**
* Object and variable dumper
* to help with debugging.
*
* @param \Kirby\Cms\App $kirby Kirby instance
* @param mixed $variable
* @param bool $echo
* @return string
*
* @deprecated 3.7.0 Disable `dump()` via `KIRBY_HELPER_DUMP` instead and create your own function
* @todo move to `Helpers::dump()`, remove component in 3.8.0
*/
'dump' => function (App $kirby, $variable, bool $echo = true) {
if ($kirby->environment()->cli() === true) {
$output = print_r($variable, true) . PHP_EOL;
} else {
$output = '<pre>' . print_r($variable, true) . '</pre>';
}
if ($echo === true) {
echo $output;
}
return $output;
},
/** /**
* Add your own email provider * Add your own email provider
* *
@ -108,7 +82,7 @@ return [
Data::write($job, array_merge($options, [ Data::write($job, array_merge($options, [
'filename' => $file->filename() 'filename' => $file->filename()
])); ]));
} catch (Throwable $e) { } catch (Throwable) {
// if thumb doesn't exist yet and job file cannot // if thumb doesn't exist yet and job file cannot
// be created, return // be created, return
return $file; return $file;
@ -138,24 +112,16 @@ return [
* @param \Kirby\Cms\App $kirby Kirby instance * @param \Kirby\Cms\App $kirby Kirby instance
* @param string $text Text to parse * @param string $text Text to parse
* @param array $options Markdown options * @param array $options Markdown options
* @param bool $inline Whether to wrap the text in `<p>` tags (deprecated: set via $options['inline'] instead)
* @return string * @return string
* @todo remove $inline parameter in in 3.8.0
*/ */
'markdown' => function (App $kirby, string $text = null, array $options = [], bool $inline = false): string { 'markdown' => function (
App $kirby,
string $text = null,
array $options = []
): string {
static $markdown; static $markdown;
static $config; static $config;
// warning for deprecated fourth parameter
if (func_num_args() === 4 && isset($options['inline']) === false) {
// @codeCoverageIgnoreStart
Helpers::deprecated('markdown component: the $inline parameter is deprecated and will be removed in Kirby 3.8.0. Use $options[\'inline\'] instead.');
// @codeCoverageIgnoreEnd
}
// support for the deprecated fourth argument
$options['inline'] ??= $inline;
// if the config options have changed or the component is called for the first time, // if the config options have changed or the component is called for the first time,
// (re-)initialize the parser object // (re-)initialize the parser object
if ($config !== $options) { if ($config !== $options) {
@ -206,17 +172,22 @@ return [
return $options['words'] ? '\b' . preg_quote($value) . '\b' : preg_quote($value); return $options['words'] ? '\b' . preg_quote($value) . '\b' : preg_quote($value);
}, $searchWords); }, $searchWords);
// returns an empty collection if there is no search word
if (empty($searchWords) === true) {
return $collection->limit(0);
}
$preg = '!(' . implode('|', $searchWords) . ')!i'; $preg = '!(' . implode('|', $searchWords) . ')!i';
$results = $collection->filter(function ($item) use ($query, $preg, $options, $lowerQuery, $exactQuery) { $results = $collection->filter(function ($item) use ($query, $preg, $options, $lowerQuery, $exactQuery) {
$data = $item->content()->toArray(); $data = $item->content()->toArray();
$keys = array_keys($data); $keys = array_keys($data);
$keys[] = 'id'; $keys[] = 'id';
if (is_a($item, 'Kirby\Cms\User') === true) { if ($item instanceof User) {
$keys[] = 'name'; $keys[] = 'name';
$keys[] = 'email'; $keys[] = 'email';
$keys[] = 'role'; $keys[] = 'role';
} elseif (is_a($item, 'Kirby\Cms\Page') === true) { } elseif ($item instanceof Page) {
// apply the default score for pages // apply the default score for pages
$options['score'] = array_merge([ $options['score'] = array_merge([
'id' => 64, 'id' => 64,
@ -295,9 +266,8 @@ return [
* @param \Kirby\Cms\App $kirby Kirby instance * @param \Kirby\Cms\App $kirby Kirby instance
* @param string|array $name Snippet name * @param string|array $name Snippet name
* @param array $data Data array for the snippet * @param array $data Data array for the snippet
* @return string|null
*/ */
'snippet' => function (App $kirby, $name, array $data = []): ?string { 'snippet' => function (App $kirby, $name, array $data = []): string {
$snippets = A::wrap($name); $snippets = A::wrap($name);
foreach ($snippets as $name) { foreach ($snippets as $name) {

View file

@ -46,13 +46,13 @@ return [
/** /**
* Latest date, which can be selected/saved (Y-m-d) * Latest date, which can be selected/saved (Y-m-d)
*/ */
'max' => function (string $max = null): ?string { 'max' => function (string $max = null): string|null {
return Date::optional($max); return Date::optional($max);
}, },
/** /**
* Earliest date, which can be selected/saved (Y-m-d) * Earliest date, which can be selected/saved (Y-m-d)
*/ */
'min' => function (string $min = null): ?string { 'min' => function (string $min = null): string|null {
return Date::optional($min); return Date::optional($min);
}, },

View file

@ -34,7 +34,10 @@ return [
], ],
'computed' => [ 'computed' => [
'parentModel' => function () { 'parentModel' => function () {
if (is_string($this->parent) === true && $model = $this->model()->query($this->parent, 'Kirby\Cms\Model')) { if (
is_string($this->parent) === true &&
$model = $this->model()->query($this->parent, 'Kirby\Cms\Model')
) {
return $model; return $model;
} }
@ -68,10 +71,13 @@ return [
foreach (Data::decode($value, 'yaml') as $id) { foreach (Data::decode($value, 'yaml') as $id) {
if (is_array($id) === true) { if (is_array($id) === true) {
$id = $id['id'] ?? null; $id = $id['uuid'] ?? $id['id'] ?? null;
} }
if ($id !== null && ($file = $this->kirby()->file($id, $this->model()))) { if (
$id !== null &&
($file = $this->kirby()->file($id, $this->model()))
) {
$files[] = $this->fileResponse($file); $files[] = $this->fileResponse($file);
} }
} }
@ -122,7 +128,7 @@ return [
]; ];
}, },
'save' => function ($value = null) { 'save' => function ($value = null) {
return A::pluck($value, 'uuid'); return A::pluck($value, $this->store);
}, },
'validations' => [ 'validations' => [
'max', 'max',

View file

@ -1,6 +1,6 @@
<?php <?php
use Kirby\Form\Options; use Kirby\Field\FieldOptions;
return [ return [
'props' => [ 'props' => [
@ -30,19 +30,18 @@ return [
], ],
'methods' => [ 'methods' => [
'getOptions' => function () { 'getOptions' => function () {
return Options::factory( $props = FieldOptions::polyfill($this->props);
$this->options(), $options = FieldOptions::factory($props['options']);
$this->props, return $options->render($this->model());
$this->model()
);
}, },
'sanitizeOption' => function ($option) { 'sanitizeOption' => function ($value) {
$allowed = array_column($this->options(), 'value'); $options = array_column($this->options(), 'value');
return in_array($option, $allowed, true) === true ? $option : null; return in_array($value, $options, true) === true ? $value : null;
}, },
'sanitizeOptions' => function ($options) { 'sanitizeOptions' => function ($values) {
$allowed = array_column($this->options(), 'value'); $options = array_column($this->options(), 'value');
return array_intersect($options, $allowed); $options = array_intersect($values, $options);
return array_values($options);
}, },
] ]
]; ];

View file

@ -1,6 +1,7 @@
<?php <?php
use Kirby\Toolkit\I18n; use Kirby\Toolkit\I18n;
use Kirby\Toolkit\Str;
return [ return [
'props' => [ 'props' => [
@ -67,12 +68,21 @@ return [
return $search; return $search;
}, },
/**
* Whether to store UUID or ID in the
* content file of the model
*
* @param string $store 'uuid'|'id'
*/
'store' => function (string $store = 'uuid') {
return Str::lower($store);
},
/** /**
* Main text for each item * Main text for each item
*/ */
'text' => function (string $text = null) { 'text' => function (string $text = null) {
return $text; return $text;
}, },
], ],
]; ];

View file

@ -51,7 +51,7 @@ return [
$parent = $this->model(); $parent = $this->model();
} }
if (is_a($parent, 'Kirby\Cms\File') === true) { if ($parent instanceof File) {
$parent = $parent->parent(); $parent = $parent->parent();
} }
@ -62,7 +62,7 @@ return [
'filename' => $filename, 'filename' => $filename,
]); ]);
if (is_a($file, 'Kirby\Cms\File') === false) { if ($file instanceof File === false) {
throw new Exception('The file could not be uploaded'); throw new Exception('The file could not be uploaded');
} }

View file

@ -1,5 +1,7 @@
<?php <?php
use Kirby\Toolkit\Str;
return [ return [
'extends' => 'tags', 'extends' => 'tags',
'props' => [ 'props' => [
@ -28,5 +30,18 @@ return [
'sort' => function (bool $sort = false) { 'sort' => function (bool $sort = false) {
return $sort; return $sort;
}, },
] ],
'methods' => [
'toValues' => function ($value) {
if (is_null($value) === true) {
return [];
}
if (is_array($value) === false) {
$value = Str::split($value, $this->separator());
}
return $this->sanitizeOptions($value);
}
],
]; ];

View file

@ -0,0 +1,104 @@
<?php
use Kirby\Data\Data;
use Kirby\Exception\InvalidArgumentException;
use Kirby\Form\Form;
use Kirby\Toolkit\I18n;
return [
'props' => [
/**
* Unset inherited props
*/
'after' => null,
'before' => null,
'autofocus' => null,
'icon' => null,
'placeholder' => null,
/**
* Set the default values for the object
*/
'default' => function ($default = null) {
return $default;
},
/**
* The placeholder text if no information has been added yet
*/
'empty' => function ($empty = null) {
return I18n::translate($empty, $empty);
},
/**
* Fields setup for the object form. Works just like fields in regular forms.
*/
'fields' => function (array $fields = []) {
return $fields;
}
],
'computed' => [
'default' => function () {
if (empty($this->default) === true) {
return '';
}
return $this->form($this->default)->values();
},
'fields' => function () {
if (empty($this->fields) === true) {
throw new Exception('Please provide some fields for the object');
}
return $this->form()->fields()->toArray();
},
'value' => function () {
$data = Data::decode($this->value, 'yaml');
if (empty($data) === true) {
return '';
}
return $this->form($data)->values();
}
],
'methods' => [
'form' => function (array $values = []) {
return new Form([
'fields' => $this->attrs['fields'],
'values' => $values,
'model' => $this->model
]);
},
],
'save' => function ($value) {
if (empty($value) === true) {
return '';
}
return $this->form($value)->content();
},
'validations' => [
'object' => function ($value) {
if (empty($value) === true) {
return true;
}
$errors = $this->form($value)->errors();
if (empty($errors) === false) {
// use the first error for details
$name = array_key_first($errors);
$error = $errors[$name];
throw new InvalidArgumentException([
'key' => 'object.validation',
'data' => [
'label' => $error['label'] ?? $name,
'message' => implode("\n", $error['message'])
]
]);
}
}
]
];

View file

@ -67,7 +67,7 @@ return [
foreach (Data::decode($value, 'yaml') as $id) { foreach (Data::decode($value, 'yaml') as $id) {
if (is_array($id) === true) { if (is_array($id) === true) {
$id = $id['id'] ?? null; $id = $id['uuid'] ?? $id['id'] ?? null;
} }
if ($id !== null && ($page = $kirby->page($id))) { if ($id !== null && ($page = $kirby->page($id))) {
@ -102,7 +102,7 @@ return [
]; ];
}, },
'save' => function ($value = null) { 'save' => function ($value = null) {
return A::pluck($value, 'id'); return A::pluck($value, $this->store);
}, },
'validations' => [ 'validations' => [
'max', 'max',

View file

@ -108,7 +108,7 @@ return [
$columns = []; $columns = [];
$mobile = 0; $mobile = 0;
if (empty($this->columns)) { if (empty($this->columns) === true) {
foreach ($this->fields as $field) { foreach ($this->fields as $field) {
// Skip hidden and unsaveable fields // Skip hidden and unsaveable fields
// They should never be included as column // They should never be included as column
@ -129,7 +129,10 @@ return [
$field = $this->fields[$columnName] ?? null; $field = $this->fields[$columnName] ?? null;
if (empty($field) === true || $field['saveable'] === false) { if (
empty($field) === true ||
$field['saveable'] === false
) {
continue; continue;
} }
@ -137,10 +140,10 @@ return [
$mobile++; $mobile++;
} }
$columns[$columnName] = array_merge($columnProps, [ $columns[$columnName] = array_merge([
'type' => $field['type'], 'type' => $field['type'],
'label' => $field['label'] ?? $field['name'] 'label' => $field['label'] ?? $field['name']
]); ], $columnProps);
} }
} }

View file

@ -31,7 +31,7 @@ return [
* Set to `list` to display each tag with 100% width, * Set to `list` to display each tag with 100% width,
* otherwise the tags are displayed inline * otherwise the tags are displayed inline
*/ */
'layout' => function (?string $layout = null) { 'layout' => function (string|null $layout = null) {
return $layout; return $layout;
}, },
/** /**
@ -55,43 +55,32 @@ return [
], ],
'computed' => [ 'computed' => [
'default' => function (): array { 'default' => function (): array {
return $this->toTags($this->default); return $this->toValues($this->default);
}, },
'value' => function (): array { 'value' => function (): array {
return $this->toTags($this->value); return $this->toValues($this->value);
} }
], ],
'methods' => [ 'methods' => [
'toTags' => function ($value) { 'toValues' => function ($value) {
if (is_null($value) === true) { if (is_null($value) === true) {
return []; return [];
} }
$options = $this->options(); if (is_array($value) === false) {
$value = Str::split($value, $this->separator());
// transform into value-text objects
return array_map(function ($option) use ($options) {
// already a valid object
if (is_array($option) === true && isset($option['value'], $option['text']) === true) {
return $option;
} }
$index = array_search($option, array_column($options, 'value')); if ($this->accept === 'options') {
$value = $this->sanitizeOptions($value);
if ($index !== false) {
return $options[$index];
} }
return [ return $value;
'value' => $option,
'text' => $option,
];
}, Str::split($value, $this->separator()));
} }
], ],
'save' => function (array $value = null): string { 'save' => function (array $value = null): string {
return A::join( return A::join(
A::pluck($value, 'value'), $value,
$this->separator() . ' ' $this->separator() . ' '
); );
}, },

View file

@ -15,7 +15,7 @@ return [
/** /**
* Sets the default time when a new page/file/user is created * Sets the default time when a new page/file/user is created
*/ */
'default' => function ($default = null): ?string { 'default' => function ($default = null): string|null {
return $default; return $default;
}, },
@ -36,13 +36,13 @@ return [
/** /**
* Latest time, which can be selected/saved (H:i or H:i:s) * Latest time, which can be selected/saved (H:i or H:i:s)
*/ */
'max' => function (string $max = null): ?string { 'max' => function (string $max = null): string|null {
return Date::optional($max); return Date::optional($max);
}, },
/** /**
* Earliest time, which can be selected/saved (H:i or H:i:s) * Earliest time, which can be selected/saved (H:i or H:i:s)
*/ */
'min' => function (string $min = null): ?string { 'min' => function (string $min = null): string|null {
return Date::optional($min); return Date::optional($min);
}, },
@ -62,7 +62,7 @@ return [
'unit' => 'minute', 'unit' => 'minute',
]); ]);
}, },
'value' => function ($value = null): ?string { 'value' => function ($value = null): string|null {
return $value; return $value;
} }
], ],
@ -80,7 +80,7 @@ return [
'format' => function () { 'format' => function () {
return $this->props['format'] ?? 'H:i:s'; return $this->props['format'] ?? 'H:i:s';
}, },
'value' => function (): ?string { 'value' => function (): string|null {
return $this->toDatetime($this->value, 'H:i:s') ?? ''; return $this->toDatetime($this->value, 'H:i:s') ?? '';
} }
], ],

View file

@ -49,9 +49,9 @@ return [
'value' => function () { 'value' => function () {
if ($this->props['value'] === null) { if ($this->props['value'] === null) {
return $this->default(); return $this->default();
} else {
return $this->toBool($this->props['value']);
} }
return $this->toBool($this->props['value']);
} }
], ],
'methods' => [ 'methods' => [

View file

@ -96,7 +96,7 @@ return [
]; ];
}, },
'save' => function ($value = null) { 'save' => function ($value = null) {
return A::pluck($value, 'id'); return A::pluck($value, $this->store);
}, },
'validations' => [ 'validations' => [
'max', 'max',

View file

@ -3,10 +3,10 @@
use Kirby\Cms\App; use Kirby\Cms\App;
use Kirby\Cms\Helpers; use Kirby\Cms\Helpers;
use Kirby\Cms\Html; use Kirby\Cms\Html;
use Kirby\Cms\Response;
use Kirby\Cms\Url; use Kirby\Cms\Url;
use Kirby\Filesystem\Asset; use Kirby\Filesystem\Asset;
use Kirby\Filesystem\F; use Kirby\Filesystem\F;
use Kirby\Http\Response;
use Kirby\Http\Router; use Kirby\Http\Router;
use Kirby\Toolkit\Date; use Kirby\Toolkit\Date;
use Kirby\Toolkit\I18n; use Kirby\Toolkit\I18n;
@ -35,7 +35,7 @@ if (Helpers::hasOverride('attr') === false) { // @codeCoverageIgnore
* @param string|null $after An optional string that will be appended if the result is not empty * @param string|null $after An optional string that will be appended if the result is not empty
* @return string|null * @return string|null
*/ */
function attr(?array $attr = null, ?string $before = null, ?string $after = null): ?string function attr(array|null $attr = null, string|null $before = null, string|null $after = null): string|null
{ {
return Html::attr($attr, null, $before, $after); return Html::attr($attr, null, $before, $after);
} }
@ -61,7 +61,7 @@ if (Helpers::hasOverride('csrf') === false) { // @codeCoverageIgnore
* @param string|null $check Pass a token here to compare it to the one in the session * @param string|null $check Pass a token here to compare it to the one in the session
* @return string|bool Either the token or a boolean check result * @return string|bool Either the token or a boolean check result
*/ */
function csrf(?string $check = null) function csrf(string|null $check = null)
{ {
// check explicitly if there have been no arguments at all; // check explicitly if there have been no arguments at all;
// checking for null introduces a security issue because null could come // checking for null introduces a security issue because null could come
@ -82,7 +82,7 @@ if (Helpers::hasOverride('css') === false) { // @codeCoverageIgnore
* @param string|array $options Pass an array of attributes for the link tag or a media attribute string * @param string|array $options Pass an array of attributes for the link tag or a media attribute string
* @return string|null * @return string|null
*/ */
function css($url, $options = null): ?string function css($url, $options = null): string|null
{ {
return Html::css($url, $options); return Html::css($url, $options);
} }
@ -167,7 +167,7 @@ if (Helpers::hasOverride('gist') === false) { // @codeCoverageIgnore
* @param string|null $file * @param string|null $file
* @return string * @return string
*/ */
function gist(string $url, ?string $file = null): string function gist(string $url, string|null $file = null): string
{ {
return App::instance()->kirbytag([ return App::instance()->kirbytag([
'gist' => $url, 'gist' => $url,
@ -199,7 +199,7 @@ if (Helpers::hasOverride('h') === false) { // @codeCoverageIgnore
* @param bool $keepTags * @param bool $keepTags
* @return string * @return string
*/ */
function h(?string $string, bool $keepTags = false): string function h(string|null $string, bool $keepTags = false): string
{ {
return Html::encode($string, $keepTags); return Html::encode($string, $keepTags);
} }
@ -213,7 +213,7 @@ if (Helpers::hasOverride('html') === false) { // @codeCoverageIgnore
* @param bool $keepTags * @param bool $keepTags
* @return string * @return string
*/ */
function html(?string $string, bool $keepTags = false): string function html(string|null $string, bool $keepTags = false): string
{ {
return Html::encode($string, $keepTags); return Html::encode($string, $keepTags);
} }
@ -230,7 +230,7 @@ if (Helpers::hasOverride('image') === false) { // @codeCoverageIgnore
* @param string|null $path * @param string|null $path
* @return \Kirby\Cms\File|null * @return \Kirby\Cms\File|null
*/ */
function image(?string $path = null) function image(string|null $path = null)
{ {
return App::instance()->image($path); return App::instance()->image($path);
} }
@ -259,7 +259,7 @@ if (Helpers::hasOverride('js') === false) { // @codeCoverageIgnore
* @param string|array $options * @param string|array $options
* @return string|null * @return string|null
*/ */
function js($url, $options = null): ?string function js($url, $options = null): string|null
{ {
return Html::js($url, $options); return Html::js($url, $options);
} }
@ -287,7 +287,7 @@ if (Helpers::hasOverride('kirbytag') === false) { // @codeCoverageIgnore
* @param array $data * @param array $data
* @return string * @return string
*/ */
function kirbytag($type, ?string $value = null, array $attr = [], array $data = []): string function kirbytag($type, string|null $value = null, array $attr = [], array $data = []): string
{ {
return App::instance()->kirbytag($type, $value, $attr, $data); return App::instance()->kirbytag($type, $value, $attr, $data);
} }
@ -302,7 +302,7 @@ if (Helpers::hasOverride('kirbytags') === false) { // @codeCoverageIgnore
* @param array $data * @param array $data
* @return string * @return string
*/ */
function kirbytags(?string $text = null, array $data = []): string function kirbytags(string|null $text = null, array $data = []): string
{ {
return App::instance()->kirbytags($text, $data); return App::instance()->kirbytags($text, $data);
} }
@ -317,7 +317,7 @@ if (Helpers::hasOverride('kirbytext') === false) { // @codeCoverageIgnore
* @param array $data * @param array $data
* @return string * @return string
*/ */
function kirbytext(?string $text = null, array $data = []): string function kirbytext(string|null $text = null, array $data = []): string
{ {
return App::instance()->kirbytext($text, $data); return App::instance()->kirbytext($text, $data);
} }
@ -333,7 +333,7 @@ if (Helpers::hasOverride('kirbytextinline') === false) { // @codeCoverageIgnore
* @param array $options * @param array $options
* @return string * @return string
*/ */
function kirbytextinline(?string $text = null, array $options = []): string function kirbytextinline(string|null $text = null, array $options = []): string
{ {
$options['markdown']['inline'] = true; $options['markdown']['inline'] = true;
return App::instance()->kirbytext($text, $options); return App::instance()->kirbytext($text, $options);
@ -348,7 +348,7 @@ if (Helpers::hasOverride('kt') === false) { // @codeCoverageIgnore
* @param array $data * @param array $data
* @return string * @return string
*/ */
function kt(?string $text = null, array $data = []): string function kt(string|null $text = null, array $data = []): string
{ {
return App::instance()->kirbytext($text, $data); return App::instance()->kirbytext($text, $data);
} }
@ -363,7 +363,7 @@ if (Helpers::hasOverride('kti') === false) { // @codeCoverageIgnore
* @param array $options * @param array $options
* @return string * @return string
*/ */
function kti(?string $text = null, array $options = []): string function kti(string|null $text = null, array $options = []): string
{ {
$options['markdown']['inline'] = true; $options['markdown']['inline'] = true;
return App::instance()->kirbytext($text, $options); return App::instance()->kirbytext($text, $options);
@ -378,7 +378,7 @@ if (Helpers::hasOverride('load') === false) { // @codeCoverageIgnore
* @param string|null $base * @param string|null $base
* @return void * @return void
*/ */
function load(array $classmap, ?string $base = null): void function load(array $classmap, string|null $base = null): void
{ {
F::loadClasses($classmap, $base); F::loadClasses($classmap, $base);
} }
@ -393,7 +393,7 @@ if (Helpers::hasOverride('markdown') === false) { // @codeCoverageIgnore
* @param array $options * @param array $options
* @return string * @return string
*/ */
function markdown(?string $text = null, array $options = []): string function markdown(string|null $text = null, array $options = []): string
{ {
return App::instance()->markdown($text, $options); return App::instance()->markdown($text, $options);
} }
@ -421,7 +421,7 @@ if (Helpers::hasOverride('page') === false) { // @codeCoverageIgnore
* @param string|null $id * @param string|null $id
* @return \Kirby\Cms\Page|null * @return \Kirby\Cms\Page|null
*/ */
function page(?string $id = null) function page(string|null $id = null)
{ {
if (empty($id) === true) { if (empty($id) === true) {
return App::instance()->site()->page(); return App::instance()->site()->page();
@ -459,8 +459,9 @@ if (Helpers::hasOverride('param') === false) { // @codeCoverageIgnore
* @param string $key * @param string $key
* @param string|null $fallback * @param string|null $fallback
* @return string|null * @return string|null
* @psalm-return ($fallback is string ? string : string|null)
*/ */
function param(string $key, ?string $fallback = null): ?string function param(string $key, string|null $fallback = null): string|null
{ {
return App::instance()->request()->url()->params()->$key ?? $fallback; return App::instance()->request()->url()->params()->$key ?? $fallback;
} }
@ -505,7 +506,7 @@ if (Helpers::hasOverride('router') === false) { // @codeCoverageIgnore
* @param \Closure|null $callback * @param \Closure|null $callback
* @return mixed * @return mixed
*/ */
function router(?string $path = null, string $method = 'GET', array $routes = [], ?Closure $callback = null) function router(string|null $path = null, string $method = 'GET', array $routes = [], Closure|null $callback = null)
{ {
return Router::execute($path, $method, $routes, $callback); return Router::execute($path, $method, $routes, $callback);
} }
@ -545,7 +546,7 @@ if (Helpers::hasOverride('smartypants') === false) { // @codeCoverageIgnore
* @param string|null $text * @param string|null $text
* @return string * @return string
*/ */
function smartypants(?string $text = null): string function smartypants(string|null $text = null): string
{ {
return App::instance()->smartypants($text); return App::instance()->smartypants($text);
} }
@ -560,7 +561,7 @@ if (Helpers::hasOverride('snippet') === false) { // @codeCoverageIgnore
* @param bool $return * @param bool $return
* @return string|null * @return string|null
*/ */
function snippet($name, $data = [], bool $return = false): ?string function snippet($name, $data = [], bool $return = false): string|null
{ {
return App::instance()->snippet($name, $data, $return); return App::instance()->snippet($name, $data, $return);
} }
@ -624,7 +625,7 @@ if (Helpers::hasOverride('timestamp') === false) { // @codeCoverageIgnore
* @param int|array|null $step array of `unit` and `size` to round to nearest * @param int|array|null $step array of `unit` and `size` to round to nearest
* @return int|null * @return int|null
*/ */
function timestamp(?string $date = null, $step = null): ?int function timestamp(string|null $date = null, $step = null): int|null
{ {
return Date::roundedTimestamp($date, $step); return Date::roundedTimestamp($date, $step);
} }
@ -641,7 +642,7 @@ if (Helpers::hasOverride('tt') === false) { // @codeCoverageIgnore
* @param string|null $locale * @param string|null $locale
* @return string * @return string
*/ */
function tt(string $key, $fallback = null, ?array $replace = null, ?string $locale = null): string function tt(string $key, $fallback = null, array|null $replace = null, string|null $locale = null): string
{ {
return I18n::template($key, $fallback, $replace, $locale); return I18n::template($key, $fallback, $replace, $locale);
} }
@ -657,7 +658,7 @@ if (Helpers::hasOverride('twitter') === false) { // @codeCoverageIgnore
* @param string|null $class * @param string|null $class
* @return string * @return string
*/ */
function twitter(string $username, ?string $text = null, ?string $title = null, ?string $class = null): string function twitter(string $username, string|null $text = null, string|null $title = null, string|null $class = null): string
{ {
return App::instance()->kirbytag([ return App::instance()->kirbytag([
'twitter' => $username, 'twitter' => $username,
@ -676,7 +677,7 @@ if (Helpers::hasOverride('u') === false) { // @codeCoverageIgnore
* @param array|string|null $options * @param array|string|null $options
* @return string * @return string
*/ */
function u(?string $path = null, $options = null): string function u(string|null $path = null, $options = null): string
{ {
return Url::to($path, $options); return Url::to($path, $options);
} }
@ -690,7 +691,7 @@ if (Helpers::hasOverride('url') === false) { // @codeCoverageIgnore
* @param array|string|null $options * @param array|string|null $options
* @return string * @return string
*/ */
function url(?string $path = null, $options = null): string function url(string|null $path = null, $options = null): string
{ {
return Url::to($path, $options); return Url::to($path, $options);
} }
@ -719,7 +720,7 @@ if (Helpers::hasOverride('video') === false) { // @codeCoverageIgnore
* @param array $attr * @param array $attr
* @return string|null * @return string|null
*/ */
function video(string $url, array $options = [], array $attr = []): ?string function video(string $url, array $options = [], array $attr = []): string|null
{ {
return Html::video($url, $options, $attr); return Html::video($url, $options, $attr);
} }
@ -734,7 +735,7 @@ if (Helpers::hasOverride('vimeo') === false) { // @codeCoverageIgnore
* @param array $attr * @param array $attr
* @return string|null * @return string|null
*/ */
function vimeo(string $url, array $options = [], array $attr = []): ?string function vimeo(string $url, array $options = [], array $attr = []): string|null
{ {
return Html::vimeo($url, $options, $attr); return Html::vimeo($url, $options, $attr);
} }
@ -764,7 +765,7 @@ if (Helpers::hasOverride('youtube') === false) { // @codeCoverageIgnore
* @param array $attr * @param array $attr
* @return string|null * @return string|null
*/ */
function youtube(string $url, array $options = [], array $attr = []): ?string function youtube(string $url, array $options = [], array $attr = []): string|null
{ {
return Html::youtube($url, $options, $attr); return Html::youtube($url, $options, $attr);
} }

View file

@ -2,6 +2,7 @@
use Kirby\Cms\App; use Kirby\Cms\App;
use Kirby\Cms\Blocks; use Kirby\Cms\Blocks;
use Kirby\Cms\Content;
use Kirby\Cms\Field; use Kirby\Cms\Field;
use Kirby\Cms\Files; use Kirby\Cms\Files;
use Kirby\Cms\Html; use Kirby\Cms\Html;
@ -63,16 +64,16 @@ return function (App $app) {
*/ */
'toBlocks' => function (Field $field) { 'toBlocks' => function (Field $field) {
try { try {
$blocks = Blocks::factory(Blocks::parse($field->value()), [ $blocks = Blocks::parse($field->value());
'parent' => $field->parent(), $blocks = Blocks::factory($blocks, [
'parent' => $field->parent()
]); ]);
return $blocks->filter('isHidden', false); return $blocks->filter('isHidden', false);
} catch (Throwable $e) { } catch (Throwable) {
if ($field->parent() === null) {
$message = 'Invalid blocks data for "' . $field->key() . '" field'; $message = 'Invalid blocks data for "' . $field->key() . '" field';
} else {
$message = 'Invalid blocks data for "' . $field->key() . '" field on parent "' . $field->parent()->title() . '"'; if ($parent = $field->parent()) {
$message .= ' on parent "' . $parent->title() . '"';
} }
throw new InvalidArgumentException($message); throw new InvalidArgumentException($message);
@ -99,13 +100,10 @@ return function (App $app) {
* @return array * @return array
*/ */
'toData' => function (Field $field, string $method = ',') { 'toData' => function (Field $field, string $method = ',') {
switch ($method) { return match ($method) {
case 'yaml': 'yaml', 'json' => Data::decode($field->value, $method),
case 'json': default => $field->split($method)
return Data::decode($field->value, $method); };
default:
return $field->split($method);
}
}, },
/** /**
@ -222,6 +220,17 @@ return function (App $app) {
return Html::a($href, $field->value, $attr ?? []); return Html::a($href, $field->value, $attr ?? []);
}, },
/**
* Parse yaml data and convert it to a
* content object
*
* @param \Kirby\Cms\Field $field
* @return \Kirby\Cms\Content
*/
'toObject' => function (Field $field) {
return new Content($field->yaml(), $field->parent(), true);
},
/** /**
* Returns a page object from a page id in the field * Returns a page object from a page id in the field
* *
@ -252,11 +261,11 @@ return function (App $app) {
'toStructure' => function (Field $field) { 'toStructure' => function (Field $field) {
try { try {
return new Structure(Data::decode($field->value, 'yaml'), $field->parent()); return new Structure(Data::decode($field->value, 'yaml'), $field->parent());
} catch (Exception $e) { } catch (Exception) {
if ($field->parent() === null) {
$message = 'Invalid structure data for "' . $field->key() . '" field'; $message = 'Invalid structure data for "' . $field->key() . '" field';
} else {
$message = 'Invalid structure data for "' . $field->key() . '" field on parent "' . $field->parent()->title() . '"'; if ($parent = $field->parent()) {
$message .= ' on parent "' . $parent->title() . '"';
} }
throw new InvalidArgumentException($message); throw new InvalidArgumentException($message);
@ -341,7 +350,7 @@ return function (App $app) {
* @param string $context Location of output (`html`, `attr`, `js`, `css`, `url` or `xml`) * @param string $context Location of output (`html`, `attr`, `js`, `css`, `url` or `xml`)
*/ */
'escape' => function (Field $field, string $context = 'html') { 'escape' => function (Field $field, string $context = 'html') {
$field->value = Str::esc($field->value, $context); $field->value = Str::esc($field->value ?? '', $context);
return $field; return $field;
}, },
@ -500,10 +509,11 @@ return function (App $app) {
* *
* @param \Kirby\Cms\Field $field * @param \Kirby\Cms\Field $field
* @param array $data * @param array $data
* @param string $fallback Fallback for tokens in the template that cannot be replaced * @param string|null $fallback Fallback for tokens in the template that cannot be replaced
* (`null` to keep the original token)
* @return \Kirby\Cms\Field * @return \Kirby\Cms\Field
*/ */
'replace' => function (Field $field, array $data = [], string $fallback = '') use ($app) { 'replace' => function (Field $field, array $data = [], string|null $fallback = '') use ($app) {
if ($parent = $field->parent()) { if ($parent = $field->parent()) {
// never pass `null` as the $template to avoid the fallback to the model ID // never pass `null` as the $template to avoid the fallback to the model ID
$field->value = $parent->toString($field->value ?? '', $data, $fallback); $field->value = $parent->toString($field->value ?? '', $data, $fallback);

View file

@ -5,7 +5,7 @@ use Kirby\Toolkit\I18n;
return function (array $props) { return function (array $props) {
$props['sections'] = [ $props['sections'] = [
'files' => [ 'files' => [
'headline' => $props['headline'] ?? I18n::translate('files'), 'label' => $props['label'] ?? $props['headline'] ?? I18n::translate('files'),
'type' => 'files', 'type' => 'files',
'layout' => $props['layout'] ?? 'cards', 'layout' => $props['layout'] ?? 'cards',
'template' => $props['template'] ?? null, 'template' => $props['template'] ?? null,
@ -17,6 +17,7 @@ return function (array $props) {
// remove global options // remove global options
unset( unset(
$props['headline'], $props['headline'],
$props['label'],
$props['layout'], $props['layout'],
$props['template'], $props['template'],
$props['image'] $props['image']

View file

@ -10,7 +10,7 @@ return function ($props) {
if (is_string($props) === true) { if (is_string($props) === true) {
$props = [ $props = [
'headline' => $props 'label' => $props
]; ];
} }
@ -27,7 +27,7 @@ return function ($props) {
if ($pages !== false) { if ($pages !== false) {
$sidebar['pages'] = $section([ $sidebar['pages'] = $section([
'headline' => I18n::translate('pages'), 'label' => I18n::translate('pages'),
'type' => 'pages', 'type' => 'pages',
'status' => 'all', 'status' => 'all',
'layout' => 'list', 'layout' => 'list',
@ -36,7 +36,7 @@ return function ($props) {
if ($files !== false) { if ($files !== false) {
$sidebar['files'] = $section([ $sidebar['files'] = $section([
'headline' => I18n::translate('files'), 'label' => I18n::translate('files'),
'type' => 'files', 'type' => 'files',
'layout' => 'list' 'layout' => 'list'
], $files); ], $files);

View file

@ -6,9 +6,9 @@ return function (array $props) {
// load the general templates setting for all sections // load the general templates setting for all sections
$templates = $props['templates'] ?? null; $templates = $props['templates'] ?? null;
$section = function ($headline, $status, $props) use ($templates) { $section = function ($label, $status, $props) use ($templates) {
$defaults = [ $defaults = [
'headline' => $headline, 'label' => $label,
'type' => 'pages', 'type' => 'pages',
'layout' => 'list', 'layout' => 'list',
'status' => $status 'status' => $status
@ -20,7 +20,7 @@ return function (array $props) {
if (is_string($props) === true) { if (is_string($props) === true) {
$props = [ $props = [
'headline' => $props 'label' => $props
]; ];
} }

View file

@ -6,6 +6,7 @@ use Kirby\Cms\PluginAssets;
use Kirby\Panel\Panel; use Kirby\Panel\Panel;
use Kirby\Panel\Plugins; use Kirby\Panel\Plugins;
use Kirby\Toolkit\Str; use Kirby\Toolkit\Str;
use Kirby\Uuid\Uuid;
return function ($kirby) { return function ($kirby) {
$api = $kirby->option('api.slug', 'api'); $api = $kirby->option('api.slug', 'api');
@ -101,6 +102,26 @@ return function ($kirby) {
return Panel::router($path); return Panel::router($path);
} }
], ],
// permalinks for page/file UUIDs
[
'pattern' => '@/(page|file)/(:all)',
'method' => 'ALL',
'env' => 'site',
'action' => function (string $type, string $id) use ($kirby) {
// try to resolve to model, but only from UUID cache;
// this ensures that only existing UUIDs can be queried
// and attackers can't force Kirby to go through the whole
// site index with a non-existing UUID
if ($model = Uuid::for($type . '://' . $id)?->model(true)) {
return $kirby
->response()
->redirect($model->url());
}
// render the error page
return false;
}
],
]; ];
// Multi-language setup // Multi-language setup

View file

@ -1,5 +1,7 @@
<?php <?php
use Kirby\Cms\Page;
use Kirby\Cms\Site;
use Kirby\Form\Form; use Kirby\Form\Form;
return [ return [
@ -31,7 +33,10 @@ return [
'fields' => function () { 'fields' => function () {
$fields = $this->form->fields()->toArray(); $fields = $this->form->fields()->toArray();
if (is_a($this->model, 'Kirby\Cms\Page') === true || is_a($this->model, 'Kirby\Cms\Site') === true) { if (
$this->model instanceof Page ||
$this->model instanceof Site
) {
// the title should never be updated directly via // the title should never be updated directly via
// fields section to avoid conflicts with the rename dialog // fields section to avoid conflicts with the rename dialog
unset($fields['title']); unset($fields['title']);

View file

@ -25,7 +25,7 @@ return [
], ],
'toArray' => function () { 'toArray' => function () {
return [ return [
'headline' => $this->headline, 'label' => $this->headline,
'text' => $this->text, 'text' => $this->text,
'theme' => $this->theme 'theme' => $this->theme
]; ];

View file

@ -1,20 +1,14 @@
<?php <?php
use Kirby\Cms\Helpers;
use Kirby\Toolkit\I18n; use Kirby\Toolkit\I18n;
return [ return [
'props' => [ 'props' => [
/** /**
* The headline for the section. This can be a simple string or a template with additional info from the parent page. * The headline for the section. This can be a simple string or a template with additional info from the parent page.
* @todo remove in 3.9.0 * @deprecated 3.8.0 Use `label` instead
*/ */
'headline' => function ($headline = null) { 'headline' => function ($headline = null) {
// TODO: add deprecation notive in 3.8.0
// if ($headline !== null) {
// Helpers::deprecated('`headline` prop for sections has been deprecated and will be removed in Kirby 3.9.0. Use `label` instead.');
// }
return I18n::translate($headline, $headline); return I18n::translate($headline, $headline);
}, },
/** /**
@ -28,14 +22,14 @@ return [
], ],
'computed' => [ 'computed' => [
'headline' => function () { 'headline' => function () {
if ($this->headline) {
return $this->model()->toString($this->headline);
}
if ($this->label) { if ($this->label) {
return $this->model()->toString($this->label); return $this->model()->toString($this->label);
} }
if ($this->headline) {
return $this->model()->toString($this->headline);
}
return ucfirst($this->name); return ucfirst($this->name);
} }
] ]

View file

@ -1,5 +1,9 @@
<?php <?php
use Kirby\Cms\File;
use Kirby\Cms\Page;
use Kirby\Cms\Site;
use Kirby\Cms\User;
use Kirby\Exception\Exception; use Kirby\Exception\Exception;
return [ return [
@ -24,10 +28,10 @@ return [
} }
if ( if (
is_a($parent, 'Kirby\Cms\Page') === false && $parent instanceof Page === false &&
is_a($parent, 'Kirby\Cms\Site') === false && $parent instanceof Site === false &&
is_a($parent, 'Kirby\Cms\File') === false && $parent instanceof File === false &&
is_a($parent, 'Kirby\Cms\User') === false $parent instanceof User === false
) { ) {
throw new Exception('The parent for the section "' . $this->name() . '" has to be a page, site or user object'); throw new Exception('The parent for the section "' . $this->name() . '" has to be a page, site or user object');
} }

View file

@ -12,7 +12,7 @@ return [
} }
], ],
'methods' => [ 'methods' => [
'searchterm' => function (): ?string { 'searchterm' => function (): string|null {
return App::instance()->request()->get('searchterm'); return App::instance()->request()->get('searchterm');
} }
] ]

View file

@ -1,6 +1,8 @@
<?php <?php
use Kirby\Cms\Blueprint; use Kirby\Cms\Blueprint;
use Kirby\Cms\Page;
use Kirby\Cms\Site;
use Kirby\Exception\InvalidArgumentException; use Kirby\Exception\InvalidArgumentException;
use Kirby\Toolkit\A; use Kirby\Toolkit\A;
use Kirby\Toolkit\I18n; use Kirby\Toolkit\I18n;
@ -53,8 +55,8 @@ return [
$parent = $this->parentModel(); $parent = $this->parentModel();
if ( if (
is_a($parent, 'Kirby\Cms\Site') === false && $parent instanceof Site === false &&
is_a($parent, 'Kirby\Cms\Page') === false $parent instanceof Page === false
) { ) {
throw new InvalidArgumentException('The parent is invalid. You must choose the site or a page as parent.'); throw new InvalidArgumentException('The parent is invalid. You must choose the site or a page as parent.');
} }
@ -62,22 +64,13 @@ return [
return $parent; return $parent;
}, },
'pages' => function () { 'pages' => function () {
switch ($this->status) { $pages = match ($this->status) {
case 'draft': 'draft' => $this->parent->drafts(),
$pages = $this->parent->drafts(); 'listed' => $this->parent->children()->listed(),
break; 'published' => $this->parent->children(),
case 'listed': 'unlisted' => $this->parent->children()->unlisted(),
$pages = $this->parent->children()->listed(); default => $this->parent->childrenAndDrafts()
break; };
case 'published':
$pages = $this->parent->children();
break;
case 'unlisted':
$pages = $this->parent->children()->unlisted();
break;
default:
$pages = $this->parent->childrenAndDrafts();
}
// filters pages that are protected and not in the templates list // filters pages that are protected and not in the templates list
// internal `filter()` method used instead of foreach loop that previously included `unset()` // internal `filter()` method used instead of foreach loop that previously included `unset()`
@ -228,7 +221,7 @@ return [
'name' => basename($props['name']), 'name' => basename($props['name']),
'title' => $props['title'], 'title' => $props['title'],
]; ];
} catch (Throwable $e) { } catch (Throwable) {
$blueprints[] = [ $blueprints[] = [
'name' => basename($template), 'name' => basename($template),
'title' => ucfirst($template), 'title' => ucfirst($template),

View file

@ -47,10 +47,12 @@ return [
continue; continue;
} }
$info = $report['info'] ?? null;
$reports[] = [ $reports[] = [
'label' => I18n::translate($report['label'], $report['label']), 'label' => I18n::translate($report['label'], $report['label']),
'value' => $value($report['value'] ?? null), 'value' => $value($report['value'] ?? null),
'info' => $value($report['info'] ?? null), 'info' => $value(I18n::translate($info, $info)),
'link' => $value($report['link'] ?? null), 'link' => $value($report['link'] ?? null),
'theme' => $value($report['theme'] ?? null) 'theme' => $value($report['theme'] ?? null)
]; ];

View file

@ -2,6 +2,7 @@
/** /**
* Constants * Constants
* @deprecated 3.8.0 Use `/` instead
*/ */
define('DS', '/'); define('DS', '/');

View file

@ -3,6 +3,7 @@
use Kirby\Cms\Html; use Kirby\Cms\Html;
use Kirby\Cms\Url; use Kirby\Cms\Url;
use Kirby\Toolkit\Str; use Kirby\Toolkit\Str;
use Kirby\Uuid\Uuid;
/** /**
* Default KirbyTags definition * Default KirbyTags definition
@ -117,11 +118,8 @@ return [
return $img; return $img;
} }
if ($link = $tag->file($tag->link)) { $link = $tag->file($tag->link)?->url();
$link = $link->url(); $link ??= $tag->link === 'self' ? $tag->src : $tag->link;
} else {
$link = $tag->link === 'self' ? $tag->src : $tag->link;
}
return Html::a($link, [$img], [ return Html::a($link, [$img], [
'rel' => $tag->rel, 'rel' => $tag->rel,
@ -173,6 +171,15 @@ return [
$tag->value = Url::to($tag->value, $tag->lang); $tag->value = Url::to($tag->value, $tag->lang);
} }
// if value is a UUID, resolve to page/file model
// and use the URL as value
if (
Uuid::is($tag->value, 'page') === true ||
Uuid::is($tag->value, 'file') === true
) {
$tag->value = Uuid::for($tag->value)->model()->url();
}
return Html::a($tag->value, $tag->text, [ return Html::a($tag->value, $tag->text, [
'rel' => $tag->rel, 'rel' => $tag->rel,
'class' => $tag->class, 'class' => $tag->class,

View file

@ -465,7 +465,7 @@ class ParsedownExtra extends Parsedown
), ),
); );
uasort($this->DefinitionData['Footnote'], 'self::sortFootnotes'); uasort($this->DefinitionData['Footnote'], [$this,'sortFootnotes']);
foreach ($this->DefinitionData['Footnote'] as $definitionId => $DefinitionData) { foreach ($this->DefinitionData['Footnote'] as $definitionId => $DefinitionData) {
if (! isset($DefinitionData['number'])) { if (! isset($DefinitionData['number'])) {

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "You must not add more than one block", "error.blocks.max.singular": "You must not add more than one block",
"error.blocks.min.plural": "You must add at least {min} blocks", "error.blocks.min.plural": "You must add at least {min} blocks",
"error.blocks.min.singular": "You must add at least one block", "error.blocks.min.singular": "You must add at least one block",
"error.blocks.validation": "There's an error in block {index}", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "Email шаблонът \"{name}\" не може да бъде открит", "error.email.preset.notFound": "Email шаблонът \"{name}\" не може да бъде открит",
@ -107,13 +107,15 @@
"error.language.name": "Please enter a valid name for the language", "error.language.name": "Please enter a valid name for the language",
"error.language.notFound": "The language could not be found", "error.language.notFound": "The language could not be found",
"error.layout.validation.block": "There's an error in block {blockIndex} in layout {layoutIndex}", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "There's an error in layout {index} settings", "error.layout.validation.settings": "There's an error in layout {index} settings",
"error.license.format": "Please enter a valid license key", "error.license.format": "Please enter a valid license key",
"error.license.email": "Моля въведете валиден email адрес", "error.license.email": "Моля въведете валиден email адрес",
"error.license.verification": "The license could not be verified", "error.license.verification": "The license could not be verified",
"error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "The Panel is currently offline", "error.offline": "The Panel is currently offline",
"error.page.changeSlug.permission": "Не можете да смените URL на \"{slug}\"", "error.page.changeSlug.permission": "Не можете да смените URL на \"{slug}\"",
@ -282,9 +284,13 @@
"field.layout.empty": "No rows yet", "field.layout.empty": "No rows yet",
"field.layout.select": "Select a layout", "field.layout.select": "Select a layout",
"field.object.empty": "No information yet",
"field.pages.empty": "Все още не са избрани страници", "field.pages.empty": "Все още не са избрани страници",
"field.structure.delete.confirm": "Сигурни ли сте, че искате да изтриете това вписване?", "field.structure.delete.confirm": "Сигурни ли сте, че искате да изтриете това вписване?",
"field.structure.empty": "Все още няма статии", "field.structure.empty": "Все още няма статии",
"field.users.empty": "Все още не са избрани потребители", "field.users.empty": "Все още не са избрани потребители",
"file.blueprint": "This file has no blueprint yet. You can define the setup in <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "This file has no blueprint yet. You can define the setup in <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -448,6 +454,7 @@
"paste": "Paste", "paste": "Paste",
"paste.after": "Paste after", "paste.after": "Paste after",
"pixel": "Пиксел", "pixel": "Пиксел",
"plugin": "Plugin",
"plugins": "Plugins", "plugins": "Plugins",
"prev": "Previous", "prev": "Previous",
"preview": "Preview", "preview": "Preview",
@ -487,11 +494,24 @@
"stats.empty": "No reports", "stats.empty": "No reports",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "The content folder seems to be exposed",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.debug": "Debugging must be turned off in production",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.git": "The .git folder seems to be exposed",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.https": "We recommend HTTPS for all your sites",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.kirby": "The kirby folder seems to be exposed",
"system.issues.site": "The site folder seems to be exposed", "system.issues.site": "The site folder seems to be exposed",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Could not check for updates",
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
"system.updateStatus.security-update": "Free security update { version } available",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "Unreleased version",
"system.updateStatus.up-to-date": "Up to date",
"system.updateStatus.update": "Free update { version } available",
"system.updateStatus.upgrade": "Upgrade { version } available",
"title": "Заглавие", "title": "Заглавие",
"template": "Образец", "template": "Образец",
@ -558,6 +578,9 @@
"users": "Потребители", "users": "Потребители",
"version": "\u0412\u0435\u0440\u0441\u0438\u044f \u043d\u0430 Kirby", "version": "\u0412\u0435\u0440\u0441\u0438\u044f \u043d\u0430 Kirby",
"version.current": "Current version",
"version.latest": "Latest version",
"versionInformation": "Version information",
"view.account": "\u0412\u0430\u0448\u0438\u044f \u0430\u043a\u0430\u0443\u043d\u0442", "view.account": "\u0412\u0430\u0448\u0438\u044f \u0430\u043a\u0430\u0443\u043d\u0442",
"view.installation": "\u0418\u043d\u0441\u0442\u0430\u043b\u0430\u0446\u0438\u044f", "view.installation": "\u0418\u043d\u0441\u0442\u0430\u043b\u0430\u0446\u0438\u044f",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "You must not add more than one block", "error.blocks.max.singular": "You must not add more than one block",
"error.blocks.min.plural": "You must add at least {min} blocks", "error.blocks.min.plural": "You must add at least {min} blocks",
"error.blocks.min.singular": "You must add at least one block", "error.blocks.min.singular": "You must add at least one block",
"error.blocks.validation": "There's an error in block {index}", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "No es pot trobar la configuració de correu electrònic \"{name}\"", "error.email.preset.notFound": "No es pot trobar la configuració de correu electrònic \"{name}\"",
@ -107,13 +107,15 @@
"error.language.name": "Introdueix un nom vàlid per a l'idioma", "error.language.name": "Introdueix un nom vàlid per a l'idioma",
"error.language.notFound": "The language could not be found", "error.language.notFound": "The language could not be found",
"error.layout.validation.block": "There's an error in block {blockIndex} in layout {layoutIndex}", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "There's an error in layout {index} settings", "error.layout.validation.settings": "There's an error in layout {index} settings",
"error.license.format": "Introduïu una clau de llicència vàlida", "error.license.format": "Introduïu una clau de llicència vàlida",
"error.license.email": "Si us plau, introdueix una adreça de correu electrònic vàlida", "error.license.email": "Si us plau, introdueix una adreça de correu electrònic vàlida",
"error.license.verification": "No sha pogut verificar la llicència", "error.license.verification": "No sha pogut verificar la llicència",
"error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "The Panel is currently offline", "error.offline": "The Panel is currently offline",
"error.page.changeSlug.permission": "No teniu permís per canviar l'apèndix d'URL per a \"{slug}\"", "error.page.changeSlug.permission": "No teniu permís per canviar l'apèndix d'URL per a \"{slug}\"",
@ -282,9 +284,13 @@
"field.layout.empty": "No rows yet", "field.layout.empty": "No rows yet",
"field.layout.select": "Select a layout", "field.layout.select": "Select a layout",
"field.object.empty": "No information yet",
"field.pages.empty": "Encara no s'ha seleccionat cap pàgina", "field.pages.empty": "Encara no s'ha seleccionat cap pàgina",
"field.structure.delete.confirm": "Segur que voleu eliminar aquesta fila?", "field.structure.delete.confirm": "Segur que voleu eliminar aquesta fila?",
"field.structure.empty": "Encara no hi ha entrades.", "field.structure.empty": "Encara no hi ha entrades.",
"field.users.empty": "Encara no s'ha seleccionat cap usuari", "field.users.empty": "Encara no s'ha seleccionat cap usuari",
"file.blueprint": "This file has no blueprint yet. You can define the setup in <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "This file has no blueprint yet. You can define the setup in <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -448,6 +454,7 @@
"paste": "Paste", "paste": "Paste",
"paste.after": "Paste after", "paste.after": "Paste after",
"pixel": "Pixel", "pixel": "Pixel",
"plugin": "Plugin",
"plugins": "Plugins", "plugins": "Plugins",
"prev": "Anterior", "prev": "Anterior",
"preview": "Preview", "preview": "Preview",
@ -487,11 +494,24 @@
"stats.empty": "No reports", "stats.empty": "No reports",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "The content folder seems to be exposed",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.debug": "Debugging must be turned off in production",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.git": "The .git folder seems to be exposed",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.https": "We recommend HTTPS for all your sites",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.kirby": "The kirby folder seems to be exposed",
"system.issues.site": "The site folder seems to be exposed", "system.issues.site": "The site folder seems to be exposed",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Could not check for updates",
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
"system.updateStatus.security-update": "Free security update { version } available",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "Unreleased version",
"system.updateStatus.up-to-date": "Up to date",
"system.updateStatus.update": "Free update { version } available",
"system.updateStatus.upgrade": "Upgrade { version } available",
"title": "Títol", "title": "Títol",
"template": "Plantilla", "template": "Plantilla",
@ -558,6 +578,9 @@
"users": "Usuaris", "users": "Usuaris",
"version": "Versi\u00f3 de Kirby", "version": "Versi\u00f3 de Kirby",
"version.current": "Current version",
"version.latest": "Latest version",
"versionInformation": "Version information",
"view.account": "La teva compta", "view.account": "La teva compta",
"view.installation": "Instal·lació", "view.installation": "Instal·lació",

View file

@ -49,8 +49,8 @@
"email": "Email", "email": "Email",
"email.placeholder": "mail@example.com", "email.placeholder": "mail@example.com",
"entries": "Entries", "entries": "Záznamy",
"entry": "Entry", "entry": "Záznam",
"environment": "Prostředí", "environment": "Prostředí",
@ -70,7 +70,7 @@
"error.blocks.max.singular": "Nelze přidat více než jeden blok", "error.blocks.max.singular": "Nelze přidat více než jeden blok",
"error.blocks.min.plural": "Musíte přidat alespoň {min} bloků", "error.blocks.min.plural": "Musíte přidat alespoň {min} bloků",
"error.blocks.min.singular": "Musíte přidat alespoň jeden blok", "error.blocks.min.singular": "Musíte přidat alespoň jeden blok",
"error.blocks.validation": "Chyba v bloku {index}", "error.blocks.validation": "V poli \"{field}\" v bloku {index} je při použití \"{fieldset}\" typu chyba",
"error.email.preset.notFound": "Nelze nalézt emailové přednastavení \"{name}\"", "error.email.preset.notFound": "Nelze nalézt emailové přednastavení \"{name}\"",
@ -107,13 +107,15 @@
"error.language.name": "Zadejte prosím platné jméno jazyka", "error.language.name": "Zadejte prosím platné jméno jazyka",
"error.language.notFound": "Jazyk nebyl nalezen", "error.language.notFound": "Jazyk nebyl nalezen",
"error.layout.validation.block": "Chyba v bloku {blockIndex} v rozvržení {layoutIndex}", "error.layout.validation.block": "V rozvržení {layoutIndex} je v poli \"{field}\" v bloku {blockIndex} při použití \"{fieldset}\" typu chyba",
"error.layout.validation.settings": "Chyba v nastavení rozvržení {index}", "error.layout.validation.settings": "Chyba v nastavení rozvržení {index}",
"error.license.format": "Zadejte prosím platné licenční číslo", "error.license.format": "Zadejte prosím platné licenční číslo",
"error.license.email": "Zadejte prosím platnou emailovou adresu", "error.license.email": "Zadejte prosím platnou emailovou adresu",
"error.license.verification": "Licenci nelze ověřit", "error.license.verification": "Licenci nelze ověřit",
"error.object.validation": "V poli \"{label}\" je chyba:\n{message}",
"error.offline": "Panel je v současnosti off-line", "error.offline": "Panel je v současnosti off-line",
"error.page.changeSlug.permission": "Nem\u016f\u017eete zm\u011bnit URL t\u00e9to str\u00e1nky", "error.page.changeSlug.permission": "Nem\u016f\u017eete zm\u011bnit URL t\u00e9to str\u00e1nky",
@ -282,9 +284,13 @@
"field.layout.empty": "Zatím žádné řádky", "field.layout.empty": "Zatím žádné řádky",
"field.layout.select": "Vyberte rozložení", "field.layout.select": "Vyberte rozložení",
"field.object.empty": "Zatím žádná informace",
"field.pages.empty": "Nebyly zatím vybrány žádné stránky", "field.pages.empty": "Nebyly zatím vybrány žádné stránky",
"field.structure.delete.confirm": "Opravdu chcete smazat tento z\u00e1znam?", "field.structure.delete.confirm": "Opravdu chcete smazat tento z\u00e1znam?",
"field.structure.empty": "Zat\u00edm nejsou \u017e\u00e1dn\u00e9 z\u00e1znamy.", "field.structure.empty": "Zat\u00edm nejsou \u017e\u00e1dn\u00e9 z\u00e1znamy.",
"field.users.empty": "Nebyli zatím vybráni žádní uživatelé", "field.users.empty": "Nebyli zatím vybráni žádní uživatelé",
"file.blueprint": "Tento typ souboru nemá blueprint. Blueprint můžete definovat v <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "Tento typ souboru nemá blueprint. Blueprint můžete definovat v <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -297,7 +303,7 @@
"hide": "Skrýt", "hide": "Skrýt",
"hour": "Hodina", "hour": "Hodina",
"import": "Import", "import": "Import",
"info": "Info", "info": "Informace",
"insert": "Vlo\u017eit", "insert": "Vlo\u017eit",
"insert.after": "Vložit za", "insert.after": "Vložit za",
"insert.before": "Vložit před", "insert.before": "Vložit před",
@ -340,12 +346,12 @@
"license": "Kirby licence", "license": "Kirby licence",
"license.buy": "Zakoupit licenci", "license.buy": "Zakoupit licenci",
"license.register": "Registrovat", "license.register": "Registrovat",
"license.manage": "Manage your licenses", "license.manage": "Spravovat licence",
"license.register.help": "Licenční kód jste po zakoupení obdrželi na email. Vložte prosím kód a zaregistrujte Vaší kopii.", "license.register.help": "Licenční kód jste po zakoupení obdrželi na email. Vložte prosím kód a zaregistrujte Vaší kopii.",
"license.register.label": "Zadejte prosím licenční kód", "license.register.label": "Zadejte prosím licenční kód",
"license.register.success": "Děkujeme Vám za podporu Kirby", "license.register.success": "Děkujeme Vám za podporu Kirby",
"license.unregistered": "Toto je neregistrovaná kopie Kirby", "license.unregistered": "Toto je neregistrovaná kopie Kirby",
"license.unregistered.label": "Unregistered", "license.unregistered.label": "Neregistrovaný",
"link": "Odkaz", "link": "Odkaz",
"link.text": "Text odkazu", "link.text": "Text odkazu",
@ -360,7 +366,7 @@
"lock.unlock": "Odemknout", "lock.unlock": "Odemknout",
"lock.isUnlocked": "Vaše neuložené změny byly přepsány jiným uživatelem. Můžeze si své úpravy stáhnout a zapracovat je ručně.", "lock.isUnlocked": "Vaše neuložené změny byly přepsány jiným uživatelem. Můžeze si své úpravy stáhnout a zapracovat je ručně.",
"login": "P\u0159ihl\u00e1sit se", "login": "Přihlásit se",
"login.code.label.login": "Kód pro přihlášení", "login.code.label.login": "Kód pro přihlášení",
"login.code.label.password-reset": "Kód pro resetování hesla", "login.code.label.password-reset": "Kód pro resetování hesla",
"login.code.placeholder.email": "000 000", "login.code.placeholder.email": "000 000",
@ -448,6 +454,7 @@
"paste": "Vložit", "paste": "Vložit",
"paste.after": "Vložit za", "paste.after": "Vložit za",
"pixel": "Pixel", "pixel": "Pixel",
"plugin": "Plugin",
"plugins": "Doplňky", "plugins": "Doplňky",
"prev": "Předchozí", "prev": "Předchozí",
"preview": "Náhled", "preview": "Náhled",
@ -475,7 +482,7 @@
"section.required": "Sekce musí být vyplněna", "section.required": "Sekce musí být vyplněna",
"security": "Security", "security": "Zabezpečení",
"select": "Vybrat", "select": "Vybrat",
"server": "Server", "server": "Server",
"settings": "Nastavení", "settings": "Nastavení",
@ -485,13 +492,26 @@
"slug": "P\u0159\u00edpona URL", "slug": "P\u0159\u00edpona URL",
"sort": "Řadit", "sort": "Řadit",
"stats.empty": "No reports", "stats.empty": "Žádná hlášení",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "Složka content je zřejmě přístupná zvenčí",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.debug": "Debug mode musí být v produkci vypnutý",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.git": "Složka .git je zřejmě přístupná zvenčí",
"system.issues.site": "The site folder seems to be exposed", "system.issues.https": "Při všechny stránky doporučujeme používat protokol HTTPS",
"system.issues.kirby": "Složka kirby je zřejmě přístupná zvenčí",
"system.issues.site": "Složka site je zřejmě přístupná zvenčí",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Could not check for updates",
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
"system.updateStatus.security-update": "Free security update { version } available",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "Unreleased version",
"system.updateStatus.up-to-date": "Up to date",
"system.updateStatus.update": "Free update { version } available",
"system.updateStatus.upgrade": "Upgrade { version } available",
"title": "Název", "title": "Název",
"template": "\u0160ablona", "template": "\u0160ablona",
@ -558,6 +578,9 @@
"users": "Uživatelé", "users": "Uživatelé",
"version": "Verze Kirby", "version": "Verze Kirby",
"version.current": "Current version",
"version.latest": "Latest version",
"versionInformation": "Version information",
"view.account": "V\u00e1\u0161 \u00fa\u010det", "view.account": "V\u00e1\u0161 \u00fa\u010det",
"view.installation": "Instalace", "view.installation": "Instalace",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "Du må ikke tilføje mere end een blok", "error.blocks.max.singular": "Du må ikke tilføje mere end een blok",
"error.blocks.min.plural": "Du skal tilføje minimum {min} blokke", "error.blocks.min.plural": "Du skal tilføje minimum {min} blokke",
"error.blocks.min.singular": "Du skal tilføje minimum een blok", "error.blocks.min.singular": "Du skal tilføje minimum een blok",
"error.blocks.validation": "Der er fejl i blok {index}", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "Email preset \"{name}\" findes ikke", "error.email.preset.notFound": "Email preset \"{name}\" findes ikke",
@ -107,13 +107,15 @@
"error.language.name": "Indtast venligst et gyldigt navn for sproget", "error.language.name": "Indtast venligst et gyldigt navn for sproget",
"error.language.notFound": "Sproget fandtes ikke", "error.language.notFound": "Sproget fandtes ikke",
"error.layout.validation.block": "Der er fejl i blok {blockIndex} i layout {layoutIndex}", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "Der er fejl i layout {index} indstillinger", "error.layout.validation.settings": "Der er fejl i layout {index} indstillinger",
"error.license.format": "Indtast venligst en gyldig licensnøgle", "error.license.format": "Indtast venligst en gyldig licensnøgle",
"error.license.email": "Indtast venligst en gyldig email adresse", "error.license.email": "Indtast venligst en gyldig email adresse",
"error.license.verification": "Licensen kunne ikke verificeres", "error.license.verification": "Licensen kunne ikke verificeres",
"error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "Panelet er i øjeblikket offline", "error.offline": "Panelet er i øjeblikket offline",
"error.page.changeSlug.permission": "Du kan ikke ændre URL-endelse for \"{slug}\"", "error.page.changeSlug.permission": "Du kan ikke ændre URL-endelse for \"{slug}\"",
@ -282,9 +284,13 @@
"field.layout.empty": "Ingen rækker endnu", "field.layout.empty": "Ingen rækker endnu",
"field.layout.select": "Vælg et layout", "field.layout.select": "Vælg et layout",
"field.object.empty": "No information yet",
"field.pages.empty": "Ingen sider valgt endnu", "field.pages.empty": "Ingen sider valgt endnu",
"field.structure.delete.confirm": "\u00d8nsker du virkelig at slette denne indtastning?", "field.structure.delete.confirm": "\u00d8nsker du virkelig at slette denne indtastning?",
"field.structure.empty": "Ingen indtastninger endnu.", "field.structure.empty": "Ingen indtastninger endnu.",
"field.users.empty": "Ingen brugere er valgt", "field.users.empty": "Ingen brugere er valgt",
"file.blueprint": "Denne fil har intet blueprint endnu. Du kan definere opsætningen i <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "Denne fil har intet blueprint endnu. Du kan definere opsætningen i <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -448,6 +454,7 @@
"paste": "Indsæt", "paste": "Indsæt",
"paste.after": "Indsæt efter", "paste.after": "Indsæt efter",
"pixel": "Pixel", "pixel": "Pixel",
"plugin": "Plugin",
"plugins": "Plugins", "plugins": "Plugins",
"prev": "Forrige", "prev": "Forrige",
"preview": "Forhåndsvisning", "preview": "Forhåndsvisning",
@ -487,11 +494,24 @@
"stats.empty": "No reports", "stats.empty": "No reports",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "The content folder seems to be exposed",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.debug": "Debugging must be turned off in production",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.git": "The .git folder seems to be exposed",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.https": "We recommend HTTPS for all your sites",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.kirby": "The kirby folder seems to be exposed",
"system.issues.site": "The site folder seems to be exposed", "system.issues.site": "The site folder seems to be exposed",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Could not check for updates",
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
"system.updateStatus.security-update": "Free security update { version } available",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "Unreleased version",
"system.updateStatus.up-to-date": "Up to date",
"system.updateStatus.update": "Free update { version } available",
"system.updateStatus.upgrade": "Upgrade { version } available",
"title": "Titel", "title": "Titel",
"template": "Skabelon", "template": "Skabelon",
@ -558,6 +578,9 @@
"users": "Brugere", "users": "Brugere",
"version": "Kirby version", "version": "Kirby version",
"version.current": "Current version",
"version.latest": "Latest version",
"versionInformation": "Version information",
"view.account": "Din konto", "view.account": "Din konto",
"view.installation": "Installation", "view.installation": "Installation",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "Bitte füge nicht mehr als einen Block hinzu", "error.blocks.max.singular": "Bitte füge nicht mehr als einen Block hinzu",
"error.blocks.min.plural": "Bitte füge mindestens {min} Blöcke hinzu", "error.blocks.min.plural": "Bitte füge mindestens {min} Blöcke hinzu",
"error.blocks.min.singular": "Bitte füge mindestens einen Block hinzu", "error.blocks.min.singular": "Bitte füge mindestens einen Block hinzu",
"error.blocks.validation": "Fehler in Block {index}", "error.blocks.validation": "Fehler im \"{field}\" Feld in Block {index} mit dem Block Typ \"{fieldset}\"",
"error.email.preset.notFound": "Die E-Mailvorlage \"{name}\" wurde nicht gefunden", "error.email.preset.notFound": "Die E-Mailvorlage \"{name}\" wurde nicht gefunden",
@ -107,13 +107,15 @@
"error.language.name": "Bitte gib einen gültigen Namen für die Sprache an", "error.language.name": "Bitte gib einen gültigen Namen für die Sprache an",
"error.language.notFound": "Die Sprache konnte nicht gefunden werden", "error.language.notFound": "Die Sprache konnte nicht gefunden werden",
"error.layout.validation.block": "Fehler in Block {blockIndex} in Layout {layoutIndex}", "error.layout.validation.block": "Fehler im \"{field}\" Feld in Block {blockIndex} mit dem Block Typ \"{fieldset}\" in Layout {layoutIndex}",
"error.layout.validation.settings": "Fehler in den Einstellungen von Layout {index}", "error.layout.validation.settings": "Fehler in den Einstellungen von Layout {index}",
"error.license.format": "Bitte gib einen gültigen Lizenzschlüssel ein", "error.license.format": "Bitte gib einen gültigen Lizenzschlüssel ein",
"error.license.email": "Bitte gib eine gültige E-Mailadresse an", "error.license.email": "Bitte gib eine gültige E-Mailadresse an",
"error.license.verification": "Die Lizenz konnte nicht verifiziert werden", "error.license.verification": "Die Lizenz konnte nicht verifiziert werden",
"error.object.validation": "Fehler im \"{label}\" Feld:\n{message}",
"error.offline": "Das Panel ist zur Zeit offline", "error.offline": "Das Panel ist zur Zeit offline",
"error.page.changeSlug.permission": "Du darfst die URL der Seite \"{slug}\" nicht ändern", "error.page.changeSlug.permission": "Du darfst die URL der Seite \"{slug}\" nicht ändern",
@ -282,9 +284,13 @@
"field.layout.empty": "Keine Layouts", "field.layout.empty": "Keine Layouts",
"field.layout.select": "Layout auswählen", "field.layout.select": "Layout auswählen",
"field.object.empty": "Noch keine Information",
"field.pages.empty": "Keine Seiten ausgewählt", "field.pages.empty": "Keine Seiten ausgewählt",
"field.structure.delete.confirm": "Willst du diesen Eintrag wirklich l\u00f6schen?", "field.structure.delete.confirm": "Willst du diesen Eintrag wirklich l\u00f6schen?",
"field.structure.empty": "Es bestehen keine Eintr\u00e4ge.", "field.structure.empty": "Es bestehen keine Eintr\u00e4ge.",
"field.users.empty": "Keine Accounts ausgewählt", "field.users.empty": "Keine Accounts ausgewählt",
"file.blueprint": "Du kannst zusätzliche Felder und Bereiche für diese Datei in <strong>/site/blueprints/files/{blueprint}.yml</strong> anlegen", "file.blueprint": "Du kannst zusätzliche Felder und Bereiche für diese Datei in <strong>/site/blueprints/files/{blueprint}.yml</strong> anlegen",
@ -448,6 +454,7 @@
"paste": "Einfügen", "paste": "Einfügen",
"paste.after": "Danach einfügen", "paste.after": "Danach einfügen",
"pixel": "Pixel", "pixel": "Pixel",
"plugin": "Plugin",
"plugins": "Plugins", "plugins": "Plugins",
"prev": "Vorheriger Eintrag", "prev": "Vorheriger Eintrag",
"preview": "Vorschau", "preview": "Vorschau",
@ -487,11 +494,24 @@
"stats.empty": "Keine Daten", "stats.empty": "Keine Daten",
"system.issues.content": "Der content Ordner scheint öffentlich zugänglich zu sein", "system.issues.content": "Der content Ordner scheint öffentlich zugänglich zu sein",
"system.issues.eol.kirby": "Deine Kirby Installation ist veraltet und erhält keine weiteren Sicherheitsupdates",
"system.issues.eol.plugin": "Deine Version des { plugin } Plugins ist veraltet und erhält keine weiteren Sicherheitsupdates",
"system.issues.debug": "Debugging muss im öffentlichen Betrieb ausgeschaltet sein", "system.issues.debug": "Debugging muss im öffentlichen Betrieb ausgeschaltet sein",
"system.issues.git": "Der .git Ordner scheint öffentlich zugänglich zu sein", "system.issues.git": "Der .git Ordner scheint öffentlich zugänglich zu sein",
"system.issues.https": "Wir empfehlen HTTPS für alle deine Seiten", "system.issues.https": "Wir empfehlen HTTPS für alle deine Seiten",
"system.issues.kirby": "Der kirby Ordner scheint öffentlich zugänglich zu sein", "system.issues.kirby": "Der kirby Ordner scheint öffentlich zugänglich zu sein",
"system.issues.site": "Der site Ordner scheint öffentlich zugänglich zu sein", "system.issues.site": "Der site Ordner scheint öffentlich zugänglich zu sein",
"system.issues.vulnerability.kirby": "Deine Installation könnte von folgender Sicherheitslücke betroffen sein ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Deine Installation könnte von folgender Sicherheitslücke im { plugin } Plugin betroffen sein ({ severity } severity): { description }",
"system.updateStatus": "Update Status",
"system.updateStatus.error": "Update Check nicht möglich",
"system.updateStatus.not-vulnerable": "Keine bekannten Sicherheitslücken",
"system.updateStatus.security-update": "Kostenloses Sicherheitsupdate { version } verfügbar",
"system.updateStatus.security-upgrade": "Upgrade { version } mit Sicherheitsverbesserungen verfügbar ",
"system.updateStatus.unreleased": "Unveröffentlichte Version",
"system.updateStatus.up-to-date": "Aktuell",
"system.updateStatus.update": "Kostenloses Update { version } verfügbar",
"system.updateStatus.upgrade": "Upgrade { version } verfügbar",
"title": "Titel", "title": "Titel",
"template": "Vorlage", "template": "Vorlage",
@ -558,6 +578,9 @@
"users": "Accounts", "users": "Accounts",
"version": "Version", "version": "Version",
"version.current": "Aktuelle Version",
"version.latest": "Neueste Version",
"versionInformation": "Informationen zur Version",
"view.account": "Dein Account", "view.account": "Dein Account",
"view.installation": "Installation", "view.installation": "Installation",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "You must not add more than one block", "error.blocks.max.singular": "You must not add more than one block",
"error.blocks.min.plural": "You must add at least {min} blocks", "error.blocks.min.plural": "You must add at least {min} blocks",
"error.blocks.min.singular": "You must add at least one block", "error.blocks.min.singular": "You must add at least one block",
"error.blocks.validation": "There's an error in block {index}", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "Δεν είναι δυνατή η εύρεση της προεπιλογής διεύθινσης ηλεκτρονικού ταχυδρομείου \"{name}\"", "error.email.preset.notFound": "Δεν είναι δυνατή η εύρεση της προεπιλογής διεύθινσης ηλεκτρονικού ταχυδρομείου \"{name}\"",
@ -107,13 +107,15 @@
"error.language.name": "Please enter a valid name for the language", "error.language.name": "Please enter a valid name for the language",
"error.language.notFound": "The language could not be found", "error.language.notFound": "The language could not be found",
"error.layout.validation.block": "There's an error in block {blockIndex} in layout {layoutIndex}", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "There's an error in layout {index} settings", "error.layout.validation.settings": "There's an error in layout {index} settings",
"error.license.format": "Please enter a valid license key", "error.license.format": "Please enter a valid license key",
"error.license.email": "Παρακαλώ εισάγετε μια έγκυρη διεύθυνση ηλεκτρονικού ταχυδρομείου", "error.license.email": "Παρακαλώ εισάγετε μια έγκυρη διεύθυνση ηλεκτρονικού ταχυδρομείου",
"error.license.verification": "The license could not be verified", "error.license.verification": "The license could not be verified",
"error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "The Panel is currently offline", "error.offline": "The Panel is currently offline",
"error.page.changeSlug.permission": "Δεν επιτρέπεται να αλλάξετε το URL της σελίδας \"{slug}\"", "error.page.changeSlug.permission": "Δεν επιτρέπεται να αλλάξετε το URL της σελίδας \"{slug}\"",
@ -282,9 +284,13 @@
"field.layout.empty": "No rows yet", "field.layout.empty": "No rows yet",
"field.layout.select": "Select a layout", "field.layout.select": "Select a layout",
"field.object.empty": "No information yet",
"field.pages.empty": "Δεν έχουν επιλεγεί ακόμη σελίδες", "field.pages.empty": "Δεν έχουν επιλεγεί ακόμη σελίδες",
"field.structure.delete.confirm": "\u0395\u03af\u03c3\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03bf\u03c2 \u03cc\u03c4\u03b9 \u03b8\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03c4\u03b5 \u03b1\u03c5\u03c4\u03ae\u03bd \u03c4\u03b7\u03bd \u03ba\u03b1\u03c4\u03b1\u03c7\u03ce\u03c1\u03b9\u03c3\u03b7;", "field.structure.delete.confirm": "\u0395\u03af\u03c3\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03bf\u03c2 \u03cc\u03c4\u03b9 \u03b8\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03c4\u03b5 \u03b1\u03c5\u03c4\u03ae\u03bd \u03c4\u03b7\u03bd \u03ba\u03b1\u03c4\u03b1\u03c7\u03ce\u03c1\u03b9\u03c3\u03b7;",
"field.structure.empty": "\u0394\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03bf\u03c5\u03bd \u03b1\u03ba\u03cc\u03bc\u03b7 \u03ba\u03b1\u03c4\u03b1\u03c7\u03c9\u03c1\u03af\u03c3\u03b5\u03b9\u03c2.", "field.structure.empty": "\u0394\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03bf\u03c5\u03bd \u03b1\u03ba\u03cc\u03bc\u03b7 \u03ba\u03b1\u03c4\u03b1\u03c7\u03c9\u03c1\u03af\u03c3\u03b5\u03b9\u03c2.",
"field.users.empty": "Δεν έχουν επιλεγεί ακόμη χρήστες", "field.users.empty": "Δεν έχουν επιλεγεί ακόμη χρήστες",
"file.blueprint": "This file has no blueprint yet. You can define the setup in <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "This file has no blueprint yet. You can define the setup in <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -448,6 +454,7 @@
"paste": "Paste", "paste": "Paste",
"paste.after": "Paste after", "paste.after": "Paste after",
"pixel": "Εικονοστοιχέιο", "pixel": "Εικονοστοιχέιο",
"plugin": "Plugin",
"plugins": "Plugins", "plugins": "Plugins",
"prev": "Προηγούμενο", "prev": "Προηγούμενο",
"preview": "Preview", "preview": "Preview",
@ -487,11 +494,24 @@
"stats.empty": "No reports", "stats.empty": "No reports",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "The content folder seems to be exposed",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.debug": "Debugging must be turned off in production",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.git": "The .git folder seems to be exposed",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.https": "We recommend HTTPS for all your sites",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.kirby": "The kirby folder seems to be exposed",
"system.issues.site": "The site folder seems to be exposed", "system.issues.site": "The site folder seems to be exposed",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Could not check for updates",
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
"system.updateStatus.security-update": "Free security update { version } available",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "Unreleased version",
"system.updateStatus.up-to-date": "Up to date",
"system.updateStatus.update": "Free update { version } available",
"system.updateStatus.upgrade": "Upgrade { version } available",
"title": "Τίτλος", "title": "Τίτλος",
"template": "\u03a0\u03c1\u03cc\u03c4\u03c5\u03c0\u03bf", "template": "\u03a0\u03c1\u03cc\u03c4\u03c5\u03c0\u03bf",
@ -558,6 +578,9 @@
"users": "Χρήστες", "users": "Χρήστες",
"version": "\u0388\u03ba\u03b4\u03bf\u03c3\u03b7 Kirby", "version": "\u0388\u03ba\u03b4\u03bf\u03c3\u03b7 Kirby",
"version.current": "Current version",
"version.latest": "Latest version",
"versionInformation": "Version information",
"view.account": "\u039f \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc\u03c2 \u03c3\u03b1\u03c2", "view.account": "\u039f \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc\u03c2 \u03c3\u03b1\u03c2",
"view.installation": "\u0395\u03b3\u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7", "view.installation": "\u0395\u03b3\u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "You must not add more than one block", "error.blocks.max.singular": "You must not add more than one block",
"error.blocks.min.plural": "You must add at least {min} blocks", "error.blocks.min.plural": "You must add at least {min} blocks",
"error.blocks.min.singular": "You must add at least one block", "error.blocks.min.singular": "You must add at least one block",
"error.blocks.validation": "There's an error in block {index}", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "The email preset \"{name}\" cannot be found", "error.email.preset.notFound": "The email preset \"{name}\" cannot be found",
@ -107,13 +107,15 @@
"error.language.name": "Please enter a valid name for the language", "error.language.name": "Please enter a valid name for the language",
"error.language.notFound": "The language could not be found", "error.language.notFound": "The language could not be found",
"error.layout.validation.block": "There's an error in block {blockIndex} in layout {layoutIndex}", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "There's an error in layout {index} settings", "error.layout.validation.settings": "There's an error in layout {index} settings",
"error.license.format": "Please enter a valid license key", "error.license.format": "Please enter a valid license key",
"error.license.email": "Please enter a valid email address", "error.license.email": "Please enter a valid email address",
"error.license.verification": "The license could not be verified", "error.license.verification": "The license could not be verified",
"error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "The Panel is currently offline", "error.offline": "The Panel is currently offline",
"error.page.changeSlug.permission": "You are not allowed to change the URL appendix for \"{slug}\"", "error.page.changeSlug.permission": "You are not allowed to change the URL appendix for \"{slug}\"",
@ -282,9 +284,13 @@
"field.layout.empty": "No rows yet", "field.layout.empty": "No rows yet",
"field.layout.select": "Select a layout", "field.layout.select": "Select a layout",
"field.object.empty": "No information yet",
"field.pages.empty": "No pages selected yet", "field.pages.empty": "No pages selected yet",
"field.structure.delete.confirm": "Do you really want to delete this row?", "field.structure.delete.confirm": "Do you really want to delete this row?",
"field.structure.empty": "No entries yet", "field.structure.empty": "No entries yet",
"field.users.empty": "No users selected yet", "field.users.empty": "No users selected yet",
"file.blueprint": "This file has no blueprint yet. You can define the setup in <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "This file has no blueprint yet. You can define the setup in <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -448,6 +454,7 @@
"paste": "Paste", "paste": "Paste",
"paste.after": "Paste after", "paste.after": "Paste after",
"pixel": "Pixel", "pixel": "Pixel",
"plugin": "Plugin",
"plugins": "Plugins", "plugins": "Plugins",
"prev": "Previous", "prev": "Previous",
"preview": "Preview", "preview": "Preview",
@ -487,11 +494,24 @@
"stats.empty": "No reports", "stats.empty": "No reports",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "The content folder seems to be exposed",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.debug": "Debugging must be turned off in production",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.git": "The .git folder seems to be exposed",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.https": "We recommend HTTPS for all your sites",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.kirby": "The kirby folder seems to be exposed",
"system.issues.site": "The site folder seems to be exposed", "system.issues.site": "The site folder seems to be exposed",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Could not check for updates",
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
"system.updateStatus.security-update": "Free security update { version } available",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "Unreleased version",
"system.updateStatus.up-to-date": "Up to date",
"system.updateStatus.update": "Free update { version } available",
"system.updateStatus.upgrade": "Upgrade { version } available",
"title": "Title", "title": "Title",
"template": "Template", "template": "Template",
@ -558,6 +578,9 @@
"users": "Users", "users": "Users",
"version": "Version", "version": "Version",
"version.current": "Current version",
"version.latest": "Latest version",
"versionInformation": "Version information",
"view.account": "Your account", "view.account": "Your account",
"view.installation": "Installation", "view.installation": "Installation",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "Vi devas ne aldoni pli ol unu bloko", "error.blocks.max.singular": "Vi devas ne aldoni pli ol unu bloko",
"error.blocks.min.plural": "Oni devas aldoni almenaŭ {min} blokojn", "error.blocks.min.plural": "Oni devas aldoni almenaŭ {min} blokojn",
"error.blocks.min.singular": "Oni devas aldoni almenaŭ unu blokon", "error.blocks.min.singular": "Oni devas aldoni almenaŭ unu blokon",
"error.blocks.validation": "Estas eraro en bloko {index}", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "La retpoŝta antaŭagordo \"{name}\" ne estas trovebla", "error.email.preset.notFound": "La retpoŝta antaŭagordo \"{name}\" ne estas trovebla",
@ -107,13 +107,15 @@
"error.language.name": "Bonvolu entajpi validan nomon por la lingvo", "error.language.name": "Bonvolu entajpi validan nomon por la lingvo",
"error.language.notFound": "La lingvo ne troveblas", "error.language.notFound": "La lingvo ne troveblas",
"error.layout.validation.block": "Estas eraro en bloko {blockIndex}, en blokaranĝo {layoutIndex}", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "Estas eraro en la agordoj de blokaranĝo {index}", "error.layout.validation.settings": "Estas eraro en la agordoj de blokaranĝo {index}",
"error.license.format": "Bonvolu entajpi validan kodon de permisilo", "error.license.format": "Bonvolu entajpi validan kodon de permisilo",
"error.license.email": "Bonvolu entajpi validan retpoŝtadreson", "error.license.email": "Bonvolu entajpi validan retpoŝtadreson",
"error.license.verification": "Ne eblis kontroli la permisilon", "error.license.verification": "Ne eblis kontroli la permisilon",
"error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "La panelo estas ĉi-momente nekonektita", "error.offline": "La panelo estas ĉi-momente nekonektita",
"error.page.changeSlug.permission": "Vi ne rajtas ŝanĝi la URL-nomon de \"{slug}\"", "error.page.changeSlug.permission": "Vi ne rajtas ŝanĝi la URL-nomon de \"{slug}\"",
@ -282,9 +284,13 @@
"field.layout.empty": "Ankoraŭ neniu vico", "field.layout.empty": "Ankoraŭ neniu vico",
"field.layout.select": "Elekti blokaranĝon", "field.layout.select": "Elekti blokaranĝon",
"field.object.empty": "No information yet",
"field.pages.empty": "Ankoraŭ neniu paĝo elektita", "field.pages.empty": "Ankoraŭ neniu paĝo elektita",
"field.structure.delete.confirm": "Ĉu vi certe volas forigi ĉi tiun vicon?", "field.structure.delete.confirm": "Ĉu vi certe volas forigi ĉi tiun vicon?",
"field.structure.empty": "Ankoraŭ neniu enigo", "field.structure.empty": "Ankoraŭ neniu enigo",
"field.users.empty": "Ankoraŭ neniu uzanto elektita", "field.users.empty": "Ankoraŭ neniu uzanto elektita",
"file.blueprint": "Ĉi tiu dosiero ankoraŭ havas neniun planon. Vi povas difini planon ĉe <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "Ĉi tiu dosiero ankoraŭ havas neniun planon. Vi povas difini planon ĉe <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -360,7 +366,7 @@
"lock.unlock": "Malŝlosi", "lock.unlock": "Malŝlosi",
"lock.isUnlocked": "Viaj nekonservitaj ŝanĝoj estas ŝanĝitaj de alia uzanto. Vi povas elŝuti dosieron kun viaj ŝanĝoj por permane kunfandi ilin.", "lock.isUnlocked": "Viaj nekonservitaj ŝanĝoj estas ŝanĝitaj de alia uzanto. Vi povas elŝuti dosieron kun viaj ŝanĝoj por permane kunfandi ilin.",
"login": "Ensaluti", "login": "Log in",
"login.code.label.login": "Ensaluta kodo", "login.code.label.login": "Ensaluta kodo",
"login.code.label.password-reset": "Kodo por restarigi pasvorton", "login.code.label.password-reset": "Kodo por restarigi pasvorton",
"login.code.placeholder.email": "000 000", "login.code.placeholder.email": "000 000",
@ -448,6 +454,7 @@
"paste": "Alglui", "paste": "Alglui",
"paste.after": "Alglui post", "paste.after": "Alglui post",
"pixel": "Pikselo", "pixel": "Pikselo",
"plugin": "Plugin",
"plugins": "Kromprogramoj", "plugins": "Kromprogramoj",
"prev": "Antaŭe", "prev": "Antaŭe",
"preview": "Antaŭrigardi", "preview": "Antaŭrigardi",
@ -487,11 +494,24 @@
"stats.empty": "No reports", "stats.empty": "No reports",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "The content folder seems to be exposed",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.debug": "Debugging must be turned off in production",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.git": "The .git folder seems to be exposed",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.https": "We recommend HTTPS for all your sites",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.kirby": "The kirby folder seems to be exposed",
"system.issues.site": "The site folder seems to be exposed", "system.issues.site": "The site folder seems to be exposed",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Could not check for updates",
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
"system.updateStatus.security-update": "Free security update { version } available",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "Unreleased version",
"system.updateStatus.up-to-date": "Up to date",
"system.updateStatus.update": "Free update { version } available",
"system.updateStatus.upgrade": "Upgrade { version } available",
"title": "Titolo", "title": "Titolo",
"template": "Ŝablono", "template": "Ŝablono",
@ -558,6 +578,9 @@
"users": "Uzantoj", "users": "Uzantoj",
"version": "Versio", "version": "Versio",
"version.current": "Current version",
"version.latest": "Latest version",
"versionInformation": "Version information",
"view.account": "Via konto", "view.account": "Via konto",
"view.installation": "Instalado", "view.installation": "Instalado",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "No debes añadir más de un bloque", "error.blocks.max.singular": "No debes añadir más de un bloque",
"error.blocks.min.plural": "Debes añadir al menos {min} bloques ", "error.blocks.min.plural": "Debes añadir al menos {min} bloques ",
"error.blocks.min.singular": "Debes añadir al menos un bloque", "error.blocks.min.singular": "Debes añadir al menos un bloque",
"error.blocks.validation": "Hay un error en el bloque {index}", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "El preajuste de email \"{name}\" no se pudo encontrar.", "error.email.preset.notFound": "El preajuste de email \"{name}\" no se pudo encontrar.",
@ -107,13 +107,15 @@
"error.language.name": "Por favor introduce un nombre válido para el idioma", "error.language.name": "Por favor introduce un nombre válido para el idioma",
"error.language.notFound": "No se pudo encontrar el idioma", "error.language.notFound": "No se pudo encontrar el idioma",
"error.layout.validation.block": "There's an error in block {blockIndex} in layout {layoutIndex}", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "There's an error in layout {index} settings", "error.layout.validation.settings": "There's an error in layout {index} settings",
"error.license.format": "Por favor introduce una llave de licencia válida", "error.license.format": "Por favor introduce una llave de licencia válida",
"error.license.email": "Por favor ingresa un correo electrónico valido", "error.license.email": "Por favor ingresa un correo electrónico valido",
"error.license.verification": "La licencia no pude ser verificada", "error.license.verification": "La licencia no pude ser verificada",
"error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "El Panel se encuentra fuera de linea ", "error.offline": "El Panel se encuentra fuera de linea ",
"error.page.changeSlug.permission": "No está permitido cambiar el apéndice de URL para \"{slug}\".", "error.page.changeSlug.permission": "No está permitido cambiar el apéndice de URL para \"{slug}\".",
@ -282,9 +284,13 @@
"field.layout.empty": "No rows yet", "field.layout.empty": "No rows yet",
"field.layout.select": "Select a layout", "field.layout.select": "Select a layout",
"field.object.empty": "No information yet",
"field.pages.empty": "Aún no ha seleccionado ningúna pagina", "field.pages.empty": "Aún no ha seleccionado ningúna pagina",
"field.structure.delete.confirm": "\u00bfEn realidad desea borrar esta entrada?", "field.structure.delete.confirm": "\u00bfEn realidad desea borrar esta entrada?",
"field.structure.empty": "A\u00fan no existen entradas.", "field.structure.empty": "A\u00fan no existen entradas.",
"field.users.empty": "Aún no ha seleccionado ningún usuario", "field.users.empty": "Aún no ha seleccionado ningún usuario",
"file.blueprint": "This file has no blueprint yet. You can define the setup in <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "This file has no blueprint yet. You can define the setup in <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -448,6 +454,7 @@
"paste": "Paste", "paste": "Paste",
"paste.after": "Paste after", "paste.after": "Paste after",
"pixel": "Pixel", "pixel": "Pixel",
"plugin": "Plugin",
"plugins": "Plugins", "plugins": "Plugins",
"prev": "Anterior", "prev": "Anterior",
"preview": "Preview", "preview": "Preview",
@ -487,11 +494,24 @@
"stats.empty": "No reports", "stats.empty": "No reports",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "The content folder seems to be exposed",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.debug": "Debugging must be turned off in production",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.git": "The .git folder seems to be exposed",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.https": "We recommend HTTPS for all your sites",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.kirby": "The kirby folder seems to be exposed",
"system.issues.site": "The site folder seems to be exposed", "system.issues.site": "The site folder seems to be exposed",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Could not check for updates",
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
"system.updateStatus.security-update": "Free security update { version } available",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "Unreleased version",
"system.updateStatus.up-to-date": "Up to date",
"system.updateStatus.update": "Free update { version } available",
"system.updateStatus.upgrade": "Upgrade { version } available",
"title": "Título", "title": "Título",
"template": "Plantilla", "template": "Plantilla",
@ -558,6 +578,9 @@
"users": "Usuarios", "users": "Usuarios",
"version": "Versión", "version": "Versión",
"version.current": "Current version",
"version.latest": "Latest version",
"versionInformation": "Version information",
"view.account": "Tu cuenta", "view.account": "Tu cuenta",
"view.installation": "Instalaci\u00f3n", "view.installation": "Instalaci\u00f3n",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "No debes añadir más de un bloque", "error.blocks.max.singular": "No debes añadir más de un bloque",
"error.blocks.min.plural": "Debes añadir al menos {min} bloques ", "error.blocks.min.plural": "Debes añadir al menos {min} bloques ",
"error.blocks.min.singular": "Debes añadir al menos un bloque", "error.blocks.min.singular": "Debes añadir al menos un bloque",
"error.blocks.validation": "Hay un error en el bloque {index}", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "El preset del correo \"{name}\" no pudo ser encontrado", "error.email.preset.notFound": "El preset del correo \"{name}\" no pudo ser encontrado",
@ -107,13 +107,15 @@
"error.language.name": "Por favor introduce un nombre válido para el idioma", "error.language.name": "Por favor introduce un nombre válido para el idioma",
"error.language.notFound": "No se pudo encontrar el idioma", "error.language.notFound": "No se pudo encontrar el idioma",
"error.layout.validation.block": "There's an error in block {blockIndex} in layout {layoutIndex}", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "There's an error in layout {index} settings", "error.layout.validation.settings": "There's an error in layout {index} settings",
"error.license.format": "Por favor introduce una llave de licencia válida", "error.license.format": "Por favor introduce una llave de licencia válida",
"error.license.email": "Por favor, introduce un correo electrónico válido", "error.license.email": "Por favor, introduce un correo electrónico válido",
"error.license.verification": "La licencia no pude ser verificada", "error.license.verification": "La licencia no pude ser verificada",
"error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "El Panel se encuentra fuera de linea ", "error.offline": "El Panel se encuentra fuera de linea ",
"error.page.changeSlug.permission": "No está permitido cambiar el apéndice de URL para \"{slug}\"", "error.page.changeSlug.permission": "No está permitido cambiar el apéndice de URL para \"{slug}\"",
@ -282,9 +284,13 @@
"field.layout.empty": "No rows yet", "field.layout.empty": "No rows yet",
"field.layout.select": "Select a layout", "field.layout.select": "Select a layout",
"field.object.empty": "No information yet",
"field.pages.empty": "Aún no hay páginas seleccionadas", "field.pages.empty": "Aún no hay páginas seleccionadas",
"field.structure.delete.confirm": "¿Realmente quieres eliminar esta fila?", "field.structure.delete.confirm": "¿Realmente quieres eliminar esta fila?",
"field.structure.empty": "Aún no hay entradas", "field.structure.empty": "Aún no hay entradas",
"field.users.empty": "Aún no hay usuarios seleccionados", "field.users.empty": "Aún no hay usuarios seleccionados",
"file.blueprint": "This file has no blueprint yet. You can define the setup in <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "This file has no blueprint yet. You can define the setup in <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -448,6 +454,7 @@
"paste": "Paste", "paste": "Paste",
"paste.after": "Paste after", "paste.after": "Paste after",
"pixel": "Pixel", "pixel": "Pixel",
"plugin": "Plugin",
"plugins": "Plugins", "plugins": "Plugins",
"prev": "Anterior", "prev": "Anterior",
"preview": "Preview", "preview": "Preview",
@ -487,11 +494,24 @@
"stats.empty": "No reports", "stats.empty": "No reports",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "The content folder seems to be exposed",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.debug": "Debugging must be turned off in production",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.git": "The .git folder seems to be exposed",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.https": "We recommend HTTPS for all your sites",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.kirby": "The kirby folder seems to be exposed",
"system.issues.site": "The site folder seems to be exposed", "system.issues.site": "The site folder seems to be exposed",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Could not check for updates",
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
"system.updateStatus.security-update": "Free security update { version } available",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "Unreleased version",
"system.updateStatus.up-to-date": "Up to date",
"system.updateStatus.update": "Free update { version } available",
"system.updateStatus.upgrade": "Upgrade { version } available",
"title": "Titulo", "title": "Titulo",
"template": "Plantilla", "template": "Plantilla",
@ -558,6 +578,9 @@
"users": "Usuarios", "users": "Usuarios",
"version": "Versión", "version": "Versión",
"version.current": "Current version",
"version.latest": "Latest version",
"versionInformation": "Version information",
"view.account": "Su cuenta", "view.account": "Su cuenta",
"view.installation": "Instalación", "view.installation": "Instalación",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "You must not add more than one block", "error.blocks.max.singular": "You must not add more than one block",
"error.blocks.min.plural": "You must add at least {min} blocks", "error.blocks.min.plural": "You must add at least {min} blocks",
"error.blocks.min.singular": "You must add at least one block", "error.blocks.min.singular": "You must add at least one block",
"error.blocks.validation": "There's an error in block {index}", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "قالب ایمیل «{name}» پیدا نشد", "error.email.preset.notFound": "قالب ایمیل «{name}» پیدا نشد",
@ -107,13 +107,15 @@
"error.language.name": "Please enter a valid name for the language", "error.language.name": "Please enter a valid name for the language",
"error.language.notFound": "The language could not be found", "error.language.notFound": "The language could not be found",
"error.layout.validation.block": "There's an error in block {blockIndex} in layout {layoutIndex}", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "There's an error in layout {index} settings", "error.layout.validation.settings": "There's an error in layout {index} settings",
"error.license.format": "Please enter a valid license key", "error.license.format": "Please enter a valid license key",
"error.license.email": "لطفا ایمیل صحیحی وارد کنید", "error.license.email": "لطفا ایمیل صحیحی وارد کنید",
"error.license.verification": "The license could not be verified", "error.license.verification": "The license could not be verified",
"error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "The Panel is currently offline", "error.offline": "The Panel is currently offline",
"error.page.changeSlug.permission": "شما امکان تغییر پسوند Url صفحه «{slug}» را ندارید", "error.page.changeSlug.permission": "شما امکان تغییر پسوند Url صفحه «{slug}» را ندارید",
@ -282,9 +284,13 @@
"field.layout.empty": "No rows yet", "field.layout.empty": "No rows yet",
"field.layout.select": "Select a layout", "field.layout.select": "Select a layout",
"field.object.empty": "No information yet",
"field.pages.empty": "صفحه‌ای انتخاب نشده است", "field.pages.empty": "صفحه‌ای انتخاب نشده است",
"field.structure.delete.confirm": "\u0645\u062f\u062e\u0644 \u062c\u0627\u0631\u06cc \u062d\u0630\u0641 \u0634\u0648\u062f\u061f", "field.structure.delete.confirm": "\u0645\u062f\u062e\u0644 \u062c\u0627\u0631\u06cc \u062d\u0630\u0641 \u0634\u0648\u062f\u061f",
"field.structure.empty": "\u0645\u0648\u0631\u062f\u06cc \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0631\u062f.", "field.structure.empty": "\u0645\u0648\u0631\u062f\u06cc \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0631\u062f.",
"field.users.empty": "کاربری انتخاب نشده است", "field.users.empty": "کاربری انتخاب نشده است",
"file.blueprint": "This file has no blueprint yet. You can define the setup in <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "This file has no blueprint yet. You can define the setup in <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -448,6 +454,7 @@
"paste": "Paste", "paste": "Paste",
"paste.after": "Paste after", "paste.after": "Paste after",
"pixel": "پیکسل", "pixel": "پیکسل",
"plugin": "Plugin",
"plugins": "Plugins", "plugins": "Plugins",
"prev": "قبلی", "prev": "قبلی",
"preview": "Preview", "preview": "Preview",
@ -487,11 +494,24 @@
"stats.empty": "No reports", "stats.empty": "No reports",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "The content folder seems to be exposed",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.debug": "Debugging must be turned off in production",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.git": "The .git folder seems to be exposed",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.https": "We recommend HTTPS for all your sites",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.kirby": "The kirby folder seems to be exposed",
"system.issues.site": "The site folder seems to be exposed", "system.issues.site": "The site folder seems to be exposed",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Could not check for updates",
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
"system.updateStatus.security-update": "Free security update { version } available",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "Unreleased version",
"system.updateStatus.up-to-date": "Up to date",
"system.updateStatus.update": "Free update { version } available",
"system.updateStatus.upgrade": "Upgrade { version } available",
"title": "عنوان", "title": "عنوان",
"template": "\u0642\u0627\u0644\u0628 \u0635\u0641\u062d\u0647", "template": "\u0642\u0627\u0644\u0628 \u0635\u0641\u062d\u0647",
@ -558,6 +578,9 @@
"users": "کاربران", "users": "کاربران",
"version": "\u0646\u0633\u062e\u0647 \u0646\u0631\u0645 \u0627\u0641\u0632\u0627\u0631", "version": "\u0646\u0633\u062e\u0647 \u0646\u0631\u0645 \u0627\u0641\u0632\u0627\u0631",
"version.current": "Current version",
"version.latest": "Latest version",
"versionInformation": "Version information",
"view.account": "حساب کاربری شما", "view.account": "حساب کاربری شما",
"view.installation": "\u0646\u0635\u0628 \u0648 \u0631\u0627\u0647 \u0627\u0646\u062f\u0627\u0632\u06cc", "view.installation": "\u0646\u0635\u0628 \u0648 \u0631\u0627\u0647 \u0627\u0646\u062f\u0627\u0632\u06cc",

View file

@ -29,7 +29,7 @@
"days.tue": "Ti", "days.tue": "Ti",
"days.wed": "Ke", "days.wed": "Ke",
"debugging": "Debugging", "debugging": "Virheenkäsittelytila",
"delete": "Poista", "delete": "Poista",
"delete.all": "Poista kaikki", "delete.all": "Poista kaikki",
@ -70,7 +70,7 @@
"error.blocks.max.singular": "Voit lisätä enintään yhden lohkon", "error.blocks.max.singular": "Voit lisätä enintään yhden lohkon",
"error.blocks.min.plural": "Lisää vähintään {min} lohkoa", "error.blocks.min.plural": "Lisää vähintään {min} lohkoa",
"error.blocks.min.singular": "Lisää vähintään yksi lohko", "error.blocks.min.singular": "Lisää vähintään yksi lohko",
"error.blocks.validation": "Virhe lohkossa {index}", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "Nimellä \"{name}\" ja kyseisellä verkkotunnuksella ei löydy sähköpostiosoitetta", "error.email.preset.notFound": "Nimellä \"{name}\" ja kyseisellä verkkotunnuksella ei löydy sähköpostiosoitetta",
@ -107,13 +107,15 @@
"error.language.name": "Anna kielen nimi", "error.language.name": "Anna kielen nimi",
"error.language.notFound": "Kieltä ei löytynyt", "error.language.notFound": "Kieltä ei löytynyt",
"error.layout.validation.block": "Lohkon {blockIndex} asetelmassa {layoutIndex} tapahtui virhe", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "Virhe asetelman {index} asetuksissa", "error.layout.validation.settings": "Virhe asetelman {index} asetuksissa",
"error.license.format": "Anna lisenssiavain", "error.license.format": "Anna lisenssiavain",
"error.license.email": "Anna sähköpostiosoite", "error.license.email": "Anna sähköpostiosoite",
"error.license.verification": "Lisenssiä ei voitu vahvistaa", "error.license.verification": "Lisenssiä ei voitu vahvistaa",
"error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "Paneeli on offline-tilassa", "error.offline": "Paneeli on offline-tilassa",
"error.page.changeSlug.permission": "Sinulla ei ole oikeutta muuttaa URL-liitettä sivulle \"{slug}\"", "error.page.changeSlug.permission": "Sinulla ei ole oikeutta muuttaa URL-liitettä sivulle \"{slug}\"",
@ -160,7 +162,7 @@
"error.template.default.notFound": "Oletussivupohjaa ei ole määritetty", "error.template.default.notFound": "Oletussivupohjaa ei ole määritetty",
"error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", "error.unexpected": "Pahus, määrittelemätön virhe! Laita virheenkäsittelytila päälle saadaksesi lisätietoja: https://getkirby.com/docs/reference/system/options/debug",
"error.user.changeEmail.permission": "Sinulla ei ole oikeutta vaihtaa käyttäjän \"{name}\" sähköpostiosoitetta", "error.user.changeEmail.permission": "Sinulla ei ole oikeutta vaihtaa käyttäjän \"{name}\" sähköpostiosoitetta",
"error.user.changeLanguage.permission": "Sinulla ei ole oikeutta vaihtaa käyttäjän \"{name}\" kieltä", "error.user.changeLanguage.permission": "Sinulla ei ole oikeutta vaihtaa käyttäjän \"{name}\" kieltä",
@ -257,7 +259,7 @@
"field.blocks.image.placeholder": "Valitse kuva", "field.blocks.image.placeholder": "Valitse kuva",
"field.blocks.image.ratio": "Kuvasuhde", "field.blocks.image.ratio": "Kuvasuhde",
"field.blocks.image.url": "Kuvan URL", "field.blocks.image.url": "Kuvan URL",
"field.blocks.line.name": "Line", "field.blocks.line.name": "Rivi",
"field.blocks.list.name": "Lista", "field.blocks.list.name": "Lista",
"field.blocks.markdown.name": "Markdown", "field.blocks.markdown.name": "Markdown",
"field.blocks.markdown.label": "Teksti", "field.blocks.markdown.label": "Teksti",
@ -282,9 +284,13 @@
"field.layout.empty": "Ei rivejä", "field.layout.empty": "Ei rivejä",
"field.layout.select": "Valitse asettelu", "field.layout.select": "Valitse asettelu",
"field.object.empty": "Ei vielä tietoja",
"field.pages.empty": " Sivuja ei ole vielä valittu", "field.pages.empty": " Sivuja ei ole vielä valittu",
"field.structure.delete.confirm": "Haluatko varmasti poistaa tämän rivin?", "field.structure.delete.confirm": "Haluatko varmasti poistaa tämän rivin?",
"field.structure.empty": "Rivejä ei ole vielä lisätty", "field.structure.empty": "Rivejä ei ole vielä lisätty",
"field.users.empty": "Käyttäjiä ei ole vielä valittu", "field.users.empty": "Käyttäjiä ei ole vielä valittu",
"file.blueprint": "Tällä tiedostolla ei ole vielä suunnitelmaa. Voit määrittää suunnitelman tiedostoon <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "Tällä tiedostolla ei ole vielä suunnitelmaa. Voit määrittää suunnitelman tiedostoon <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -297,7 +303,7 @@
"hide": "Piilota", "hide": "Piilota",
"hour": "Tunti", "hour": "Tunti",
"import": "Tuo", "import": "Tuo",
"info": "Info", "info": "Tietoja",
"insert": "Lis\u00e4\u00e4", "insert": "Lis\u00e4\u00e4",
"insert.after": "Lisää eteen", "insert.after": "Lisää eteen",
"insert.before": "Lisää jälkeen", "insert.before": "Lisää jälkeen",
@ -340,12 +346,12 @@
"license": "Lisenssi", "license": "Lisenssi",
"license.buy": "Osta lisenssi", "license.buy": "Osta lisenssi",
"license.register": "Rekisteröi", "license.register": "Rekisteröi",
"license.manage": "Manage your licenses", "license.manage": "Hallinnoi lisenssejäsi",
"license.register.help": "Lisenssiavain on lähetetty oston jälkeen sähköpostiisi. Kopioi ja liitä avain tähän.", "license.register.help": "Lisenssiavain on lähetetty oston jälkeen sähköpostiisi. Kopioi ja liitä avain tähän.",
"license.register.label": "Anna lisenssiavain", "license.register.label": "Anna lisenssiavain",
"license.register.success": "Kiitos kun tuet Kirbyä", "license.register.success": "Kiitos kun tuet Kirbyä",
"license.unregistered": "Tämä on rekisteröimätön demo Kirbystä", "license.unregistered": "Tämä on rekisteröimätön demo Kirbystä",
"license.unregistered.label": "Unregistered", "license.unregistered.label": "Rekisteröimätön",
"link": "Linkki", "link": "Linkki",
"link.text": "Linkin teksti", "link.text": "Linkin teksti",
@ -448,6 +454,7 @@
"paste": "Liitä", "paste": "Liitä",
"paste.after": "Liitä jälkeen", "paste.after": "Liitä jälkeen",
"pixel": "Pikseli", "pixel": "Pikseli",
"plugin": "Liitännäinen",
"plugins": "Liitännäiset", "plugins": "Liitännäiset",
"prev": "Edellinen", "prev": "Edellinen",
"preview": "Esikatselu", "preview": "Esikatselu",
@ -475,7 +482,7 @@
"section.required": "Osio on pakollinen", "section.required": "Osio on pakollinen",
"security": "Security", "security": "Tietoturva",
"select": "Valitse", "select": "Valitse",
"server": "Palvelin", "server": "Palvelin",
"settings": "Asetukset", "settings": "Asetukset",
@ -485,13 +492,26 @@
"slug": "URL-tunniste", "slug": "URL-tunniste",
"sort": "Järjestele", "sort": "Järjestele",
"stats.empty": "No reports", "stats.empty": "Ei raportteja",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "Content-kansio näyttäisi olevan julkinen",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.debug": "Virheenkäsittelytila pitää poistaa käytöstä tuotantoympäristössä",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.git": ".git-kansio näyttäisi olevan julkinen",
"system.issues.site": "The site folder seems to be exposed", "system.issues.https": "Suosittelemme HTTPS:n käyttöä kaikilla sivustoillasi",
"system.issues.kirby": "Kirby-kansio näyttäisi olevan julkinen",
"system.issues.site": "Site-kansio näyttäisi olevan julkinen",
"system.issues.vulnerability.kirby": "Asennuksesi voi olla altis seuraaville haavoittuvuuksille ({ severity } vakavuus): { description }",
"system.issues.vulnerability.plugin": "Asennuksesi käyttämä liitännäinen { plugin } voi olla altis haavoittuvuudelle ({ severity } vakavuus): { description }",
"system.updateStatus": "Päivitysten tilanne",
"system.updateStatus.error": "Päivityksiä ei voitu tarkistaa",
"system.updateStatus.not-vulnerable": "Ei tunnettuja haavoittuvuuksia",
"system.updateStatus.security-update": "Ilmainen tietoturvapäivitys { version } saatavilla",
"system.updateStatus.security-upgrade": "Tietoturvakorjauksia sisältävä päivitys { version } saatavilla",
"system.updateStatus.unreleased": "Julkaisematon versio",
"system.updateStatus.up-to-date": "Ajan tasalla",
"system.updateStatus.update": "Ilmainen päivitys { version } saatavilla",
"system.updateStatus.upgrade": "Päivitys { version } saatavilla",
"title": "Nimi", "title": "Nimi",
"template": "Sivupohja", "template": "Sivupohja",
@ -558,6 +578,9 @@
"users": "Käyttäjät", "users": "Käyttäjät",
"version": "Versio", "version": "Versio",
"version.current": "Nykyinen versio ",
"version.latest": "Uusin versio ",
"versionInformation": "Version tiedot",
"view.account": "Oma käyttäjätili", "view.account": "Oma käyttäjätili",
"view.installation": "Asennus", "view.installation": "Asennus",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "Vous ne devez pas ajouter plus d'un bloc", "error.blocks.max.singular": "Vous ne devez pas ajouter plus d'un bloc",
"error.blocks.min.plural": "Vous devez ajouter au moins {min} blocs", "error.blocks.min.plural": "Vous devez ajouter au moins {min} blocs",
"error.blocks.min.singular": "Vous devez ajouter au moins un bloc", "error.blocks.min.singular": "Vous devez ajouter au moins un bloc",
"error.blocks.validation": "Il y a une erreur dans le bloc {index}", "error.blocks.validation": "Il y a une erreur sur le champ \"{field}\" du bloc {index} utilisant le type de bloc \"{fieldset}\"",
"error.email.preset.notFound": "La configuration de courriel « {name} » na pu être trouvé ", "error.email.preset.notFound": "La configuration de courriel « {name} » na pu être trouvé ",
@ -107,13 +107,15 @@
"error.language.name": "Veuillez saisir un nom valide pour cette langue", "error.language.name": "Veuillez saisir un nom valide pour cette langue",
"error.language.notFound": "La langue na pu être trouvée", "error.language.notFound": "La langue na pu être trouvée",
"error.layout.validation.block": "Il y a une erreur dans le block {blockIndex} de la disposition {layoutIndex}", "error.layout.validation.block": "Il y a une erreur sur le champ \"{field}\" du bloc {blockIndex} utilisant le type de bloc \"{fieldset}\" dans le layout {layoutIndex}.",
"error.layout.validation.settings": "Il y a une erreur dans les paramètres de la disposition {index}", "error.layout.validation.settings": "Il y a une erreur dans les paramètres de la disposition {index}",
"error.license.format": "Veuillez saisir un numéro de licence valide", "error.license.format": "Veuillez saisir un numéro de licence valide",
"error.license.email": "Veuillez saisir un courriel valide", "error.license.email": "Veuillez saisir un courriel valide",
"error.license.verification": "La licence na pu être vérifiée", "error.license.verification": "La licence na pu être vérifiée",
"error.object.validation": "Il y a une erreur dans le champ \"{label}\" :\n{message}",
"error.offline": "Le Panel est actuellement hors ligne", "error.offline": "Le Panel est actuellement hors ligne",
"error.page.changeSlug.permission": "Vous nêtes pas autorisé à modifier lidentifiant dURL pour « {slug} »", "error.page.changeSlug.permission": "Vous nêtes pas autorisé à modifier lidentifiant dURL pour « {slug} »",
@ -282,9 +284,13 @@
"field.layout.empty": "Pas encore de rangées", "field.layout.empty": "Pas encore de rangées",
"field.layout.select": "Choisir une disposition", "field.layout.select": "Choisir une disposition",
"field.object.empty": "Pas encore dinformation",
"field.pages.empty": "Pas encore de page sélectionnée", "field.pages.empty": "Pas encore de page sélectionnée",
"field.structure.delete.confirm": "Voulez-vous vraiment supprimer cette ligne ?", "field.structure.delete.confirm": "Voulez-vous vraiment supprimer cette ligne ?",
"field.structure.empty": "Pas encore dentrée", "field.structure.empty": "Pas encore dentrée",
"field.users.empty": "Pas encore dutilisateur sélectionné", "field.users.empty": "Pas encore dutilisateur sélectionné",
"file.blueprint": "Ce fichier na pas encore de blueprint. Vous pouvez en définir les paramètres dans <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "Ce fichier na pas encore de blueprint. Vous pouvez en définir les paramètres dans <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -365,7 +371,7 @@
"login.code.label.password-reset": "Code de réinitialisation du mot de passe", "login.code.label.password-reset": "Code de réinitialisation du mot de passe",
"login.code.placeholder.email": "000 000", "login.code.placeholder.email": "000 000",
"login.code.text.email": "Si votre adresse de courriel est enregistrée, le code demandé vous sera envoyé par courriel.", "login.code.text.email": "Si votre adresse de courriel est enregistrée, le code demandé vous sera envoyé par courriel.",
"login.email.login.body": "Bonjour {user.nameOrEmail},\n\nVous avez récemment demandé un code de connexion pour le Panel de {site}.\nLe codede connexion suivant sera valide pendant {timeout} minutes :\n\n{code}\n\nSi vous navez pas demandé de codede connexion, veuillez ignorer cet email ou contacter votre administrateur si vous avez des questions.\nPar sécurité, merci de ne PAS faire suivre cet email.", "login.email.login.body": "Bonjour {user.nameOrEmail},\n\nVous avez récemment demandé un code de connexion pour le Panel de {site}.\nLe code de connexion suivant sera valide pendant {timeout} minutes :\n\n{code}\n\nSi vous navez pas demandé de code de connexion, veuillez ignorer cet email ou contacter votre administrateur si vous avez des questions.\nPar sécurité, merci de ne PAS faire suivre cet email.",
"login.email.login.subject": "Votre code de connexion", "login.email.login.subject": "Votre code de connexion",
"login.email.password-reset.body": "Bonjour {user.nameOrEmail},\n\nVous avez récemment demandé un code de réinitialisation de mot de passe pour le Panel de {site}.\nLe code de réinitialisation de mot de passe suivant sera valide pendant {timeout} minutes :\n\n{code}\n\nSi vous navez pas demandé de code de réinitialisation de mot de passe, veuillez ignorer cet email ou contacter votre administrateur si vous avez des questions.\nPar sécurité, merci de ne PAS faire suivre cet email.", "login.email.password-reset.body": "Bonjour {user.nameOrEmail},\n\nVous avez récemment demandé un code de réinitialisation de mot de passe pour le Panel de {site}.\nLe code de réinitialisation de mot de passe suivant sera valide pendant {timeout} minutes :\n\n{code}\n\nSi vous navez pas demandé de code de réinitialisation de mot de passe, veuillez ignorer cet email ou contacter votre administrateur si vous avez des questions.\nPar sécurité, merci de ne PAS faire suivre cet email.",
"login.email.password-reset.subject": "Votre code de réinitialisation du mot de passe", "login.email.password-reset.subject": "Votre code de réinitialisation du mot de passe",
@ -448,6 +454,7 @@
"paste": "Coller", "paste": "Coller",
"paste.after": "Coller après", "paste.after": "Coller après",
"pixel": "Pixel", "pixel": "Pixel",
"plugin": "Plugin",
"plugins": "Plugins", "plugins": "Plugins",
"prev": "Précédent", "prev": "Précédent",
"preview": "Prévisualiser", "preview": "Prévisualiser",
@ -487,11 +494,24 @@
"stats.empty": "Aucun rapport", "stats.empty": "Aucun rapport",
"system.issues.content": "Le dossier content semble exposé", "system.issues.content": "Le dossier content semble exposé",
"system.issues.eol.kirby": "La version de Kirby installée a atteint la fin de son cycle de vie et ne recevra plus de mises à jour de sécurité",
"system.issues.eol.plugin": "La version du plugin { plugin } installée a atteint la fin de son cycle de vie et ne recevra plus de mises à jour de sécurité",
"system.issues.debug": "Le débogage doit être désactivé en production", "system.issues.debug": "Le débogage doit être désactivé en production",
"system.issues.git": "Le dossier .git semble exposé", "system.issues.git": "Le dossier .git semble exposé",
"system.issues.https": "Nous recommandons HTTPS pour tous vos sites", "system.issues.https": "Nous recommandons HTTPS pour tous vos sites",
"system.issues.kirby": "Le dossier kirby semble exposé", "system.issues.kirby": "Le dossier kirby semble exposé",
"system.issues.site": "Le dossier site semble exposé", "system.issues.site": "Le dossier site semble exposé",
"system.issues.vulnerability.kirby": "Votre installation pourrait être affectée par la vulnérabilité suivante ({ severity } gravité) : { description }",
"system.issues.vulnerability.plugin": "Votre installation pourrait être affectée par la vulnérabilité suivante du plugin { plugin } ({ severity } gravité) : { description }",
"system.updateStatus": "Statut des mises à jour",
"system.updateStatus.error": "Les mises à jour n'ont pu être vérifiées",
"system.updateStatus.not-vulnerable": "Aucune vulnérabilité connue",
"system.updateStatus.security-update": "Mise à jour gratuite { version } disponible",
"system.updateStatus.security-upgrade": "Mise à jour { version } avec correctifs de sécurité disponible",
"system.updateStatus.unreleased": "Version non diffusée",
"system.updateStatus.up-to-date": "À jour",
"system.updateStatus.update": "Mise à jour gratuite { version } disponible",
"system.updateStatus.upgrade": "Mise à jour { version } disponible",
"title": "Titre", "title": "Titre",
"template": "Modèle", "template": "Modèle",
@ -558,6 +578,9 @@
"users": "Utilisateurs", "users": "Utilisateurs",
"version": "Version", "version": "Version",
"version.current": "Version actuelle",
"version.latest": "Dernière version",
"versionInformation": "Informations de version",
"view.account": "Votre compte", "view.account": "Votre compte",
"view.installation": "Installation", "view.installation": "Installation",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "Csak egyetlen blokk adható hozzá", "error.blocks.max.singular": "Csak egyetlen blokk adható hozzá",
"error.blocks.min.plural": "Legalább {min} blokkot hozzá kell adnod", "error.blocks.min.plural": "Legalább {min} blokkot hozzá kell adnod",
"error.blocks.min.singular": "Legalább egy blokkot hozzá kell adnod", "error.blocks.min.singular": "Legalább egy blokkot hozzá kell adnod",
"error.blocks.validation": "Hiba van az alábbi blokkban: {index}", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "A \"{name}\" email-beállítás nem található", "error.email.preset.notFound": "A \"{name}\" email-beállítás nem található",
@ -107,13 +107,15 @@
"error.language.name": "Kérlek, add meg a nyelv érvényes nevét", "error.language.name": "Kérlek, add meg a nyelv érvényes nevét",
"error.language.notFound": "A nyelv nem található", "error.language.notFound": "A nyelv nem található",
"error.layout.validation.block": "Hibát találtunk az alábbi blokkban: {blockIndex} az alábbi elrendezésben: {layoutIndex}", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "Hibát találtunk a(z) {index} elrendezés beállításaiban", "error.layout.validation.settings": "Hibát találtunk a(z) {index} elrendezés beállításaiban",
"error.license.format": "Kérlek, add meg az évényes lincensz kulcsot", "error.license.format": "Kérlek, add meg az évényes lincensz kulcsot",
"error.license.email": "Kérlek adj meg egy valós email-címet", "error.license.email": "Kérlek adj meg egy valós email-címet",
"error.license.verification": "A licensz nem ellenőrizhető", "error.license.verification": "A licensz nem ellenőrizhető",
"error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "A Panel jelenleg nem elérhető", "error.offline": "A Panel jelenleg nem elérhető",
"error.page.changeSlug.permission": "Nem változtathatod meg az URL-előtagot: \"{slug}\"", "error.page.changeSlug.permission": "Nem változtathatod meg az URL-előtagot: \"{slug}\"",
@ -282,9 +284,13 @@
"field.layout.empty": "Még nincsenek sorok", "field.layout.empty": "Még nincsenek sorok",
"field.layout.select": "Válassz elrendezést", "field.layout.select": "Válassz elrendezést",
"field.object.empty": "No information yet",
"field.pages.empty": "Nincs oldal kiválasztva", "field.pages.empty": "Nincs oldal kiválasztva",
"field.structure.delete.confirm": "Biztos t\u00f6r\u00f6lni szeretn\u00e9d ezt a bejegyz\u00e9st?", "field.structure.delete.confirm": "Biztos t\u00f6r\u00f6lni szeretn\u00e9d ezt a bejegyz\u00e9st?",
"field.structure.empty": "Nincs m\u00e9g bejegyz\u00e9s", "field.structure.empty": "Nincs m\u00e9g bejegyz\u00e9s",
"field.users.empty": "Nincs felhasználó kiválasztva", "field.users.empty": "Nincs felhasználó kiválasztva",
"file.blueprint": "Ehhez a fájlhoz még nem tartozik oldalsablon. Itt hozhatod létre: <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "Ehhez a fájlhoz még nem tartozik oldalsablon. Itt hozhatod létre: <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -448,6 +454,7 @@
"paste": "Beillesztés", "paste": "Beillesztés",
"paste.after": "Beillesztés utána", "paste.after": "Beillesztés utána",
"pixel": "Pixel", "pixel": "Pixel",
"plugin": "Plugin",
"plugins": "Pluginek", "plugins": "Pluginek",
"prev": "Előző", "prev": "Előző",
"preview": "Előnézet", "preview": "Előnézet",
@ -487,11 +494,24 @@
"stats.empty": "No reports", "stats.empty": "No reports",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "The content folder seems to be exposed",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.debug": "Debugging must be turned off in production",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.git": "The .git folder seems to be exposed",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.https": "We recommend HTTPS for all your sites",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.kirby": "The kirby folder seems to be exposed",
"system.issues.site": "The site folder seems to be exposed", "system.issues.site": "The site folder seems to be exposed",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Could not check for updates",
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
"system.updateStatus.security-update": "Free security update { version } available",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "Unreleased version",
"system.updateStatus.up-to-date": "Up to date",
"system.updateStatus.update": "Free update { version } available",
"system.updateStatus.upgrade": "Upgrade { version } available",
"title": "Cím", "title": "Cím",
"template": "Sablon", "template": "Sablon",
@ -558,6 +578,9 @@
"users": "Felhasználók", "users": "Felhasználók",
"version": "Kirby verzi\u00f3", "version": "Kirby verzi\u00f3",
"version.current": "Current version",
"version.latest": "Latest version",
"versionInformation": "Version information",
"view.account": "Fi\u00f3kod", "view.account": "Fi\u00f3kod",
"view.installation": "Telep\u00edt\u00e9s", "view.installation": "Telep\u00edt\u00e9s",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "Anda tidak boleh menambahkan lebih dari satu blok", "error.blocks.max.singular": "Anda tidak boleh menambahkan lebih dari satu blok",
"error.blocks.min.plural": "Anda setidaknya menambahkan {min} blok", "error.blocks.min.plural": "Anda setidaknya menambahkan {min} blok",
"error.blocks.min.singular": "Anda setidaknya menambahkan satu blok", "error.blocks.min.singular": "Anda setidaknya menambahkan satu blok",
"error.blocks.validation": "Ada kesalahan di blok {index}", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "Surel \"{name}\" tidak dapat ditemukan", "error.email.preset.notFound": "Surel \"{name}\" tidak dapat ditemukan",
@ -107,13 +107,15 @@
"error.language.name": "Masukkan nama bahasa yang valid", "error.language.name": "Masukkan nama bahasa yang valid",
"error.language.notFound": "The language could not be found", "error.language.notFound": "The language could not be found",
"error.layout.validation.block": "Ada kesalahan di blok {blockIndex} di tata letak {layoutIndex}", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "Ada kesalahan di pengaturan tata letak {index}", "error.layout.validation.settings": "Ada kesalahan di pengaturan tata letak {index}",
"error.license.format": "Masukkan kode lisensi yang valid", "error.license.format": "Masukkan kode lisensi yang valid",
"error.license.email": "Masukkan surel yang valid", "error.license.email": "Masukkan surel yang valid",
"error.license.verification": "Lisensi tidak dapat diverifikasi", "error.license.verification": "Lisensi tidak dapat diverifikasi",
"error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "The Panel is currently offline", "error.offline": "The Panel is currently offline",
"error.page.changeSlug.permission": "Anda tidak diizinkan mengubah akhiran URL untuk \"{slug}\"", "error.page.changeSlug.permission": "Anda tidak diizinkan mengubah akhiran URL untuk \"{slug}\"",
@ -282,9 +284,13 @@
"field.layout.empty": "Belum ada baris", "field.layout.empty": "Belum ada baris",
"field.layout.select": "Pilih tata letak", "field.layout.select": "Pilih tata letak",
"field.object.empty": "No information yet",
"field.pages.empty": "Belum ada halaman yang dipilih", "field.pages.empty": "Belum ada halaman yang dipilih",
"field.structure.delete.confirm": "Anda yakin menghapus baris ini?", "field.structure.delete.confirm": "Anda yakin menghapus baris ini?",
"field.structure.empty": "Belum ada entri", "field.structure.empty": "Belum ada entri",
"field.users.empty": "Belum ada pengguna yang dipilih", "field.users.empty": "Belum ada pengguna yang dipilih",
"file.blueprint": "This file has no blueprint yet. You can define the setup in <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "This file has no blueprint yet. You can define the setup in <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -448,6 +454,7 @@
"paste": "Paste", "paste": "Paste",
"paste.after": "Paste after", "paste.after": "Paste after",
"pixel": "Piksel", "pixel": "Piksel",
"plugin": "Plugin",
"plugins": "Plugins", "plugins": "Plugins",
"prev": "Sebelumnya", "prev": "Sebelumnya",
"preview": "Pratinjau", "preview": "Pratinjau",
@ -487,11 +494,24 @@
"stats.empty": "No reports", "stats.empty": "No reports",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "The content folder seems to be exposed",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.debug": "Debugging must be turned off in production",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.git": "The .git folder seems to be exposed",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.https": "We recommend HTTPS for all your sites",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.kirby": "The kirby folder seems to be exposed",
"system.issues.site": "The site folder seems to be exposed", "system.issues.site": "The site folder seems to be exposed",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Could not check for updates",
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
"system.updateStatus.security-update": "Free security update { version } available",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "Unreleased version",
"system.updateStatus.up-to-date": "Up to date",
"system.updateStatus.update": "Free update { version } available",
"system.updateStatus.upgrade": "Upgrade { version } available",
"title": "Judul", "title": "Judul",
"template": "Templat", "template": "Templat",
@ -558,6 +578,9 @@
"users": "Pengguna", "users": "Pengguna",
"version": "Versi", "version": "Versi",
"version.current": "Current version",
"version.latest": "Latest version",
"versionInformation": "Version information",
"view.account": "Akun Anda", "view.account": "Akun Anda",
"view.installation": "Pemasangan", "view.installation": "Pemasangan",

View file

@ -49,8 +49,8 @@
"email": "Netfang", "email": "Netfang",
"email.placeholder": "nafn@netfang.is", "email.placeholder": "nafn@netfang.is",
"entries": "Entries", "entries": "Færslur",
"entry": "Entry", "entry": "Færsla",
"environment": "Umhverfi", "environment": "Umhverfi",
@ -70,7 +70,7 @@
"error.blocks.max.singular": "Ekki meira en einn bálkur", "error.blocks.max.singular": "Ekki meira en einn bálkur",
"error.blocks.min.plural": "Minnst {min}. bálka", "error.blocks.min.plural": "Minnst {min}. bálka",
"error.blocks.min.singular": "Allavegana einn bálkur takk", "error.blocks.min.singular": "Allavegana einn bálkur takk",
"error.blocks.validation": "Það er villa í bálki númer {index}. Klikkaðu á bálkinn og finndu villuna. Það er væntanlega rauðlitur rammi utan um villuna.", "error.blocks.validation": "Það er villa í {field} sviðinu í bálkinum {index} sem notar {fieldset} bálkgerðina",
"error.email.preset.notFound": "Netfangstillingarnar: \"{name}\" fundust ekki", "error.email.preset.notFound": "Netfangstillingarnar: \"{name}\" fundust ekki",
@ -107,13 +107,15 @@
"error.language.name": "Gott og gyllt nafn fyrir tungumálið", "error.language.name": "Gott og gyllt nafn fyrir tungumálið",
"error.language.notFound": "Tungumálið fannst ekkert", "error.language.notFound": "Tungumálið fannst ekkert",
"error.layout.validation.block": "Það er villa í bálki {blockIndex} í rammanum {layoutIndex}", "error.layout.validation.block": "Það er villa í {field} sviðinu í bálkinum {blockIndex} sem notar {fieldset} bálkgerðina í rammanum {layoutIndex}",
"error.layout.validation.settings": "Hér er villa í sitllingum fyrir ramman {index}", "error.layout.validation.settings": "Hér er villa í sitllingum fyrir ramman {index}",
"error.license.format": "Gildur leyfiskóði hér", "error.license.format": "Gildur leyfiskóði hér",
"error.license.email": "Almennilegt netfang hér", "error.license.email": "Almennilegt netfang hér",
"error.license.verification": "Ekki heppnaðist að staðfesta leyfið", "error.license.verification": "Ekki heppnaðist að staðfesta leyfið",
"error.object.validation": "Það er villa í \"{label}\" sviðinu:\n{message}",
"error.offline": "Stjórnborðið er óvirkt eins og stendur.", "error.offline": "Stjórnborðið er óvirkt eins og stendur.",
"error.page.changeSlug.permission": "Þú hefur ekkert leyfi til þess að breyta slóðarforskeytinu fyrir \"{slug}\"", "error.page.changeSlug.permission": "Þú hefur ekkert leyfi til þess að breyta slóðarforskeytinu fyrir \"{slug}\"",
@ -282,9 +284,13 @@
"field.layout.empty": "Nei. Engir rammar enn.", "field.layout.empty": "Nei. Engir rammar enn.",
"field.layout.select": "Veldu rammategund", "field.layout.select": "Veldu rammategund",
"field.object.empty": "Engar upplýsingar enn",
"field.pages.empty": "Engar síður valdar ennþá", "field.pages.empty": "Engar síður valdar ennþá",
"field.structure.delete.confirm": "Viltu virkilega eyða þessari röð?", "field.structure.delete.confirm": "Viltu virkilega eyða þessari röð?",
"field.structure.empty": "Engar færslur enn", "field.structure.empty": "Engar færslur enn",
"field.users.empty": "Engir notendur valdir enn", "field.users.empty": "Engir notendur valdir enn",
"file.blueprint": "Þessi skrá hefur ekki skipan (e. blueprint) ennþá. Þú mátt skilgreina skipanina í <strong>/site/blueprints/{template}.yml</strong>", "file.blueprint": "Þessi skrá hefur ekki skipan (e. blueprint) ennþá. Þú mátt skilgreina skipanina í <strong>/site/blueprints/{template}.yml</strong>",
@ -297,7 +303,7 @@
"hide": "Fela", "hide": "Fela",
"hour": "Klukkustund", "hour": "Klukkustund",
"import": "Hlaða inn", "import": "Hlaða inn",
"info": "Info", "info": "Upplýsingar",
"insert": "Setja inn", "insert": "Setja inn",
"insert.after": "Setja eftir", "insert.after": "Setja eftir",
"insert.before": "Setja fyrir", "insert.before": "Setja fyrir",
@ -340,12 +346,12 @@
"license": "Leyfi", "license": "Leyfi",
"license.buy": "Kaupa leyfi", "license.buy": "Kaupa leyfi",
"license.register": "Skr\u00E1 Kirby", "license.register": "Skr\u00E1 Kirby",
"license.manage": "Manage your licenses", "license.manage": "Sýslaðu með leyfin þín",
"license.register.help": "Þú fékkst sendan tölvupóst með leyfiskóðanum þegar þú keyptir leyfi. Vinsamlegast afritaðu hann og settu hann hingað til að skrá þig.", "license.register.help": "Þú fékkst sendan tölvupóst með leyfiskóðanum þegar þú keyptir leyfi. Vinsamlegast afritaðu hann og settu hann hingað til að skrá þig.",
"license.register.label": "Vinsamlegast settu inn leyfiskóðan", "license.register.label": "Vinsamlegast settu inn leyfiskóðan",
"license.register.success": "Þakka þér fyrir að velja Kirby", "license.register.success": "Þakka þér fyrir að velja Kirby",
"license.unregistered": "Þetta er óskráð prufueintak af Kirby", "license.unregistered": "Þetta er óskráð prufueintak af Kirby",
"license.unregistered.label": "Unregistered", "license.unregistered.label": "Óskráð",
"link": "Tengill", "link": "Tengill",
"link.text": "Tengilstexti", "link.text": "Tengilstexti",
@ -365,9 +371,9 @@
"login.code.label.password-reset": "Kóði fyrir endurstillingu lykilorðs", "login.code.label.password-reset": "Kóði fyrir endurstillingu lykilorðs",
"login.code.placeholder.email": "000 000", "login.code.placeholder.email": "000 000",
"login.code.text.email": "Ef netfangið þitt er skráð þá bíður þín nýr tölvupóstur.", "login.code.text.email": "Ef netfangið þitt er skráð þá bíður þín nýr tölvupóstur.",
"login.email.login.body": "Já halló {user.nameOrEmail},\n\nNýlega baðstu um innskráningarkóða fyrir bakendan á sorli.is.\nEftirfarandi kóði er virkur í {timeout} mínútur:\n\n{code}\n\nEf þú óskaðir ekki eftir þessu þá hunsaðu þennan tölvupóst eða talaðu við vefstjóran ef þú vilt fræðast nánar.\nAf öryggisástæðum vinsamlegast áframsendu þennan tölvupóst ALLS EKKI.", "login.email.login.body": "Já halló {user.nameOrEmail},\n\nNýlega baðstu um innskráningarkóða fyrir bakendan á {site}.\nEftirfarandi kóði er virkur í {timeout} mínútur:\n\n{code}\n\nEf þú óskaðir ekki eftir þessu þá hunsaðu þennan tölvupóst eða talaðu við vefstjóran ef þú vilt fræðast nánar.\nAf öryggisástæðum vinsamlegast áframsendu þennan tölvupóst ALLS EKKI.",
"login.email.login.subject": "Innskráningarkóðinn þinn", "login.email.login.subject": "Innskráningarkóðinn þinn",
"login.email.password-reset.body": "Nei halló {user.nameOrEmail},\n\nNýverið baðstu um að lykilorði þínu væri endurstillt fyrir bakendan á sorli.is. \nEftirfarandi kóði er virkur í {timeout} mínútur:\n\n{code}\n\nEf þú óskaðir ekki eftir þessu þá hunsaðu þennan tölvupóst eða talaðu við vefstjóran ef þú vilt fræðast nánar.\nAf öryggisástæðum vinsamlegast áframsendu þennan tölvupóst ALLS EKKI.", "login.email.password-reset.body": "Nei halló {user.nameOrEmail},\n\nNýverið baðstu um að lykilorði þínu væri endurstillt fyrir bakendan á {site}. \nEftirfarandi kóði er virkur í {timeout} mínútur:\n\n{code}\n\nEf þú óskaðir ekki eftir þessu þá hunsaðu þennan tölvupóst eða talaðu við vefstjóran ef þú vilt fræðast nánar.\nAf öryggisástæðum vinsamlegast áframsendu þennan tölvupóst ALLS EKKI.",
"login.email.password-reset.subject": "Kóðinn þinn fyrir endurstillingu lykilorðs", "login.email.password-reset.subject": "Kóðinn þinn fyrir endurstillingu lykilorðs",
"login.remember": "Vista innskráningu", "login.remember": "Vista innskráningu",
"login.reset": "Endurheimta lykilorð takk", "login.reset": "Endurheimta lykilorð takk",
@ -430,11 +436,11 @@
"page.sort": "Breyta röðun", "page.sort": "Breyta röðun",
"page.status": "Staða", "page.status": "Staða",
"page.status.draft": "Uppkast", "page.status.draft": "Uppkast",
"page.status.draft.description": "Þessi síða er uppkast og er aðeins sýnileg höfundum og stjórum eða gegnum falinn tengil.", "page.status.draft.description": "Þessi síða er uppkast og er aðeins sýnileg vefstjórum eða gegnum laumu tengil.",
"page.status.listed": "Útgefin og listuð", "page.status.listed": "Útgefin og listuð",
"page.status.listed.description": "Síðan er aðgengileg öllum og sýnleg í leiðarkerfi vefsins", "page.status.listed.description": "Síðan er útgefin og listuð.",
"page.status.unlisted": "Útgefin", "page.status.unlisted": "Útgefin",
"page.status.unlisted.description": "Síðan er aðgengileg öllum en þó ekki sýnileg í leiðarkerfi vefsins", "page.status.unlisted.description": "Síðan er útgefin en þó ólistuð.",
"pages": "Síður", "pages": "Síður",
"pages.empty": "Engar síður enn", "pages.empty": "Engar síður enn",
@ -448,6 +454,7 @@
"paste": "Líma", "paste": "Líma",
"paste.after": "Líma eftir", "paste.after": "Líma eftir",
"pixel": "Punkta", "pixel": "Punkta",
"plugin": "Viðbót",
"plugins": "Viðbætur", "plugins": "Viðbætur",
"prev": "Fyrri", "prev": "Fyrri",
"preview": "Forskoða", "preview": "Forskoða",
@ -475,7 +482,7 @@
"section.required": "Þetta svæði er nauðsynlegt", "section.required": "Þetta svæði er nauðsynlegt",
"security": "Security", "security": "Öryggi",
"select": "Velja", "select": "Velja",
"server": "Vefþjónn", "server": "Vefþjónn",
"settings": "Stillingar", "settings": "Stillingar",
@ -485,13 +492,26 @@
"slug": "Slögg", "slug": "Slögg",
"sort": "Raða", "sort": "Raða",
"stats.empty": "No reports", "stats.empty": "Engar skýrslur",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "Efnismappan virðist vera berskjölduð",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.eol.kirby": "Uppsett Kirby eintak þitt hefur runnið sitt skeið á enda og mun ekki verða uppfært framar",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.eol.plugin": "Uppsett eintak þitt af viðbótinni { plugin } hefur runnið sitt skeið á enda og mun ekki verða uppfærð framar",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.debug": "Aflúsun ætti alltaf að vera óvrikt í útgefnum vef",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.git": ".git mappan virðist vera berskjölduð",
"system.issues.site": "The site folder seems to be exposed", "system.issues.https": "Við mælum harðlega með því að þú notir HTTPS fyrir öll þín vefsvæði",
"system.issues.kirby": "Kirby mappan virðist vera berskjölduð",
"system.issues.site": "Mappa vefsvæðisins virðist vera berskjölduð",
"system.issues.vulnerability.kirby": "Uppsetningin þín gæti verið berskjölduð gagnvart eftirfarandi veikleika: ({ severity } veikleikinn): { description }",
"system.issues.vulnerability.plugin": "Uppsetningin þín gæti verið berskjölduð gagnvart eftirfarandi veikleika í viðbótinni { plugin }: ({ severity } veikleikinn): { description }",
"system.updateStatus": "Uppfærslustaða",
"system.updateStatus.error": "Gat því miður ekki athugað með uppfærslur",
"system.updateStatus.not-vulnerable": "Engir þekktir veikleikar",
"system.updateStatus.security-update": "Ókeypis öryggisuppfærsla { version } fáanleg",
"system.updateStatus.security-upgrade": "Uppfærsla { version } með öryggisuppfærslum fáanleg",
"system.updateStatus.unreleased": "Óútgefin útgáfa",
"system.updateStatus.up-to-date": "Allt spikk og span",
"system.updateStatus.update": "Ókeypis uppfærsla { version } fáanleg",
"system.updateStatus.upgrade": "Uppfærsla fyrir { version } fáanleg",
"title": "Titill", "title": "Titill",
"template": "Sniðmát", "template": "Sniðmát",
@ -558,6 +578,9 @@
"users": "Notendur", "users": "Notendur",
"version": "Útgáfa", "version": "Útgáfa",
"version.current": "Núverandi útgáfa",
"version.latest": "Nýjasta útgáfa",
"versionInformation": "Útgáfuupplýsingar",
"view.account": "Notandareikningurinn þinn", "view.account": "Notandareikningurinn þinn",
"view.installation": "Uppsetning", "view.installation": "Uppsetning",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "Non puoi aggiungere più di un blocco", "error.blocks.max.singular": "Non puoi aggiungere più di un blocco",
"error.blocks.min.plural": "Devi aggiungere almeno {min} blocchi", "error.blocks.min.plural": "Devi aggiungere almeno {min} blocchi",
"error.blocks.min.singular": "Devi aggiungere almeno un blocco", "error.blocks.min.singular": "Devi aggiungere almeno un blocco",
"error.blocks.validation": "C'è un errore nel blocco {index}", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "Non è stato possibile trovare il preset email \"{name}\"", "error.email.preset.notFound": "Non è stato possibile trovare il preset email \"{name}\"",
@ -107,13 +107,15 @@
"error.language.name": "Inserisci un nome valido per la lingua", "error.language.name": "Inserisci un nome valido per la lingua",
"error.language.notFound": "La lingua non è stata trovata", "error.language.notFound": "La lingua non è stata trovata",
"error.layout.validation.block": "C'è un errore nel blocco {blockIndex} nel layout {layoutIndex}", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "C'è un errore nelle impostazioni del layout {index}", "error.layout.validation.settings": "C'è un errore nelle impostazioni del layout {index}",
"error.license.format": "Inserisci un codice di licenza valido", "error.license.format": "Inserisci un codice di licenza valido",
"error.license.email": "Inserisci un indirizzo email valido", "error.license.email": "Inserisci un indirizzo email valido",
"error.license.verification": "Non è stato possibile verificare la licenza", "error.license.verification": "Non è stato possibile verificare la licenza",
"error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "Il pannello di controllo è attualmente offline", "error.offline": "Il pannello di controllo è attualmente offline",
"error.page.changeSlug.permission": "Non ti è permesso cambiare l'URL di \"{slug}\"", "error.page.changeSlug.permission": "Non ti è permesso cambiare l'URL di \"{slug}\"",
@ -282,9 +284,13 @@
"field.layout.empty": "Nessuna riga inserita", "field.layout.empty": "Nessuna riga inserita",
"field.layout.select": "Scegli un layout", "field.layout.select": "Scegli un layout",
"field.object.empty": "No information yet",
"field.pages.empty": "Nessuna pagina selezionata", "field.pages.empty": "Nessuna pagina selezionata",
"field.structure.delete.confirm": "Vuoi veramente eliminare questo elemento?", "field.structure.delete.confirm": "Vuoi veramente eliminare questo elemento?",
"field.structure.empty": "Non ci sono ancora elementi.", "field.structure.empty": "Non ci sono ancora elementi.",
"field.users.empty": "Nessun utente selezionato", "field.users.empty": "Nessun utente selezionato",
"file.blueprint": "Questo file non ha ancora un blueprint. Puoi definire la sua configurazione in <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "Questo file non ha ancora un blueprint. Puoi definire la sua configurazione in <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -448,6 +454,7 @@
"paste": "Incolla", "paste": "Incolla",
"paste.after": "Incolla dopo", "paste.after": "Incolla dopo",
"pixel": "Pixel", "pixel": "Pixel",
"plugin": "Plugin",
"plugins": "Plugins", "plugins": "Plugins",
"prev": "Precedente", "prev": "Precedente",
"preview": "Anteprima", "preview": "Anteprima",
@ -487,11 +494,24 @@
"stats.empty": "No reports", "stats.empty": "No reports",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "The content folder seems to be exposed",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.debug": "Debugging must be turned off in production",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.git": "The .git folder seems to be exposed",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.https": "We recommend HTTPS for all your sites",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.kirby": "The kirby folder seems to be exposed",
"system.issues.site": "The site folder seems to be exposed", "system.issues.site": "The site folder seems to be exposed",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Could not check for updates",
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
"system.updateStatus.security-update": "Free security update { version } available",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "Unreleased version",
"system.updateStatus.up-to-date": "Up to date",
"system.updateStatus.update": "Free update { version } available",
"system.updateStatus.upgrade": "Upgrade { version } available",
"title": "Titolo", "title": "Titolo",
"template": "Template", "template": "Template",
@ -558,6 +578,9 @@
"users": "Utenti", "users": "Utenti",
"version": "Versione di Kirby", "version": "Versione di Kirby",
"version.current": "Current version",
"version.latest": "Latest version",
"versionInformation": "Version information",
"view.account": "Il tuo account", "view.account": "Il tuo account",
"view.installation": "Installazione", "view.installation": "Installazione",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "블록을 하나 이상 추가할 수 없습니다.", "error.blocks.max.singular": "블록을 하나 이상 추가할 수 없습니다.",
"error.blocks.min.plural": "블록을 {min}개 이상 추가하세요.", "error.blocks.min.plural": "블록을 {min}개 이상 추가하세요.",
"error.blocks.min.singular": "블록을 하나 이상 추가하세요.", "error.blocks.min.singular": "블록을 하나 이상 추가하세요.",
"error.blocks.validation": "블록({index})이 올바르지 않습니다.", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "기본 이메일 주소({name})가 없습니다.", "error.email.preset.notFound": "기본 이메일 주소({name})가 없습니다.",
@ -107,13 +107,15 @@
"error.language.name": "올바른 언어명을 입력하세요.", "error.language.name": "올바른 언어명을 입력하세요.",
"error.language.notFound": "언어를 찾을 수 없습니다.", "error.language.notFound": "언어를 찾을 수 없습니다.",
"error.layout.validation.block": "레이아웃({layoutIndex})의 블록({blockIndex})을 확인하세요.", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "레이아웃({index})의 옵션을 확인하세요.", "error.layout.validation.settings": "레이아웃({index})의 옵션을 확인하세요.",
"error.license.format": "올바른 라이선스 키를 입력하세요.", "error.license.format": "올바른 라이선스 키를 입력하세요.",
"error.license.email": "올바른 이메일 주소를 입력하세요.", "error.license.email": "올바른 이메일 주소를 입력하세요.",
"error.license.verification": "라이선스 키가 올바르지 않습니다.", "error.license.verification": "라이선스 키가 올바르지 않습니다.",
"error.object.validation": "{label} 필드에 오류가 있습니다.\n{message}",
"error.offline": "패널이 오프라인 상태입니다.", "error.offline": "패널이 오프라인 상태입니다.",
"error.page.changeSlug.permission": "고유 주소({slug})를 변경할 권한이 없습니다.", "error.page.changeSlug.permission": "고유 주소({slug})를 변경할 권한이 없습니다.",
@ -282,9 +284,13 @@
"field.layout.empty": "행이 없습니다.", "field.layout.empty": "행이 없습니다.",
"field.layout.select": "레이아웃 선택", "field.layout.select": "레이아웃 선택",
"field.object.empty": "정보가 없습니다.",
"field.pages.empty": "선택한 페이지가 없습니다.", "field.pages.empty": "선택한 페이지가 없습니다.",
"field.structure.delete.confirm": "이 항목을 삭제할까요?", "field.structure.delete.confirm": "이 항목을 삭제할까요?",
"field.structure.empty": "항목이 없습니다.", "field.structure.empty": "항목이 없습니다.",
"field.users.empty": "선택한 사용자가 없습니다.", "field.users.empty": "선택한 사용자가 없습니다.",
"file.blueprint": "블루프린트(<strong>/site/blueprints/files/{blueprint}.yml</strong>)를 설정하세요.", "file.blueprint": "블루프린트(<strong>/site/blueprints/files/{blueprint}.yml</strong>)를 설정하세요.",
@ -448,6 +454,7 @@
"paste": "붙여넣기", "paste": "붙여넣기",
"paste.after": "뒤로 붙여넣기", "paste.after": "뒤로 붙여넣기",
"pixel": "픽셀", "pixel": "픽셀",
"plugin": "플러그인",
"plugins": "플러그인", "plugins": "플러그인",
"prev": "이전", "prev": "이전",
"preview": "미리 보기", "preview": "미리 보기",
@ -487,11 +494,24 @@
"stats.empty": "관련 기록이 없습니다.", "stats.empty": "관련 기록이 없습니다.",
"system.issues.content": "<code>/content</code> 폴더의 권한을 확인하세요.", "system.issues.content": "<code>/content</code> 폴더의 권한을 확인하세요.",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "공개 서버상에서는 디버그 모드를 해제하세요.", "system.issues.debug": "공개 서버상에서는 디버그 모드를 해제하세요.",
"system.issues.git": "<code>/.git</code> 폴더의 권한을 확인하세요.", "system.issues.git": "<code>/.git</code> 폴더의 권한을 확인하세요.",
"system.issues.https": "HTTPS를 권장합니다.", "system.issues.https": "HTTPS를 권장합니다.",
"system.issues.kirby": "<code>/kirby</code> 폴더의 권한을 확인하세요.", "system.issues.kirby": "<code>/kirby</code> 폴더의 권한을 확인하세요.",
"system.issues.site": "<code>/site</code> 폴더의 권한을 확인하세요.", "system.issues.site": "<code>/site</code> 폴더의 권한을 확인하세요.",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "업데이트 상태",
"system.updateStatus.error": "업데이트를 확인할 수 없습니다.",
"system.updateStatus.not-vulnerable": "알려진 취약성이 없습니다.",
"system.updateStatus.security-update": "Free security update { version } available",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "출시 전 버전",
"system.updateStatus.up-to-date": "최신 버전입니다.",
"system.updateStatus.update": "{ version } 버전으로 무료 업데이트",
"system.updateStatus.upgrade": "{ version } 버전으로 업그레이드",
"title": "제목", "title": "제목",
"template": "\ud15c\ud50c\ub9bf", "template": "\ud15c\ud50c\ub9bf",
@ -558,6 +578,9 @@
"users": "사용자", "users": "사용자",
"version": "버전", "version": "버전",
"version.current": "현재 버전",
"version.latest": "최신 버전",
"versionInformation": "버전 정보",
"view.account": "계정", "view.account": "계정",
"view.installation": "\uc124\uce58", "view.installation": "\uc124\uce58",

View file

@ -1,10 +1,10 @@
{ {
"account.changeName": "Change your name", "account.changeName": "Pakeisti savo vardą",
"account.delete": "Delete your account", "account.delete": "Panaikinti savo paskyrą",
"account.delete.confirm": "Do you really want to delete your account? You will be logged out immediately. Your account cannot be recovered.", "account.delete.confirm": "Ar tikrai norite panaikinti savo paskyrą? Jūs iš karto atsijungsite. Paskyros bus neįmanoma atstatyti.",
"add": "Pridėti", "add": "Pridėti",
"author": "Author", "author": "Autorius",
"avatar": "Profilio nuotrauka", "avatar": "Profilio nuotrauka",
"back": "Atgal", "back": "Atgal",
"cancel": "Atšaukti", "cancel": "Atšaukti",
@ -49,10 +49,10 @@
"email": "El. paštas", "email": "El. paštas",
"email.placeholder": "mail@example.com", "email.placeholder": "mail@example.com",
"entries": "Entries", "entries": "Įrašai",
"entry": "Entry", "entry": "Įrašas",
"environment": "Environment", "environment": "Aplinka",
"error.access.code": "Neteisinas kodas", "error.access.code": "Neteisinas kodas",
"error.access.login": "Neteisingas prisijungimo vardas", "error.access.login": "Neteisingas prisijungimo vardas",
@ -70,7 +70,7 @@
"error.blocks.max.singular": "Jūs galite pridėti daugiausiai vieną bloką", "error.blocks.max.singular": "Jūs galite pridėti daugiausiai vieną bloką",
"error.blocks.min.plural": "Minimalus blokų kiekis: {min}", "error.blocks.min.plural": "Minimalus blokų kiekis: {min}",
"error.blocks.min.singular": "Jūs turite pridėti bent vieną bloką", "error.blocks.min.singular": "Jūs turite pridėti bent vieną bloką",
"error.blocks.validation": "Bloke {index} yra klaida", "error.blocks.validation": "Yra klaida laukelyje \"{field}\" bloke {index} naudojant bloko tipą \"{fieldset}\"",
"error.email.preset.notFound": "El. pašto paruoštukas \"{name}\" nerastas", "error.email.preset.notFound": "El. pašto paruoštukas \"{name}\" nerastas",
@ -107,14 +107,16 @@
"error.language.name": "Prašome įrašyti teisingą kalbos pavadinimą", "error.language.name": "Prašome įrašyti teisingą kalbos pavadinimą",
"error.language.notFound": "Nepavyko rasti šios kalbos", "error.language.notFound": "Nepavyko rasti šios kalbos",
"error.layout.validation.block": "Yra klaida bloke {blockIndex} išdėstyme {layoutIndex}", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "Yra klaida išdėstymo {index} nustatymuose", "error.layout.validation.settings": "Yra klaida išdėstymo {index} nustatymuose",
"error.license.format": "Prašome įrašyti teisingą licenzijos kodą", "error.license.format": "Prašome įrašyti teisingą licenzijos kodą",
"error.license.email": "Prašome įrašyti teisingą el. pašto adresą", "error.license.email": "Prašome įrašyti teisingą el. pašto adresą",
"error.license.verification": "Nepavyko patikrinti licenzijos", "error.license.verification": "Nepavyko patikrinti licenzijos",
"error.offline": "The Panel is currently offline", "error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "Valdymo pultas dabar yra offline",
"error.page.changeSlug.permission": "Neturite teisės pakeisti \"{slug}\" URL", "error.page.changeSlug.permission": "Neturite teisės pakeisti \"{slug}\" URL",
"error.page.changeStatus.incomplete": "Puslapis turi klaidų ir negali būti paskelbtas", "error.page.changeStatus.incomplete": "Puslapis turi klaidų ir negali būti paskelbtas",
@ -282,9 +284,13 @@
"field.layout.empty": "Dar nėra eilučių", "field.layout.empty": "Dar nėra eilučių",
"field.layout.select": "Pasirinkite išdėstymą", "field.layout.select": "Pasirinkite išdėstymą",
"field.object.empty": "Dar nėra informacijos",
"field.pages.empty": "Dar nėra puslapių", "field.pages.empty": "Dar nėra puslapių",
"field.structure.delete.confirm": "Ar tikrai norite pašalinti šią eilutę?", "field.structure.delete.confirm": "Ar tikrai norite pašalinti šią eilutę?",
"field.structure.empty": "Dar nėra įrašų", "field.structure.empty": "Dar nėra įrašų",
"field.users.empty": "Dar nėra vartotojų", "field.users.empty": "Dar nėra vartotojų",
"file.blueprint": "Šis failas dar neturi blueprint. Galite nustatyti jį per <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "Šis failas dar neturi blueprint. Galite nustatyti jį per <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -340,12 +346,12 @@
"license": "Licenzija", "license": "Licenzija",
"license.buy": "Pirkti licenziją", "license.buy": "Pirkti licenziją",
"license.register": "Registruoti", "license.register": "Registruoti",
"license.manage": "Manage your licenses", "license.manage": "Valdyti savo licencijas",
"license.register.help": "Licenzijos kodą gavote el. paštu po apmokėjimo. Prašome įterpti čia, kad sistema būtų užregistruota.", "license.register.help": "Licenzijos kodą gavote el. paštu po apmokėjimo. Prašome įterpti čia, kad sistema būtų užregistruota.",
"license.register.label": "Prašome įrašyti jūsų licenzijos kodą", "license.register.label": "Prašome įrašyti jūsų licenzijos kodą",
"license.register.success": "Ačiū, kad palaikote Kirby", "license.register.success": "Ačiū, kad palaikote Kirby",
"license.unregistered": "Tai neregistruota Kirby demo versija", "license.unregistered": "Tai neregistruota Kirby demo versija",
"license.unregistered.label": "Unregistered", "license.unregistered.label": "Neregistruota",
"link": "Nuoroda", "link": "Nuoroda",
"link.text": "Nuorodos tekstas", "link.text": "Nuorodos tekstas",
@ -448,7 +454,8 @@
"paste": "Įterpti", "paste": "Įterpti",
"paste.after": "Įterpti po", "paste.after": "Įterpti po",
"pixel": "Pikselis", "pixel": "Pikselis",
"plugins": "Plugins", "plugin": "Įskiepas",
"plugins": "Įskiepai",
"prev": "Ankstesnis", "prev": "Ankstesnis",
"preview": "Peržiūra", "preview": "Peržiūra",
"remove": "Pašalinti", "remove": "Pašalinti",
@ -475,9 +482,9 @@
"section.required": "Sekcija privaloma", "section.required": "Sekcija privaloma",
"security": "Security", "security": "Saugumas",
"select": "Pasirinkti", "select": "Pasirinkti",
"server": "Server", "server": "Serveris",
"settings": "Nustatymai", "settings": "Nustatymai",
"show": "Rodyti", "show": "Rodyti",
"site.blueprint": "Svetainė neturi blueprint. Jūs galite nustatyti jį <strong>/site/blueprints/site.yml</strong>", "site.blueprint": "Svetainė neturi blueprint. Jūs galite nustatyti jį <strong>/site/blueprints/site.yml</strong>",
@ -485,13 +492,26 @@
"slug": "URL pabaiga", "slug": "URL pabaiga",
"sort": "Rikiuoti", "sort": "Rikiuoti",
"stats.empty": "No reports", "stats.empty": "Nėra pranešimų",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "The content folder seems to be exposed",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.debug": "Debugging must be turned off in production",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.git": "The .git folder seems to be exposed",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.https": "We recommend HTTPS for all your sites",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.kirby": "The kirby folder seems to be exposed",
"system.issues.site": "The site folder seems to be exposed", "system.issues.site": "The site folder seems to be exposed",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Atnaujinimų statusas",
"system.updateStatus.error": "Nepavyko patikrinti atnaujinimų",
"system.updateStatus.not-vulnerable": "Nėra žinomų saugumo spragų",
"system.updateStatus.security-update": "Prieinamas nemokamas saugumo atnaujinimas { version }",
"system.updateStatus.security-upgrade": "Prieinama nauja { version } versija su saugumo atnaujinimais",
"system.updateStatus.unreleased": "Neišleista versija",
"system.updateStatus.up-to-date": "Naujausia versija",
"system.updateStatus.update": "Prieinamas nemokamas atnaujinimas { version }",
"system.updateStatus.upgrade": "Prieinamas atnaujinimas { version }",
"title": "Pavadinimas", "title": "Pavadinimas",
"template": "Puslapio šablonas", "template": "Puslapio šablonas",
@ -558,13 +578,16 @@
"users": "Vartotojai", "users": "Vartotojai",
"version": "Versija", "version": "Versija",
"version.current": "Dabartinė versija",
"version.latest": "Naujausia versija",
"versionInformation": "Versijos informacija",
"view.account": "Jūsų paskyra", "view.account": "Jūsų paskyra",
"view.installation": "Installation", "view.installation": "Installation",
"view.languages": "Kalbos", "view.languages": "Kalbos",
"view.resetPassword": "Sukurti naują slaptažodį", "view.resetPassword": "Sukurti naują slaptažodį",
"view.site": "Svetainė", "view.site": "Svetainė",
"view.system": "System", "view.system": "Sistema",
"view.users": "Vartotojai", "view.users": "Vartotojai",
"welcome": "Sveiki", "welcome": "Sveiki",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "Du kan ikke legge til mer enn en blokk", "error.blocks.max.singular": "Du kan ikke legge til mer enn en blokk",
"error.blocks.min.plural": "Du må legge til minst {min} blokker", "error.blocks.min.plural": "Du må legge til minst {min} blokker",
"error.blocks.min.singular": "Du må legge til minst en blokk", "error.blocks.min.singular": "Du må legge til minst en blokk",
"error.blocks.validation": "Det er en feil i blokken {index}", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "E-postinnstillingen \"{name}\" ble ikke funnet", "error.email.preset.notFound": "E-postinnstillingen \"{name}\" ble ikke funnet",
@ -107,13 +107,15 @@
"error.language.name": "Vennligst skriv inn et gyldig navn for språket", "error.language.name": "Vennligst skriv inn et gyldig navn for språket",
"error.language.notFound": "Finner ikke språket", "error.language.notFound": "Finner ikke språket",
"error.layout.validation.block": "Det er en feil i blokk {blockIndex} i layout {layoutIndex}", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "Det er en feil i layout {index} innstillinger", "error.layout.validation.settings": "Det er en feil i layout {index} innstillinger",
"error.license.format": "Vennligst skriv inn gyldig lisensnøkkel", "error.license.format": "Vennligst skriv inn gyldig lisensnøkkel",
"error.license.email": "Vennligst skriv inn en gyldig e-postadresse", "error.license.email": "Vennligst skriv inn en gyldig e-postadresse",
"error.license.verification": "Lisensen kunne ikke verifiseres", "error.license.verification": "Lisensen kunne ikke verifiseres",
"error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "Panelet er i øyeblikket offline", "error.offline": "Panelet er i øyeblikket offline",
"error.page.changeSlug.permission": "Du kan ikke endre URLen for denne siden", "error.page.changeSlug.permission": "Du kan ikke endre URLen for denne siden",
@ -282,9 +284,13 @@
"field.layout.empty": "Ingen rader enda", "field.layout.empty": "Ingen rader enda",
"field.layout.select": "Velg en layout", "field.layout.select": "Velg en layout",
"field.object.empty": "No information yet",
"field.pages.empty": "Ingen side har blitt valgt", "field.pages.empty": "Ingen side har blitt valgt",
"field.structure.delete.confirm": "\u00d8nsker du virkelig \u00e5 slette denne oppf\u00f8ringen?", "field.structure.delete.confirm": "\u00d8nsker du virkelig \u00e5 slette denne oppf\u00f8ringen?",
"field.structure.empty": "Ingen oppf\u00f8ringer enda", "field.structure.empty": "Ingen oppf\u00f8ringer enda",
"field.users.empty": "Ingen bruker har blitt valgt", "field.users.empty": "Ingen bruker har blitt valgt",
"file.blueprint": "Denne filen har ikke en blueprint enda. Du kan definere oppsettet i <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "Denne filen har ikke en blueprint enda. Du kan definere oppsettet i <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -448,6 +454,7 @@
"paste": "Lim inn", "paste": "Lim inn",
"paste.after": "Lim inn etter", "paste.after": "Lim inn etter",
"pixel": "Piksel", "pixel": "Piksel",
"plugin": "Plugin",
"plugins": "Plugins", "plugins": "Plugins",
"prev": "Forrige", "prev": "Forrige",
"preview": "Forhåndsvisning", "preview": "Forhåndsvisning",
@ -487,11 +494,24 @@
"stats.empty": "No reports", "stats.empty": "No reports",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "The content folder seems to be exposed",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.debug": "Debugging must be turned off in production",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.git": "The .git folder seems to be exposed",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.https": "We recommend HTTPS for all your sites",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.kirby": "The kirby folder seems to be exposed",
"system.issues.site": "The site folder seems to be exposed", "system.issues.site": "The site folder seems to be exposed",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Could not check for updates",
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
"system.updateStatus.security-update": "Free security update { version } available",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "Unreleased version",
"system.updateStatus.up-to-date": "Up to date",
"system.updateStatus.update": "Free update { version } available",
"system.updateStatus.upgrade": "Upgrade { version } available",
"title": "Tittel", "title": "Tittel",
"template": "Mal", "template": "Mal",
@ -558,6 +578,9 @@
"users": "Brukere", "users": "Brukere",
"version": "Kirby versjon", "version": "Kirby versjon",
"version.current": "Current version",
"version.latest": "Latest version",
"versionInformation": "Version information",
"view.account": "Din konto", "view.account": "Din konto",
"view.installation": "Installasjon", "view.installation": "Installasjon",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "Je kunt niet meer dan één blok toevoegen", "error.blocks.max.singular": "Je kunt niet meer dan één blok toevoegen",
"error.blocks.min.plural": "Je moet ten minste {min} blok toevoegen", "error.blocks.min.plural": "Je moet ten minste {min} blok toevoegen",
"error.blocks.min.singular": "Je moet ten minste één blok toevoegen", "error.blocks.min.singular": "Je moet ten minste één blok toevoegen",
"error.blocks.validation": "Er is een fout gevonden in blok {index}", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "De e-mailvoorinstelling \"{name}\" kan niet worden gevonden", "error.email.preset.notFound": "De e-mailvoorinstelling \"{name}\" kan niet worden gevonden",
@ -107,13 +107,15 @@
"error.language.name": "Vul een geldige naam voor deze taal in", "error.language.name": "Vul een geldige naam voor deze taal in",
"error.language.notFound": "De taal kan niet worden gevonden", "error.language.notFound": "De taal kan niet worden gevonden",
"error.layout.validation.block": "Er is een fout gevonden in blok {blockIndex} in ontwerp {layoutIndex}", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "Er is een fout gevonden in de instellingen van ontwerp {index} ", "error.layout.validation.settings": "Er is een fout gevonden in de instellingen van ontwerp {index} ",
"error.license.format": "Vul een gelidge licentie-key in", "error.license.format": "Vul een gelidge licentie-key in",
"error.license.email": "Gelieve een geldig emailadres in te voeren", "error.license.email": "Gelieve een geldig emailadres in te voeren",
"error.license.verification": "De licentie kon niet worden geverifieerd. ", "error.license.verification": "De licentie kon niet worden geverifieerd. ",
"error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "Het Panel is momenteel offline", "error.offline": "Het Panel is momenteel offline",
"error.page.changeSlug.permission": "Je kunt de URL van deze pagina niet wijzigen", "error.page.changeSlug.permission": "Je kunt de URL van deze pagina niet wijzigen",
@ -282,9 +284,13 @@
"field.layout.empty": "Er zijn nog geen rijen", "field.layout.empty": "Er zijn nog geen rijen",
"field.layout.select": "Selecteer een indeling", "field.layout.select": "Selecteer een indeling",
"field.object.empty": "Nog geen informatie",
"field.pages.empty": "Nog geen pagina's geselecteerd", "field.pages.empty": "Nog geen pagina's geselecteerd",
"field.structure.delete.confirm": "Wil je deze entry verwijderen?", "field.structure.delete.confirm": "Wil je deze entry verwijderen?",
"field.structure.empty": "Nog geen items.", "field.structure.empty": "Nog geen items.",
"field.users.empty": "Nog geen gebruikers geselecteerd", "field.users.empty": "Nog geen gebruikers geselecteerd",
"file.blueprint": "Dit bestand heeft nog geen blauwdruk. U kunt de instellingen definiëren in <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "Dit bestand heeft nog geen blauwdruk. U kunt de instellingen definiëren in <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -340,7 +346,7 @@
"license": "Licentie", "license": "Licentie",
"license.buy": "Koop een licentie", "license.buy": "Koop een licentie",
"license.register": "Registreren", "license.register": "Registreren",
"license.manage": "Manage your licenses", "license.manage": "Beheer je licenties",
"license.register.help": "Je hebt de licentie via e-mail gekregen nadat je de aankoop hebt gedaan. Kopieer en plak de licentie om te registreren. ", "license.register.help": "Je hebt de licentie via e-mail gekregen nadat je de aankoop hebt gedaan. Kopieer en plak de licentie om te registreren. ",
"license.register.label": "Vul je licentie in", "license.register.label": "Vul je licentie in",
"license.register.success": "Bedankt dat je Kirby ondersteunt", "license.register.success": "Bedankt dat je Kirby ondersteunt",
@ -448,6 +454,7 @@
"paste": "Plak", "paste": "Plak",
"paste.after": "Plak achter", "paste.after": "Plak achter",
"pixel": "Pixel", "pixel": "Pixel",
"plugin": "Plugin",
"plugins": "Plugins", "plugins": "Plugins",
"prev": "Vorige", "prev": "Vorige",
"preview": "Voorbeeld", "preview": "Voorbeeld",
@ -475,7 +482,7 @@
"section.required": "De sectie is verplicht", "section.required": "De sectie is verplicht",
"security": "Security", "security": "Beveiliging",
"select": "Selecteren", "select": "Selecteren",
"server": "Server", "server": "Server",
"settings": "Opties", "settings": "Opties",
@ -487,11 +494,24 @@
"stats.empty": "No reports", "stats.empty": "No reports",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "The content folder seems to be exposed",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.debug": "Debugging must be turned off in production",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.git": "De .git map lijkt zichtbaar te zijn",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.https": "We raden HTTPS aan voor al je sites",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.kirby": "The kirby folder seems to be exposed",
"system.issues.site": "The site folder seems to be exposed", "system.issues.site": "The site folder seems to be exposed",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Could not check for updates",
"system.updateStatus.not-vulnerable": "Geen gekende kwetsbaarheden",
"system.updateStatus.security-update": "Gratis veiligheids update { version } beschikbaar",
"system.updateStatus.security-upgrade": "Upgrade { version } met veiligheid aanpassingen beschikbaar",
"system.updateStatus.unreleased": "Niet vrijgegeven versie",
"system.updateStatus.up-to-date": "Up to date",
"system.updateStatus.update": "Gratis update { version } beschikbaar",
"system.updateStatus.upgrade": "Upgrade { version } beschikbaar",
"title": "Titel", "title": "Titel",
"template": "Template", "template": "Template",
@ -558,6 +578,9 @@
"users": "Gebruikers", "users": "Gebruikers",
"version": "Kirby-versie", "version": "Kirby-versie",
"version.current": "Huidige versie",
"version.latest": "Laatste versie",
"versionInformation": "Versie informatie",
"view.account": "Jouw account", "view.account": "Jouw account",
"view.installation": "Installatie", "view.installation": "Installatie",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "Możesz dodać tylko jeden blok", "error.blocks.max.singular": "Możesz dodać tylko jeden blok",
"error.blocks.min.plural": "Musisz dodać co najmniej {min} bloki/-ów", "error.blocks.min.plural": "Musisz dodać co najmniej {min} bloki/-ów",
"error.blocks.min.singular": "Musisz dodać co najmniej jeden blok", "error.blocks.min.singular": "Musisz dodać co najmniej jeden blok",
"error.blocks.validation": "W bloku {index} jest błąd", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "Nie udało się załadować wzorca wiadomości e-mail \"{name}\"", "error.email.preset.notFound": "Nie udało się załadować wzorca wiadomości e-mail \"{name}\"",
@ -107,13 +107,15 @@
"error.language.name": "Wprowadź poprawną nazwę języka.", "error.language.name": "Wprowadź poprawną nazwę języka.",
"error.language.notFound": "Język nie został odnaleziony", "error.language.notFound": "Język nie został odnaleziony",
"error.layout.validation.block": "W bloku {blockIndex} w układzie {layoutIndex} jest błąd", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "W ustawieniach układu {index} jest błąd", "error.layout.validation.settings": "W ustawieniach układu {index} jest błąd",
"error.license.format": "Wprowadź poprawny klucz licencyjny", "error.license.format": "Wprowadź poprawny klucz licencyjny",
"error.license.email": "Wprowadź poprawny adres email", "error.license.email": "Wprowadź poprawny adres email",
"error.license.verification": "Nie udało się zweryfikować licencji", "error.license.verification": "Nie udało się zweryfikować licencji",
"error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "Panel jest obecnie offline", "error.offline": "Panel jest obecnie offline",
"error.page.changeSlug.permission": "Nie możesz zmienić końcówki adresu URL w \"{slug}\"", "error.page.changeSlug.permission": "Nie możesz zmienić końcówki adresu URL w \"{slug}\"",
@ -282,9 +284,13 @@
"field.layout.empty": "Nie ma jeszcze żadnych rzędów", "field.layout.empty": "Nie ma jeszcze żadnych rzędów",
"field.layout.select": "Wybierz układ", "field.layout.select": "Wybierz układ",
"field.object.empty": "No information yet",
"field.pages.empty": "Nie wybrano jeszcze żadnych stron", "field.pages.empty": "Nie wybrano jeszcze żadnych stron",
"field.structure.delete.confirm": "Czy na pewno chcesz usunąć ten wiersz?", "field.structure.delete.confirm": "Czy na pewno chcesz usunąć ten wiersz?",
"field.structure.empty": "Nie ma jeszcze \u017cadnych wpis\u00f3w.", "field.structure.empty": "Nie ma jeszcze \u017cadnych wpis\u00f3w.",
"field.users.empty": "Nie wybrano jeszcze żadnych użytkowników", "field.users.empty": "Nie wybrano jeszcze żadnych użytkowników",
"file.blueprint": "Ten plik nie ma jeszcze wzorca. Możesz go zdefiniować w <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "Ten plik nie ma jeszcze wzorca. Możesz go zdefiniować w <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -448,6 +454,7 @@
"paste": "Wklej", "paste": "Wklej",
"paste.after": "Wklej po", "paste.after": "Wklej po",
"pixel": "Piksel", "pixel": "Piksel",
"plugin": "Plugin",
"plugins": "Wtyczki", "plugins": "Wtyczki",
"prev": "Poprzednie", "prev": "Poprzednie",
"preview": "Podgląd", "preview": "Podgląd",
@ -487,11 +494,24 @@
"stats.empty": "Brak raportów", "stats.empty": "Brak raportów",
"system.issues.content": "Zdaje się, że folder „content” jest wystawiony na publiczny dostęp", "system.issues.content": "Zdaje się, że folder „content” jest wystawiony na publiczny dostęp",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Debugowanie musi być wyłączone w środowisku produkcyjnym", "system.issues.debug": "Debugowanie musi być wyłączone w środowisku produkcyjnym",
"system.issues.git": "Zdaje się, że folder „.git” jest wystawiony na publiczny dostęp", "system.issues.git": "Zdaje się, że folder „.git” jest wystawiony na publiczny dostęp",
"system.issues.https": "Zalecamy HTTPS dla wszystkich Twoich witryn", "system.issues.https": "Zalecamy HTTPS dla wszystkich Twoich witryn",
"system.issues.kirby": "Zdaje się, że folder „kirby” jest wystawiony na publiczny dostęp", "system.issues.kirby": "Zdaje się, że folder „kirby” jest wystawiony na publiczny dostęp",
"system.issues.site": "Zdaje się, że folder „site” jest wystawiony na publiczny dostęp", "system.issues.site": "Zdaje się, że folder „site” jest wystawiony na publiczny dostęp",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Could not check for updates",
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
"system.updateStatus.security-update": "Free security update { version } available",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "Unreleased version",
"system.updateStatus.up-to-date": "Up to date",
"system.updateStatus.update": "Free update { version } available",
"system.updateStatus.upgrade": "Upgrade { version } available",
"title": "Tytuł", "title": "Tytuł",
"template": "Szablon", "template": "Szablon",
@ -558,6 +578,9 @@
"users": "Użytkownicy", "users": "Użytkownicy",
"version": "Wersja", "version": "Wersja",
"version.current": "Current version",
"version.latest": "Latest version",
"versionInformation": "Version information",
"view.account": "Twoje konto", "view.account": "Twoje konto",
"view.installation": "Instalacja", "view.installation": "Instalacja",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "Você não deve adicionar mais do que um bloco", "error.blocks.max.singular": "Você não deve adicionar mais do que um bloco",
"error.blocks.min.plural": "Você deve adicionar pelo menos {min} blocos", "error.blocks.min.plural": "Você deve adicionar pelo menos {min} blocos",
"error.blocks.min.singular": "Você deve adicionar pelo menos um bloco", "error.blocks.min.singular": "Você deve adicionar pelo menos um bloco",
"error.blocks.validation": "Há um erro no bloco {index}", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "Pré-configuração de email \"{name}\" não foi encontrada", "error.email.preset.notFound": "Pré-configuração de email \"{name}\" não foi encontrada",
@ -107,13 +107,15 @@
"error.language.name": "Por favor entre um nome válido para o idioma", "error.language.name": "Por favor entre um nome válido para o idioma",
"error.language.notFound": "O idioma não foi encontrado", "error.language.notFound": "O idioma não foi encontrado",
"error.layout.validation.block": "Há um erro no bloco {blockIndex} no layout {layoutIndex}", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "Há um erro na configuração do layout {index}", "error.layout.validation.settings": "Há um erro na configuração do layout {index}",
"error.license.format": "Por favor entre uma chave de licensa válida ", "error.license.format": "Por favor entre uma chave de licensa válida ",
"error.license.email": "Digite um endereço de email válido", "error.license.email": "Digite um endereço de email válido",
"error.license.verification": "A licensa não pôde ser verificada", "error.license.verification": "A licensa não pôde ser verificada",
"error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "O painel está offline no momento", "error.offline": "O painel está offline no momento",
"error.page.changeSlug.permission": "Você não tem permissão para alterar o anexo de URL de \"{slug}\"", "error.page.changeSlug.permission": "Você não tem permissão para alterar o anexo de URL de \"{slug}\"",
@ -282,9 +284,13 @@
"field.layout.empty": "Nenhuma linha", "field.layout.empty": "Nenhuma linha",
"field.layout.select": "Selecionar um layout", "field.layout.select": "Selecionar um layout",
"field.object.empty": "No information yet",
"field.pages.empty": "Nenhuma página selecionada", "field.pages.empty": "Nenhuma página selecionada",
"field.structure.delete.confirm": "Deseja realmente deletar esta linha?", "field.structure.delete.confirm": "Deseja realmente deletar esta linha?",
"field.structure.empty": "Nenhum registro", "field.structure.empty": "Nenhum registro",
"field.users.empty": "Nenhum usuário selecionado", "field.users.empty": "Nenhum usuário selecionado",
"file.blueprint": "Este arquivo não tem planta. Você pode definir sua planta em <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "Este arquivo não tem planta. Você pode definir sua planta em <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -448,6 +454,7 @@
"paste": "Colar", "paste": "Colar",
"paste.after": "Colar após", "paste.after": "Colar após",
"pixel": "Pixel", "pixel": "Pixel",
"plugin": "Plugin",
"plugins": "Plugins", "plugins": "Plugins",
"prev": "Anterior", "prev": "Anterior",
"preview": "Visualizar", "preview": "Visualizar",
@ -487,11 +494,24 @@
"stats.empty": "No reports", "stats.empty": "No reports",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "The content folder seems to be exposed",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.debug": "Debugging must be turned off in production",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.git": "The .git folder seems to be exposed",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.https": "We recommend HTTPS for all your sites",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.kirby": "The kirby folder seems to be exposed",
"system.issues.site": "The site folder seems to be exposed", "system.issues.site": "The site folder seems to be exposed",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Could not check for updates",
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
"system.updateStatus.security-update": "Free security update { version } available",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "Unreleased version",
"system.updateStatus.up-to-date": "Up to date",
"system.updateStatus.update": "Free update { version } available",
"system.updateStatus.upgrade": "Upgrade { version } available",
"title": "Título", "title": "Título",
"template": "Tema", "template": "Tema",
@ -558,6 +578,9 @@
"users": "Usuários", "users": "Usuários",
"version": "Vers\u00e3o do Kirby", "version": "Vers\u00e3o do Kirby",
"version.current": "Current version",
"version.latest": "Latest version",
"versionInformation": "Version information",
"view.account": "Sua conta", "view.account": "Sua conta",
"view.installation": "Instala\u00e7\u00e3o", "view.installation": "Instala\u00e7\u00e3o",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "Você não deve adicionar mais do que um bloco", "error.blocks.max.singular": "Você não deve adicionar mais do que um bloco",
"error.blocks.min.plural": "Você deve adicionar pelo menos {min} blocos", "error.blocks.min.plural": "Você deve adicionar pelo menos {min} blocos",
"error.blocks.min.singular": "Você deve adicionar pelo menos um bloco", "error.blocks.min.singular": "Você deve adicionar pelo menos um bloco",
"error.blocks.validation": "Há um erro no bloco {index}", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "Preset de email \"{name}\" não encontrado", "error.email.preset.notFound": "Preset de email \"{name}\" não encontrado",
@ -107,13 +107,15 @@
"error.language.name": "Insira um nome válido para o idioma", "error.language.name": "Insira um nome válido para o idioma",
"error.language.notFound": "O idioma não foi encontrado", "error.language.notFound": "O idioma não foi encontrado",
"error.layout.validation.block": "Há um erro no bloco {blockIndex} no layout {layoutIndex}", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "Há um erro na configuração do layout {index}", "error.layout.validation.settings": "Há um erro na configuração do layout {index}",
"error.license.format": "Insira uma chave de licença válida", "error.license.format": "Insira uma chave de licença válida",
"error.license.email": "Digite um endereço de email válido", "error.license.email": "Digite um endereço de email válido",
"error.license.verification": "Não foi possível verificar a licença", "error.license.verification": "Não foi possível verificar a licença",
"error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "O painel está offline no momento", "error.offline": "O painel está offline no momento",
"error.page.changeSlug.permission": "Não tem permissões para alterar a URL de \"{slug}\"", "error.page.changeSlug.permission": "Não tem permissões para alterar a URL de \"{slug}\"",
@ -282,9 +284,13 @@
"field.layout.empty": "Nenhuma linha", "field.layout.empty": "Nenhuma linha",
"field.layout.select": "Selecionar um layout", "field.layout.select": "Selecionar um layout",
"field.object.empty": "No information yet",
"field.pages.empty": "Nenhuma página selecionada", "field.pages.empty": "Nenhuma página selecionada",
"field.structure.delete.confirm": "Deseja realmente excluir este registro?", "field.structure.delete.confirm": "Deseja realmente excluir este registro?",
"field.structure.empty": "Nenhum registro", "field.structure.empty": "Nenhum registro",
"field.users.empty": "Nenhum utilizador selecionado", "field.users.empty": "Nenhum utilizador selecionado",
"file.blueprint": "Este arquivo não tem planta. Você pode definir sua planta em <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "Este arquivo não tem planta. Você pode definir sua planta em <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -448,6 +454,7 @@
"paste": "Colar", "paste": "Colar",
"paste.after": "Colar após", "paste.after": "Colar após",
"pixel": "Pixel", "pixel": "Pixel",
"plugin": "Plugin",
"plugins": "Plugins", "plugins": "Plugins",
"prev": "Anterior", "prev": "Anterior",
"preview": "Visualizar", "preview": "Visualizar",
@ -487,11 +494,24 @@
"stats.empty": "No reports", "stats.empty": "No reports",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "The content folder seems to be exposed",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.debug": "Debugging must be turned off in production",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.git": "The .git folder seems to be exposed",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.https": "We recommend HTTPS for all your sites",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.kirby": "The kirby folder seems to be exposed",
"system.issues.site": "The site folder seems to be exposed", "system.issues.site": "The site folder seems to be exposed",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Could not check for updates",
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
"system.updateStatus.security-update": "Free security update { version } available",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "Unreleased version",
"system.updateStatus.up-to-date": "Up to date",
"system.updateStatus.update": "Free update { version } available",
"system.updateStatus.upgrade": "Upgrade { version } available",
"title": "Título", "title": "Título",
"template": "Tema", "template": "Tema",
@ -558,6 +578,9 @@
"users": "Utilizadores", "users": "Utilizadores",
"version": "Vers\u00e3o do Kirby", "version": "Vers\u00e3o do Kirby",
"version.current": "Current version",
"version.latest": "Latest version",
"versionInformation": "Version information",
"view.account": "A sua conta", "view.account": "A sua conta",
"view.installation": "Instala\u00e7\u00e3o", "view.installation": "Instala\u00e7\u00e3o",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "Вы не можете добавить больше одного блока", "error.blocks.max.singular": "Вы не можете добавить больше одного блока",
"error.blocks.min.plural": "Вы должны добавить хотя бы {min} блоков", "error.blocks.min.plural": "Вы должны добавить хотя бы {min} блоков",
"error.blocks.min.singular": "Вы должны добавить хотя бы один блок", "error.blocks.min.singular": "Вы должны добавить хотя бы один блок",
"error.blocks.validation": "Обнаружена ошибка в блоке {index}", "error.blocks.validation": "Ошибка в поле \"{field}\" в блоке {index} типа \"{fieldset}\"",
"error.email.preset.notFound": "Шаблон эл. почты \"{name}\" не найден", "error.email.preset.notFound": "Шаблон эл. почты \"{name}\" не найден",
@ -107,13 +107,15 @@
"error.language.name": "Пожалуйста, впишите правильное название языка", "error.language.name": "Пожалуйста, впишите правильное название языка",
"error.language.notFound": "Не получилось найти этот язык", "error.language.notFound": "Не получилось найти этот язык",
"error.layout.validation.block": "Ошибка в блоке {blockIndex} в макете {layoutIndex}", "error.layout.validation.block": "Ошибка в поле \"{field}\" в блоке {blockIndex} типа \"{fieldset}\" внутри разметки {layoutIndex}",
"error.layout.validation.settings": "Ошибка в настройках макета {index}", "error.layout.validation.settings": "Ошибка в настройках макета {index}",
"error.license.format": "Пожалуйста, введите правильный лицензионный код", "error.license.format": "Пожалуйста, введите правильный лицензионный код",
"error.license.email": "Пожалуйста, введите правильный Email", "error.license.email": "Пожалуйста, введите правильный Email",
"error.license.verification": "Лицензия не подтверждена", "error.license.verification": "Лицензия не подтверждена",
"error.object.validation": "Ошибка в поле \"{label}\":\n{message}",
"error.offline": "Панель управления не в сети", "error.offline": "Панель управления не в сети",
"error.page.changeSlug.permission": "\u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c URL \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b", "error.page.changeSlug.permission": "\u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c URL \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b",
@ -282,9 +284,13 @@
"field.layout.empty": "Строк нет", "field.layout.empty": "Строк нет",
"field.layout.select": "Выберите разметку", "field.layout.select": "Выберите разметку",
"field.object.empty": "Пока нет информации",
"field.pages.empty": "Страницы не выбраны", "field.pages.empty": "Страницы не выбраны",
"field.structure.delete.confirm": "Вы точно хотите удалить эту запись?", "field.structure.delete.confirm": "Вы точно хотите удалить эту запись?",
"field.structure.empty": "Записей нет", "field.structure.empty": "Записей нет",
"field.users.empty": "Пользователей нет", "field.users.empty": "Пользователей нет",
"file.blueprint": "У файла пока нет разметки. Вы можете определить новые секции и поля разметки в <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "У файла пока нет разметки. Вы можете определить новые секции и поля разметки в <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -448,6 +454,7 @@
"paste": "Вставить", "paste": "Вставить",
"paste.after": "Вставить после", "paste.after": "Вставить после",
"pixel": "Пиксель", "pixel": "Пиксель",
"plugin": "Расширение",
"plugins": "Плагины", "plugins": "Плагины",
"prev": "Предыдущий", "prev": "Предыдущий",
"preview": "Предпросмотр", "preview": "Предпросмотр",
@ -487,11 +494,24 @@
"stats.empty": "Статистики нет", "stats.empty": "Статистики нет",
"system.issues.content": "Похоже, к папке content есть несанкционированный доступ", "system.issues.content": "Похоже, к папке content есть несанкционированный доступ",
"system.issues.eol.kirby": "Срок службы установленной вами версии Kirby истек, и она больше не будет получать обновления для системы безопасности",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Включен режим отладки (debugging). Используйте его только при разработке.", "system.issues.debug": "Включен режим отладки (debugging). Используйте его только при разработке.",
"system.issues.git": "Похоже, к папке .git есть несанкционированный доступ", "system.issues.git": "Похоже, к папке .git есть несанкционированный доступ",
"system.issues.https": "Рекомендуется использовать HTTPS на всех сайтах", "system.issues.https": "Рекомендуется использовать HTTPS на всех сайтах",
"system.issues.kirby": "Похоже, к папке kirby есть несанкционированный доступ", "system.issues.kirby": "Похоже, к папке kirby есть несанкционированный доступ",
"system.issues.site": "Похоже, к папке site есть несанкционированный доступ", "system.issues.site": "Похоже, к папке site есть несанкционированный доступ",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Не удалось проверить обновления",
"system.updateStatus.not-vulnerable": "Известных уязвимостей не выявлено",
"system.updateStatus.security-update": "Доступно бесплатное обновление для системы безопасности { version }",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "Unreleased version",
"system.updateStatus.up-to-date": "Последняя версия",
"system.updateStatus.update": "Доступно бесплатное обновление { version }",
"system.updateStatus.upgrade": "Upgrade { version } available",
"title": "Название", "title": "Название",
"template": "\u0428\u0430\u0431\u043b\u043e\u043d", "template": "\u0428\u0430\u0431\u043b\u043e\u043d",
@ -558,6 +578,9 @@
"users": "Пользователи", "users": "Пользователи",
"version": "Версия", "version": "Версия",
"version.current": "Текущая версия",
"version.latest": "Последняя версия",
"versionInformation": "Version information",
"view.account": "\u0412\u0430\u0448 \u0430\u043a\u043a\u0430\u0443\u043d\u0442", "view.account": "\u0412\u0430\u0448 \u0430\u043a\u043a\u0430\u0443\u043d\u0442",
"view.installation": "\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430", "view.installation": "\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "You must not add more than one block", "error.blocks.max.singular": "You must not add more than one block",
"error.blocks.min.plural": "You must add at least {min} blocks", "error.blocks.min.plural": "You must add at least {min} blocks",
"error.blocks.min.singular": "You must add at least one block", "error.blocks.min.singular": "You must add at least one block",
"error.blocks.validation": "There's an error in block {index}", "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
"error.email.preset.notFound": "E-mailovú predvoľbu \"{name}\" nie je možné nájsť", "error.email.preset.notFound": "E-mailovú predvoľbu \"{name}\" nie je možné nájsť",
@ -107,13 +107,15 @@
"error.language.name": "Please enter a valid name for the language", "error.language.name": "Please enter a valid name for the language",
"error.language.notFound": "The language could not be found", "error.language.notFound": "The language could not be found",
"error.layout.validation.block": "There's an error in block {blockIndex} in layout {layoutIndex}", "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
"error.layout.validation.settings": "There's an error in layout {index} settings", "error.layout.validation.settings": "There's an error in layout {index} settings",
"error.license.format": "Please enter a valid license key", "error.license.format": "Please enter a valid license key",
"error.license.email": "Prosím, zadajte platnú e-mailovú adresu", "error.license.email": "Prosím, zadajte platnú e-mailovú adresu",
"error.license.verification": "The license could not be verified", "error.license.verification": "The license could not be verified",
"error.object.validation": "Theres an error in the \"{label}\" field:\n{message}",
"error.offline": "The Panel is currently offline", "error.offline": "The Panel is currently offline",
"error.page.changeSlug.permission": "Nemáte povolenie na zmenu URL príponu pre \"{slug}\"", "error.page.changeSlug.permission": "Nemáte povolenie na zmenu URL príponu pre \"{slug}\"",
@ -282,9 +284,13 @@
"field.layout.empty": "No rows yet", "field.layout.empty": "No rows yet",
"field.layout.select": "Select a layout", "field.layout.select": "Select a layout",
"field.object.empty": "No information yet",
"field.pages.empty": "Žiadne stránky zatiaľ neboli zvolené", "field.pages.empty": "Žiadne stránky zatiaľ neboli zvolené",
"field.structure.delete.confirm": "Ste si istý, že chcete zmazať tento riadok?", "field.structure.delete.confirm": "Ste si istý, že chcete zmazať tento riadok?",
"field.structure.empty": "Zatiaľ žiadne údaje", "field.structure.empty": "Zatiaľ žiadne údaje",
"field.users.empty": "Žiadni užívatelia zatiaľ neboli zvolení", "field.users.empty": "Žiadni užívatelia zatiaľ neboli zvolení",
"file.blueprint": "This file has no blueprint yet. You can define the setup in <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "This file has no blueprint yet. You can define the setup in <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -448,6 +454,7 @@
"paste": "Paste", "paste": "Paste",
"paste.after": "Paste after", "paste.after": "Paste after",
"pixel": "Pixel", "pixel": "Pixel",
"plugin": "Plugin",
"plugins": "Plugins", "plugins": "Plugins",
"prev": "Predchádzajúci", "prev": "Predchádzajúci",
"preview": "Preview", "preview": "Preview",
@ -487,11 +494,24 @@
"stats.empty": "No reports", "stats.empty": "No reports",
"system.issues.content": "The content folder seems to be exposed", "system.issues.content": "The content folder seems to be exposed",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
"system.issues.debug": "Debugging must be turned off in production", "system.issues.debug": "Debugging must be turned off in production",
"system.issues.git": "The .git folder seems to be exposed", "system.issues.git": "The .git folder seems to be exposed",
"system.issues.https": "We recommend HTTPS for all your sites", "system.issues.https": "We recommend HTTPS for all your sites",
"system.issues.kirby": "The kirby folder seems to be exposed", "system.issues.kirby": "The kirby folder seems to be exposed",
"system.issues.site": "The site folder seems to be exposed", "system.issues.site": "The site folder seems to be exposed",
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
"system.updateStatus": "Update status",
"system.updateStatus.error": "Could not check for updates",
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
"system.updateStatus.security-update": "Free security update { version } available",
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
"system.updateStatus.unreleased": "Unreleased version",
"system.updateStatus.up-to-date": "Up to date",
"system.updateStatus.update": "Free update { version } available",
"system.updateStatus.upgrade": "Upgrade { version } available",
"title": "Titulok", "title": "Titulok",
"template": "Šablóna", "template": "Šablóna",
@ -558,6 +578,9 @@
"users": "Užívatelia", "users": "Užívatelia",
"version": "Verzia", "version": "Verzia",
"version.current": "Current version",
"version.latest": "Latest version",
"versionInformation": "Version information",
"view.account": "Váš účet", "view.account": "Váš účet",
"view.installation": "Inštalácia", "view.installation": "Inštalácia",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "Du får inte lägga till mer än ett block", "error.blocks.max.singular": "Du får inte lägga till mer än ett block",
"error.blocks.min.plural": "Du måste lägga till minst {min} block", "error.blocks.min.plural": "Du måste lägga till minst {min} block",
"error.blocks.min.singular": "Du måste lägga till minst ett block", "error.blocks.min.singular": "Du måste lägga till minst ett block",
"error.blocks.validation": "Det finns ett fel i block {index}", "error.blocks.validation": "Det finns ett fel i fältet \"{field}\" i block {index} med blocktypen \"{fieldset}\"",
"error.email.preset.notFound": "E-postförinställningen \"{name}\" kan inte hittas", "error.email.preset.notFound": "E-postförinställningen \"{name}\" kan inte hittas",
@ -107,13 +107,15 @@
"error.language.name": "Ange ett giltigt namn för språket", "error.language.name": "Ange ett giltigt namn för språket",
"error.language.notFound": "Språket hittades inte", "error.language.notFound": "Språket hittades inte",
"error.layout.validation.block": "Det finns ett fel i block {blockIndex} i layout {layoutIndex}", "error.layout.validation.block": "Det finns ett fel i fältet \"{field}\" i blocket {blockIndex} med blocktypen \"{fieldset}\" i layouten {layoutIndex}",
"error.layout.validation.settings": "Det finns ett fel i inställningarna för layout {index}", "error.layout.validation.settings": "Det finns ett fel i inställningarna för layout {index}",
"error.license.format": "Ange en giltig licensnyckel", "error.license.format": "Ange en giltig licensnyckel",
"error.license.email": "Ange en giltig e-postadress", "error.license.email": "Ange en giltig e-postadress",
"error.license.verification": "Licensen kunde inte verifieras", "error.license.verification": "Licensen kunde inte verifieras",
"error.object.validation": "Det finns ett fel i fältet \"{label}\":\n{message}",
"error.offline": "Panelen är för närvarande offline", "error.offline": "Panelen är för närvarande offline",
"error.page.changeSlug.permission": "Du har inte behörighet att ändra URL-appendixen för \"{slug}\"", "error.page.changeSlug.permission": "Du har inte behörighet att ändra URL-appendixen för \"{slug}\"",
@ -282,9 +284,13 @@
"field.layout.empty": "Inga rader än", "field.layout.empty": "Inga rader än",
"field.layout.select": "Välj en layout", "field.layout.select": "Välj en layout",
"field.object.empty": "Ingen information ännu",
"field.pages.empty": "Inga sidor valda än", "field.pages.empty": "Inga sidor valda än",
"field.structure.delete.confirm": "Vill du verkligen radera denna rad?", "field.structure.delete.confirm": "Vill du verkligen radera denna rad?",
"field.structure.empty": "Inga poster än", "field.structure.empty": "Inga poster än",
"field.users.empty": "Inga användare valda än", "field.users.empty": "Inga användare valda än",
"file.blueprint": "Denna fil har ingen blueprint än. Du kan skapa en i <strong>/site/blueprints/files/{blueprint}.yml</strong>", "file.blueprint": "Denna fil har ingen blueprint än. Du kan skapa en i <strong>/site/blueprints/files/{blueprint}.yml</strong>",
@ -448,6 +454,7 @@
"paste": "Klistra in", "paste": "Klistra in",
"paste.after": "Klistra in efter", "paste.after": "Klistra in efter",
"pixel": "Pixel", "pixel": "Pixel",
"plugin": "Tillägg",
"plugins": "Tillägg", "plugins": "Tillägg",
"prev": "Föregående", "prev": "Föregående",
"preview": "Förhandsgranska", "preview": "Förhandsgranska",
@ -487,11 +494,24 @@
"stats.empty": "Inga rapporter", "stats.empty": "Inga rapporter",
"system.issues.content": "Mappen content verkar vara exponerad", "system.issues.content": "Mappen content verkar vara exponerad",
"system.issues.eol.kirby": "Din installerade Kirby-version har nått slutet av sin livscykel och kommer inte att få fler säkerhetsuppdateringar",
"system.issues.eol.plugin": "Den installerade versionen av tillägget { plugin } har nått slutet på sin livscykel och kommer inte att få fler säkerhetsuppdateringar.",
"system.issues.debug": "Felsökningsläget måste vara avstängt i produktion", "system.issues.debug": "Felsökningsläget måste vara avstängt i produktion",
"system.issues.git": "Mappen .git verkar vara exponerad", "system.issues.git": "Mappen .git verkar vara exponerad",
"system.issues.https": "Vi rekommenderar HTTPS för alla dina webbplatser", "system.issues.https": "Vi rekommenderar HTTPS för alla dina webbplatser",
"system.issues.kirby": "Mappen kirby verkar vara exponerad", "system.issues.kirby": "Mappen kirby verkar vara exponerad",
"system.issues.site": "Mappen site verkar vara exponerad", "system.issues.site": "Mappen site verkar vara exponerad",
"system.issues.vulnerability.kirby": "Din installation kan vara påverkad av följande sårbarhet ({ severity } allvarlighetsgrad): { description }",
"system.issues.vulnerability.plugin": "Din installation kan vara påverkad av följande sårbarhet i tillägget { plugin } ({ severity } allvarlighetsgrad): { description }",
"system.updateStatus": "Uppdateringsstatus",
"system.updateStatus.error": "Det gick inte att söka efter uppdateringar",
"system.updateStatus.not-vulnerable": "Inga kända sårbarheter",
"system.updateStatus.security-update": "Gratis säkerhetsuppdatering { version } tillgänglig",
"system.updateStatus.security-upgrade": "Uppgradering { version } med säkerhetskorrigeringar är tillgänglig",
"system.updateStatus.unreleased": "Osläppt version",
"system.updateStatus.up-to-date": "Uppdaterad",
"system.updateStatus.update": "Gratis uppdatering { version } tillgänglig",
"system.updateStatus.upgrade": "Uppgradering { version } tillgänglig",
"title": "Titel", "title": "Titel",
"template": "Mall", "template": "Mall",
@ -558,6 +578,9 @@
"users": "Användare", "users": "Användare",
"version": "Version", "version": "Version",
"version.current": "Aktuell version",
"version.latest": "Senaste version",
"versionInformation": "Versionsinformation",
"view.account": "Ditt konto", "view.account": "Ditt konto",
"view.installation": "Installation", "view.installation": "Installation",

View file

@ -70,7 +70,7 @@
"error.blocks.max.singular": "Birden fazla blok eklememelisiniz", "error.blocks.max.singular": "Birden fazla blok eklememelisiniz",
"error.blocks.min.plural": "En az {min} blok eklemelisiniz", "error.blocks.min.plural": "En az {min} blok eklemelisiniz",
"error.blocks.min.singular": "En az bir blok eklemelisiniz", "error.blocks.min.singular": "En az bir blok eklemelisiniz",
"error.blocks.validation": "{index} bloğunda bir hata var", "error.blocks.validation": "\"{fieldset}\" blok türünü kullanan {index}. bloktaki \"{field}\" alanında bir hata var",
"error.email.preset.notFound": "\"{name}\" e-posta adresi bulunamadı", "error.email.preset.notFound": "\"{name}\" e-posta adresi bulunamadı",
@ -107,13 +107,15 @@
"error.language.name": "Lütfen dil için geçerli bir isim girin", "error.language.name": "Lütfen dil için geçerli bir isim girin",
"error.language.notFound": "Dil bulunamadı", "error.language.notFound": "Dil bulunamadı",
"error.layout.validation.block": "{layoutIndex}. düzenin {blockIndex}. bloğunda bir hata var", "error.layout.validation.block": "{layoutIndex}. sıradaki düzende \"{fieldset}\" blok türünü kullanan {blockIndex}. bloktaki \"{field}\" alanında bir hata var",
"error.layout.validation.settings": "{index}. düzen ayarlarında bir hata var", "error.layout.validation.settings": "{index}. düzen ayarlarında bir hata var",
"error.license.format": "Lütfen geçerli bir lisans anahtarı girin", "error.license.format": "Lütfen geçerli bir lisans anahtarı girin",
"error.license.email": "Lütfen geçerli bir e-posta adresi girin", "error.license.email": "Lütfen geçerli bir e-posta adresi girin",
"error.license.verification": "Lisans doğrulanamadı", "error.license.verification": "Lisans doğrulanamadı",
"error.object.validation": "\"{label}\" alanında bir hata var:\n{message}",
"error.offline": "Panel şu anda çevrimdışı", "error.offline": "Panel şu anda çevrimdışı",
"error.page.changeSlug.permission": "\"{slug}\" uzantısına sahip bu sayfanın adresini değiştirilemez", "error.page.changeSlug.permission": "\"{slug}\" uzantısına sahip bu sayfanın adresini değiştirilemez",
@ -282,9 +284,13 @@
"field.layout.empty": "Henüz satır yok", "field.layout.empty": "Henüz satır yok",
"field.layout.select": "Bir düzen seçin", "field.layout.select": "Bir düzen seçin",
"field.object.empty": "Henüz bilgi yok",
"field.pages.empty": "Henüz sayfa seçilmedi", "field.pages.empty": "Henüz sayfa seçilmedi",
"field.structure.delete.confirm": "Bu girdiyi silmek istedi\u011finizden emin misiniz?", "field.structure.delete.confirm": "Bu girdiyi silmek istedi\u011finizden emin misiniz?",
"field.structure.empty": "Hen\u00fcz bir girdi yok", "field.structure.empty": "Hen\u00fcz bir girdi yok",
"field.users.empty": "Henüz kullanıcı seçilmedi", "field.users.empty": "Henüz kullanıcı seçilmedi",
"file.blueprint": "Bu dosyanın henüz bir planı yok. Kurulumu <strong>/site/blueprints/files/{blueprint}.yml</strong> dosyasında tanımlayabilirsiniz.", "file.blueprint": "Bu dosyanın henüz bir planı yok. Kurulumu <strong>/site/blueprints/files/{blueprint}.yml</strong> dosyasında tanımlayabilirsiniz.",
@ -448,6 +454,7 @@
"paste": "Yapıştır", "paste": "Yapıştır",
"paste.after": "Sonrasına yapıştır", "paste.after": "Sonrasına yapıştır",
"pixel": "Piksel", "pixel": "Piksel",
"plugin": "Eklenti",
"plugins": "Eklentiler", "plugins": "Eklentiler",
"prev": "Önceki", "prev": "Önceki",
"preview": "Önizle", "preview": "Önizle",
@ -487,11 +494,24 @@
"stats.empty": "Rapor yok", "stats.empty": "Rapor yok",
"system.issues.content": "İçerik klasörü açığa çıkmış görünüyor", "system.issues.content": "İçerik klasörü açığa çıkmış görünüyor",
"system.issues.eol.kirby": "Yüklü Kirby sürümünüz kullanım ömrünün sonuna ulaştı ve daha fazla güvenlik güncellemesi almayacak",
"system.issues.eol.plugin": "{ plugin } eklentisinin yüklü sürümü kullanım ömrünün sonuna ulaştı ve daha fazla güvenlik güncellemesi almayacak",
"system.issues.debug": "Canlı modda hata ayıklama kapatılmalıdır", "system.issues.debug": "Canlı modda hata ayıklama kapatılmalıdır",
"system.issues.git": ".git klasörü açığa çıkmış görünüyor", "system.issues.git": ".git klasörü açığa çıkmış görünüyor",
"system.issues.https": "Tüm siteleriniz için HTTPS'yi öneriyoruz", "system.issues.https": "Tüm siteleriniz için HTTPS'yi öneriyoruz",
"system.issues.kirby": "Kirby klasörü açığa çıkmış görünüyor", "system.issues.kirby": "Kirby klasörü açığa çıkmış görünüyor",
"system.issues.site": "Site klasörü açığa çıkmış görünüyor", "system.issues.site": "Site klasörü açığa çıkmış görünüyor",
"system.issues.vulnerability.kirby": "Kurulumunuz aşağıdaki güvenlik açığından ({ severity } önem derecesi) etkilenebilir: { description }",
"system.issues.vulnerability.plugin": "Kurulumunuz, { plugin } eklentisindeki ({ severity } önem derecesi) aşağıdaki güvenlik açığından etkilenebilir: { description }",
"system.updateStatus": "Güncelleme durumu",
"system.updateStatus.error": "Güncellemeler kontrol edilemedi",
"system.updateStatus.not-vulnerable": "Bilinen güvenlik açığı yok",
"system.updateStatus.security-update": "Ücretsiz güvenlik güncellemesi { version } mevcut",
"system.updateStatus.security-upgrade": "Mevcut güvenlik düzeltmeleriyle { version } sürümüne yükseltin",
"system.updateStatus.unreleased": "Yayınlanmamış sürüm",
"system.updateStatus.up-to-date": "Güncel",
"system.updateStatus.update": "Ücretsiz güncelleme { version } mevcut",
"system.updateStatus.upgrade": "{ version } yükseltme mevcut",
"title": "Başlık", "title": "Başlık",
"template": "\u015eablon", "template": "\u015eablon",
@ -558,6 +578,9 @@
"users": "Kullanıcılar", "users": "Kullanıcılar",
"version": "Versiyon", "version": "Versiyon",
"version.current": "Mevcut sürüm",
"version.latest": "En son sürüm",
"versionInformation": "Sürüm bilgisi",
"view.account": "Hesap Bilgilerin", "view.account": "Hesap Bilgilerin",
"view.installation": "Kurulum", "view.installation": "Kurulum",

File diff suppressed because one or more lines are too long

View file

@ -409,6 +409,9 @@
<symbol id="icon-markdown" viewBox="0 0 16 16"> <symbol id="icon-markdown" viewBox="0 0 16 16">
<path d="M14.85 3H1.15C.52 3 0 3.52 0 4.15v7.69C0 12.48.52 13 1.15 13h13.69c.64 0 1.15-.52 1.15-1.15v-7.7C16 3.52 15.48 3 14.85 3zM9 11H7V8L5.5 9.92 4 8v3H2V5h2l1.5 2L7 5h2v6zm2.99.5L9.5 8H11V5h2v3h1.5l-2.51 3.5z" /> <path d="M14.85 3H1.15C.52 3 0 3.52 0 4.15v7.69C0 12.48.52 13 1.15 13h13.69c.64 0 1.15-.52 1.15-1.15v-7.7C16 3.52 15.48 3 14.85 3zM9 11H7V8L5.5 9.92 4 8v3H2V5h2l1.5 2L7 5h2v6zm2.99.5L9.5 8H11V5h2v3h1.5l-2.51 3.5z" />
</symbol> </symbol>
<symbol id="icon-mastodon" viewBox="0 0 16 16">
<path d="M14.943 3.935c-.215-1.591-1.612-2.845-3.268-3.088-.28-.041-1.338-.19-3.79-.19h-.019c-2.453 0-2.979.148-3.258.19-1.61.236-3.08 1.363-3.437 2.973-.172.793-.19 1.672-.158 2.478.045 1.157.054 2.311.16 3.463.073.765.2 1.524.382 2.27.339 1.38 1.711 2.53 3.056 2.998 1.44.488 2.988.57 4.472.234.163-.038.325-.081.484-.131.36-.114.783-.241 1.093-.465a.036.036 0 0 0 .015-.027v-1.116a.033.033 0 0 0-.041-.031c-.951.225-1.925.338-2.902.336-1.682 0-2.134-.792-2.264-1.122a3.463 3.463 0 0 1-.196-.884.032.032 0 0 1 .04-.033c.935.224 1.893.337 2.855.336.231 0 .461 0 .693-.006.967-.027 1.986-.076 2.938-.26l.067-.015c1.501-.286 2.93-1.184 3.075-3.458.005-.09.018-.938.018-1.03.001-.316.103-2.24-.015-3.422Zm-2.31 5.674h-1.578V5.772c0-.808-.339-1.22-1.028-1.22-.758 0-1.138.488-1.138 1.45v2.1H7.32v-2.1c0-.962-.38-1.45-1.138-1.45-.686 0-1.029.412-1.03 1.22v3.837H3.577V5.656c0-.808.208-1.45.623-1.926.429-.474.991-.718 1.689-.718.808 0 1.418.308 1.825.924l.393.655.393-.655c.407-.616 1.017-.924 1.823-.924.698 0 1.26.244 1.69.718.415.475.623 1.117.623 1.926l-.002 3.953Z"/>
</symbol>
<symbol id="icon-menu" viewBox="0 0 16 16"> <symbol id="icon-menu" viewBox="0 0 16 16">
<path d="M0 0h16v3H0V0zM0 6h16v3H0V6zM0 12h16v3H0v-3z" /> <path d="M0 0h16v3H0V0zM0 6h16v3H0V6zM0 12h16v3H0v-3z" />
</symbol> </symbol>

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Before After
Before After

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -4,10 +4,14 @@ namespace Kirby\Api;
use Closure; use Closure;
use Exception; use Exception;
use Kirby\Cms\User;
use Kirby\Exception\Exception as ExceptionException;
use Kirby\Exception\NotFoundException; use Kirby\Exception\NotFoundException;
use Kirby\Filesystem\F; use Kirby\Filesystem\F;
use Kirby\Http\Response; use Kirby\Http\Response;
use Kirby\Http\Route;
use Kirby\Http\Router; use Kirby\Http\Router;
use Kirby\Toolkit\Collection as BaseCollection;
use Kirby\Toolkit\I18n; use Kirby\Toolkit\I18n;
use Kirby\Toolkit\Pagination; use Kirby\Toolkit\Pagination;
use Kirby\Toolkit\Properties; use Kirby\Toolkit\Properties;
@ -32,82 +36,59 @@ class Api
/** /**
* Authentication callback * Authentication callback
*
* @var \Closure
*/ */
protected $authentication; protected Closure|null $authentication = null;
/** /**
* Debugging flag * Debugging flag
*
* @var bool
*/ */
protected $debug = false; protected bool $debug = false;
/** /**
* Collection definition * Collection definition
*
* @var array
*/ */
protected $collections = []; protected array $collections = [];
/** /**
* Injected data/dependencies * Injected data/dependencies
*
* @var array
*/ */
protected $data = []; protected array $data = [];
/** /**
* Model definitions * Model definitions
*
* @var array
*/ */
protected $models = []; protected array $models = [];
/** /**
* The current route * The current route
*
* @var \Kirby\Http\Route
*/ */
protected $route; protected Route|null $route = null;
/** /**
* The Router instance * The Router instance
*
* @var \Kirby\Http\Router
*/ */
protected $router; protected Router|null $router = null;
/** /**
* Route definition * Route definition
*
* @var array
*/ */
protected $routes = []; protected array $routes = [];
/** /**
* Request data * Request data
* [query, body, files] * [query, body, files]
*
* @var array
*/ */
protected $requestData = []; protected array $requestData = [];
/** /**
* The applied request method * The applied request method
* (GET, POST, PATCH, etc.) * (GET, POST, PATCH, etc.)
*
* @var string
*/ */
protected $requestMethod; protected string|null $requestMethod = null;
/** /**
* Magic accessor for any given data * Magic accessor for any given data
* *
* @param string $method
* @param array $args
* @return mixed
* @throws \Kirby\Exception\NotFoundException * @throws \Kirby\Exception\NotFoundException
*/ */
public function __call(string $method, array $args = []) public function __call(string $method, array $args = [])
@ -117,8 +98,6 @@ class Api
/** /**
* Creates a new API instance * Creates a new API instance
*
* @param array $props
*/ */
public function __construct(array $props) public function __construct(array $props)
{ {
@ -128,16 +107,10 @@ class Api
/** /**
* Runs the authentication method * Runs the authentication method
* if set * if set
*
* @return mixed
*/ */
public function authenticate() public function authenticate()
{ {
if ($auth = $this->authentication()) { return $this->authentication()?->call($this) ?? true;
return $auth->call($this);
}
return true;
} }
/** /**
@ -145,7 +118,7 @@ class Api
* *
* @return \Closure|null * @return \Closure|null
*/ */
public function authentication() public function authentication(): Closure|null
{ {
return $this->authentication; return $this->authentication;
} }
@ -154,14 +127,10 @@ class Api
* Execute an API call for the given path, * Execute an API call for the given path,
* request method and optional request data * request method and optional request data
* *
* @param string|null $path
* @param string $method
* @param array $requestData
* @return mixed
* @throws \Kirby\Exception\NotFoundException * @throws \Kirby\Exception\NotFoundException
* @throws \Exception * @throws \Exception
*/ */
public function call(string $path = null, string $method = 'GET', array $requestData = []) public function call(string|null $path = null, string $method = 'GET', array $requestData = [])
{ {
$path = rtrim($path ?? '', '/'); $path = rtrim($path ?? '', '/');
@ -170,19 +139,18 @@ class Api
$this->router = new Router($this->routes()); $this->router = new Router($this->routes());
$this->route = $this->router->find($path, $method); $this->route = $this->router->find($path, $method);
$auth = $this->route->attributes()['auth'] ?? true; $auth = $this->route?->attributes()['auth'] ?? true;
if ($auth !== false) { if ($auth !== false) {
$user = $this->authenticate(); $user = $this->authenticate();
// set PHP locales based on *user* language // set PHP locales based on *user* language
// so that e.g. strftime() gets formatted correctly // so that e.g. strftime() gets formatted correctly
if (is_a($user, 'Kirby\Cms\User') === true) { if ($user instanceof User) {
$language = $user->language(); $language = $user->language();
// get the locale from the translation // get the locale from the translation
$translation = $user->kirby()->translation($language); $locale = $user->kirby()->translation($language)->locale();
$locale = ($translation !== null) ? $translation->locale() : $language;
// provide some variants as fallbacks to be // provide some variants as fallbacks to be
// compatible with as many systems as possible // compatible with as many systems as possible
@ -208,14 +176,17 @@ class Api
$validate = Pagination::$validate; $validate = Pagination::$validate;
Pagination::$validate = false; Pagination::$validate = false;
$output = $this->route->action()->call($this, ...$this->route->arguments()); $output = $this->route?->action()->call(
$this,
...$this->route->arguments()
);
// restore old pagination validation mode // restore old pagination validation mode
Pagination::$validate = $validate; Pagination::$validate = $validate;
if ( if (
is_object($output) === true && is_object($output) === true &&
is_a($output, 'Kirby\\Http\\Response') !== true $output instanceof Response === false
) { ) {
return $this->resolve($output)->toResponse(); return $this->resolve($output)->toResponse();
} }
@ -226,13 +197,10 @@ class Api
/** /**
* Setter and getter for an API collection * Setter and getter for an API collection
* *
* @param string $name
* @param array|null $collection
* @return \Kirby\Api\Collection
* @throws \Kirby\Exception\NotFoundException If no collection for `$name` exists * @throws \Kirby\Exception\NotFoundException If no collection for `$name` exists
* @throws \Exception * @throws \Exception
*/ */
public function collection(string $name, $collection = null) public function collection(string $name, array|BaseCollection|null $collection = null): Collection
{ {
if (isset($this->collections[$name]) === false) { if (isset($this->collections[$name]) === false) {
throw new NotFoundException(sprintf('The collection "%s" does not exist', $name)); throw new NotFoundException(sprintf('The collection "%s" does not exist', $name));
@ -243,8 +211,6 @@ class Api
/** /**
* Returns the collections definition * Returns the collections definition
*
* @return array
*/ */
public function collections(): array public function collections(): array
{ {
@ -255,13 +221,9 @@ class Api
* Returns the injected data array * Returns the injected data array
* or certain parts of it by key * or certain parts of it by key
* *
* @param string|null $key
* @param mixed ...$args
* @return mixed
*
* @throws \Kirby\Exception\NotFoundException If no data for `$key` exists * @throws \Kirby\Exception\NotFoundException If no data for `$key` exists
*/ */
public function data($key = null, ...$args) public function data(string|null $key = null, ...$args)
{ {
if ($key === null) { if ($key === null) {
return $this->data; return $this->data;
@ -272,7 +234,7 @@ class Api
} }
// lazy-load data wrapped in Closures // lazy-load data wrapped in Closures
if (is_a($this->data[$key], 'Closure') === true) { if ($this->data[$key] instanceof Closure) {
return $this->data[$key]->call($this, ...$args); return $this->data[$key]->call($this, ...$args);
} }
@ -281,8 +243,6 @@ class Api
/** /**
* Returns the debugging flag * Returns the debugging flag
*
* @return bool
*/ */
public function debug(): bool public function debug(): bool
{ {
@ -291,9 +251,6 @@ class Api
/** /**
* Checks if injected data exists for the given key * Checks if injected data exists for the given key
*
* @param string $key
* @return bool
*/ */
public function hasData(string $key): bool public function hasData(string $key): bool
{ {
@ -305,39 +262,31 @@ class Api
* based on the `type` field * based on the `type` field
* *
* @param array models or collections * @param array models or collections
* @param mixed $object * @return string|null key of match
*
* @return string key of match
*/ */
protected function match(array $array, $object = null) protected function match(array $array, $object = null): string|null
{ {
foreach ($array as $definition => $model) { foreach ($array as $definition => $model) {
if (is_a($object, $model['type']) === true) { if ($object instanceof $model['type']) {
return $definition; return $definition;
} }
} }
return null;
} }
/** /**
* Returns an API model instance by name * Returns an API model instance by name
* *
* @param string|null $name
* @param mixed $object
* @return \Kirby\Api\Model
*
* @throws \Kirby\Exception\NotFoundException If no model for `$name` exists * @throws \Kirby\Exception\NotFoundException If no model for `$name` exists
*/ */
public function model(string $name = null, $object = null) public function model(string|null $name = null, $object = null): Model
{ {
// Try to auto-match object with API models // Try to auto-match object with API models
if ($name === null) { $name ??= $this->match($this->models, $object);
if ($model = $this->match($this->models, $object)) {
$name = $model;
}
}
if (isset($this->models[$name]) === false) { if (isset($this->models[$name]) === false) {
throw new NotFoundException(sprintf('The model "%s" does not exist', $name)); throw new NotFoundException(sprintf('The model "%s" does not exist', $name ?? 'NULL'));
} }
return new Model($this, $object, $this->models[$name]); return new Model($this, $object, $this->models[$name]);
@ -345,8 +294,6 @@ class Api
/** /**
* Returns all model definitions * Returns all model definitions
*
* @return array
*/ */
public function models(): array public function models(): array
{ {
@ -363,8 +310,11 @@ class Api
* @param mixed $default * @param mixed $default
* @return mixed * @return mixed
*/ */
public function requestData(string $type = null, string $key = null, $default = null) public function requestData(
{ string|null $type = null,
string|null $key = null,
$default = null
) {
if ($type === null) { if ($type === null) {
return $this->requestData; return $this->requestData;
} }
@ -381,58 +331,40 @@ class Api
/** /**
* Returns the request body if available * Returns the request body if available
*
* @param string|null $key
* @param mixed $default
* @return mixed
*/ */
public function requestBody(string $key = null, $default = null) public function requestBody(string|null $key = null, $default = null)
{ {
return $this->requestData('body', $key, $default); return $this->requestData('body', $key, $default);
} }
/** /**
* Returns the files from the request if available * Returns the files from the request if available
*
* @param string|null $key
* @param mixed $default
* @return mixed
*/ */
public function requestFiles(string $key = null, $default = null) public function requestFiles(string|null $key = null, $default = null)
{ {
return $this->requestData('files', $key, $default); return $this->requestData('files', $key, $default);
} }
/** /**
* Returns all headers from the request if available * Returns all headers from the request if available
*
* @param string|null $key
* @param mixed $default
* @return mixed
*/ */
public function requestHeaders(string $key = null, $default = null) public function requestHeaders(string|null $key = null, $default = null)
{ {
return $this->requestData('headers', $key, $default); return $this->requestData('headers', $key, $default);
} }
/** /**
* Returns the request method * Returns the request method
*
* @return string
*/ */
public function requestMethod(): string public function requestMethod(): string|null
{ {
return $this->requestMethod; return $this->requestMethod;
} }
/** /**
* Returns the request query if available * Returns the request query if available
*
* @param string|null $key
* @param mixed $default
* @return mixed
*/ */
public function requestQuery(string $key = null, $default = null) public function requestQuery(string|null $key = null, $default = null)
{ {
return $this->requestData('query', $key, $default); return $this->requestData('query', $key, $default);
} }
@ -441,14 +373,14 @@ class Api
* Turns a Kirby object into an * Turns a Kirby object into an
* API model or collection representation * API model or collection representation
* *
* @param mixed $object
* @return \Kirby\Api\Model|\Kirby\Api\Collection
*
* @throws \Kirby\Exception\NotFoundException If `$object` cannot be resolved * @throws \Kirby\Exception\NotFoundException If `$object` cannot be resolved
*/ */
public function resolve($object) public function resolve($object): Model|Collection
{ {
if (is_a($object, 'Kirby\Api\Model') === true || is_a($object, 'Kirby\Api\Collection') === true) { if (
$object instanceof Model ||
$object instanceof Collection
) {
return $object; return $object;
} }
@ -465,8 +397,6 @@ class Api
/** /**
* Returns all defined routes * Returns all defined routes
*
* @return array
*/ */
public function routes(): array public function routes(): array
{ {
@ -475,11 +405,9 @@ class Api
/** /**
* Setter for the authentication callback * Setter for the authentication callback
*
* @param \Closure|null $authentication
* @return $this * @return $this
*/ */
protected function setAuthentication(Closure $authentication = null) protected function setAuthentication(Closure|null $authentication = null): static
{ {
$this->authentication = $authentication; $this->authentication = $authentication;
return $this; return $this;
@ -487,11 +415,9 @@ class Api
/** /**
* Setter for the collections definition * Setter for the collections definition
*
* @param array|null $collections
* @return $this * @return $this
*/ */
protected function setCollections(array $collections = null) protected function setCollections(array|null $collections = null): static
{ {
if ($collections !== null) { if ($collections !== null) {
$this->collections = array_change_key_case($collections); $this->collections = array_change_key_case($collections);
@ -501,11 +427,9 @@ class Api
/** /**
* Setter for the injected data * Setter for the injected data
*
* @param array|null $data
* @return $this * @return $this
*/ */
protected function setData(array $data = null) protected function setData(array|null $data = null): static
{ {
$this->data = $data ?? []; $this->data = $data ?? [];
return $this; return $this;
@ -513,11 +437,9 @@ class Api
/** /**
* Setter for the debug flag * Setter for the debug flag
*
* @param bool $debug
* @return $this * @return $this
*/ */
protected function setDebug(bool $debug = false) protected function setDebug(bool $debug = false): static
{ {
$this->debug = $debug; $this->debug = $debug;
return $this; return $this;
@ -525,11 +447,9 @@ class Api
/** /**
* Setter for the model definitions * Setter for the model definitions
*
* @param array|null $models
* @return $this * @return $this
*/ */
protected function setModels(array $models = null) protected function setModels(array|null $models = null): static
{ {
if ($models !== null) { if ($models !== null) {
$this->models = array_change_key_case($models); $this->models = array_change_key_case($models);
@ -540,11 +460,9 @@ class Api
/** /**
* Setter for the request data * Setter for the request data
*
* @param array|null $requestData
* @return $this * @return $this
*/ */
protected function setRequestData(array $requestData = null) protected function setRequestData(array|null $requestData = null): static
{ {
$defaults = [ $defaults = [
'query' => [], 'query' => [],
@ -558,11 +476,9 @@ class Api
/** /**
* Setter for the request method * Setter for the request method
*
* @param string|null $requestMethod
* @return $this * @return $this
*/ */
protected function setRequestMethod(string $requestMethod = null) protected function setRequestMethod(string|null $requestMethod = null): static
{ {
$this->requestMethod = $requestMethod ?? 'GET'; $this->requestMethod = $requestMethod ?? 'GET';
return $this; return $this;
@ -570,11 +486,9 @@ class Api
/** /**
* Setter for the route definitions * Setter for the route definitions
*
* @param array|null $routes
* @return $this * @return $this
*/ */
protected function setRoutes(array $routes = null) protected function setRoutes(array|null $routes = null): static
{ {
$this->routes = $routes ?? []; $this->routes = $routes ?? [];
return $this; return $this;
@ -582,13 +496,8 @@ class Api
/** /**
* Renders the API call * Renders the API call
*
* @param string $path
* @param string $method
* @param array $requestData
* @return mixed
*/ */
public function render(string $path, $method = 'GET', array $requestData = []) public function render(string $path, string $method = 'GET', array $requestData = [])
{ {
try { try {
$result = $this->call($path, $method, $requestData); $result = $this->call($path, $method, $requestData);
@ -596,13 +505,12 @@ class Api
$result = $this->responseForException($e); $result = $this->responseForException($e);
} }
if ($result === null) { $result = match ($result) {
$result = $this->responseFor404(); null => $this->responseFor404(),
} elseif ($result === false) { false => $this->responseFor400(),
$result = $this->responseFor400(); true => $this->responseFor200(),
} elseif ($result === true) { default => $result
$result = $this->responseFor200(); };
}
if (is_array($result) === false) { if (is_array($result) === false) {
return $result; return $result;
@ -628,8 +536,6 @@ class Api
/** /**
* Returns a 200 - ok * Returns a 200 - ok
* response array. * response array.
*
* @return array
*/ */
public function responseFor200(): array public function responseFor200(): array
{ {
@ -643,8 +549,6 @@ class Api
/** /**
* Returns a 400 - bad request * Returns a 400 - bad request
* response array. * response array.
*
* @return array
*/ */
public function responseFor400(): array public function responseFor400(): array
{ {
@ -658,8 +562,6 @@ class Api
/** /**
* Returns a 404 - not found * Returns a 404 - not found
* response array. * response array.
*
* @return array
*/ */
public function responseFor404(): array public function responseFor404(): array
{ {
@ -674,9 +576,6 @@ class Api
* Creates the response array for * Creates the response array for
* an exception. Kirby exceptions will * an exception. Kirby exceptions will
* have more information * have more information
*
* @param \Throwable $e
* @return array
*/ */
public function responseForException(Throwable $e): array public function responseForException(Throwable $e): array
{ {
@ -696,11 +595,11 @@ class Api
'file' => F::relativepath($e->getFile(), $docRoot), 'file' => F::relativepath($e->getFile(), $docRoot),
'line' => $e->getLine(), 'line' => $e->getLine(),
'details' => [], 'details' => [],
'route' => $this->route ? $this->route->pattern() : null 'route' => $this->route?->pattern()
]; ];
// extend the information for Kirby Exceptions // extend the information for Kirby Exceptions
if (is_a($e, 'Kirby\Exception\Exception') === true) { if ($e instanceof ExceptionException) {
$result['key'] = $e->getKey(); $result['key'] = $e->getKey();
$result['details'] = $e->getDetails(); $result['details'] = $e->getDetails();
$result['code'] = $e->getHttpCode(); $result['code'] = $e->getHttpCode();
@ -726,14 +625,9 @@ class Api
* move_uploaded_file() not working with unit test * move_uploaded_file() not working with unit test
* Added debug parameter for testing purposes as we did in the Email class * Added debug parameter for testing purposes as we did in the Email class
* *
* @param \Closure $callback
* @param bool $single
* @param bool $debug
* @return array
*
* @throws \Exception If request has no files or there was an error with the upload * @throws \Exception If request has no files or there was an error with the upload
*/ */
public function upload(Closure $callback, $single = false, $debug = false): array public function upload(Closure $callback, bool $single = false, bool $debug = false): array
{ {
$trials = 0; $trials = 0;
$uploads = []; $uploads = [];
@ -757,13 +651,16 @@ class Api
if ($postMaxSize < $uploadMaxFileSize) { if ($postMaxSize < $uploadMaxFileSize) {
throw new Exception(I18n::translate('upload.error.iniPostSize')); throw new Exception(I18n::translate('upload.error.iniPostSize'));
} else {
throw new Exception(I18n::translate('upload.error.noFiles'));
} }
throw new Exception(I18n::translate('upload.error.noFiles'));
} }
foreach ($files as $upload) { foreach ($files as $upload) {
if (isset($upload['tmp_name']) === false && is_array($upload)) { if (
isset($upload['tmp_name']) === false &&
is_array($upload) === true
) {
continue; continue;
} }
@ -780,7 +677,10 @@ class Api
// try to detect the correct mime and add the extension // try to detect the correct mime and add the extension
// accordingly. This will avoid .tmp filenames // accordingly. This will avoid .tmp filenames
if (empty($extension) === true || in_array($extension, ['tmp', 'temp'])) { if (
empty($extension) === true ||
in_array($extension, ['tmp', 'temp']) === true
) {
$mime = F::mime($upload['tmp_name']); $mime = F::mime($upload['tmp_name']);
$extension = F::mimeToExtension($mime); $extension = F::mimeToExtension($mime);
$filename = F::name($upload['name']) . '.' . $extension; $filename = F::name($upload['name']) . '.' . $extension;
@ -792,7 +692,10 @@ class Api
// move the file to a location including the extension, // move the file to a location including the extension,
// for better mime detection // for better mime detection
if ($debug === false && move_uploaded_file($upload['tmp_name'], $source) === false) { if (
$debug === false &&
move_uploaded_file($upload['tmp_name'], $source) === false
) {
throw new Exception(I18n::translate('upload.error.cantMove')); throw new Exception(I18n::translate('upload.error.cantMove'));
} }

View file

@ -2,6 +2,7 @@
namespace Kirby\Api; namespace Kirby\Api;
use Closure;
use Exception; use Exception;
use Kirby\Toolkit\Str; use Kirby\Toolkit\Str;
@ -19,37 +20,15 @@ use Kirby\Toolkit\Str;
*/ */
class Collection class Collection
{ {
/** protected Api $api;
* @var \Kirby\Api\Api
*/
protected $api;
/**
* @var mixed|null
*/
protected $data; protected $data;
/**
* @var mixed|null
*/
protected $model; protected $model;
/**
* @var mixed|null
*/
protected $select; protected $select;
/**
* @var mixed|null
*/
protected $view; protected $view;
/** /**
* Collection constructor * Collection constructor
* *
* @param \Kirby\Api\Api $api
* @param mixed|null $data
* @param array $schema
* @throws \Exception * @throws \Exception
*/ */
public function __construct(Api $api, $data, array $schema) public function __construct(Api $api, $data, array $schema)
@ -57,10 +36,11 @@ class Collection
$this->api = $api; $this->api = $api;
$this->data = $data; $this->data = $data;
$this->model = $schema['model'] ?? null; $this->model = $schema['model'] ?? null;
$this->select = null;
$this->view = $schema['view'] ?? null; $this->view = $schema['view'] ?? null;
if ($data === null) { if ($data === null) {
if (is_a($schema['default'] ?? null, 'Closure') === false) { if (($schema['default'] ?? null) instanceof Closure === false) {
throw new Exception('Missing collection data'); throw new Exception('Missing collection data');
} }
@ -69,18 +49,17 @@ class Collection
if ( if (
isset($schema['type']) === true && isset($schema['type']) === true &&
is_a($this->data, $schema['type']) === false $this->data instanceof $schema['type'] === false
) { ) {
throw new Exception('Invalid collection type'); throw new Exception('Invalid collection type');
} }
} }
/** /**
* @param string|array|null $keys
* @return $this * @return $this
* @throws \Exception * @throws \Exception
*/ */
public function select($keys = null) public function select($keys = null): static
{ {
if ($keys === false) { if ($keys === false) {
return $this; return $this;
@ -99,7 +78,6 @@ class Collection
} }
/** /**
* @return array
* @throws \Kirby\Exception\NotFoundException * @throws \Kirby\Exception\NotFoundException
* @throws \Exception * @throws \Exception
*/ */
@ -125,7 +103,6 @@ class Collection
} }
/** /**
* @return array
* @throws \Kirby\Exception\NotFoundException * @throws \Kirby\Exception\NotFoundException
* @throws \Exception * @throws \Exception
*/ */
@ -167,10 +144,9 @@ class Collection
} }
/** /**
* @param string $view
* @return $this * @return $this
*/ */
public function view(string $view) public function view(string $view): static
{ {
$this->view = $view; $this->view = $view;
return $this; return $this;

View file

@ -2,6 +2,7 @@
namespace Kirby\Api; namespace Kirby\Api;
use Closure;
use Exception; use Exception;
use Kirby\Toolkit\Str; use Kirby\Toolkit\Str;
@ -21,37 +22,15 @@ use Kirby\Toolkit\Str;
*/ */
class Model class Model
{ {
/** protected Api $api;
* @var \Kirby\Api\Api
*/
protected $api;
/**
* @var mixed|null
*/
protected $data; protected $data;
/**
* @var array|mixed
*/
protected $fields; protected $fields;
/**
* @var mixed|null
*/
protected $select; protected $select;
/**
* @var array|mixed
*/
protected $views; protected $views;
/** /**
* Model constructor * Model constructor
* *
* @param \Kirby\Api\Api $api
* @param mixed $data
* @param array $schema
* @throws \Exception * @throws \Exception
*/ */
public function __construct(Api $api, $data, array $schema) public function __construct(Api $api, $data, array $schema)
@ -62,12 +41,15 @@ class Model
$this->select = $schema['select'] ?? null; $this->select = $schema['select'] ?? null;
$this->views = $schema['views'] ?? []; $this->views = $schema['views'] ?? [];
if ($this->select === null && array_key_exists('default', $this->views)) { if (
$this->select === null &&
array_key_exists('default', $this->views)
) {
$this->view('default'); $this->view('default');
} }
if ($data === null) { if ($data === null) {
if (is_a($schema['default'] ?? null, 'Closure') === false) { if (($schema['default'] ?? null) instanceof Closure === false) {
throw new Exception('Missing model data'); throw new Exception('Missing model data');
} }
@ -76,18 +58,17 @@ class Model
if ( if (
isset($schema['type']) === true && isset($schema['type']) === true &&
is_a($this->data, $schema['type']) === false $this->data instanceof $schema['type'] === false
) { ) {
throw new Exception(sprintf('Invalid model type "%s" expected: "%s"', get_class($this->data), $schema['type'])); throw new Exception(sprintf('Invalid model type "%s" expected: "%s"', get_class($this->data), $schema['type']));
} }
} }
/** /**
* @param null $keys
* @return $this * @return $this
* @throws \Exception * @throws \Exception
*/ */
public function select($keys = null) public function select($keys = null): static
{ {
if ($keys === false) { if ($keys === false) {
return $this; return $this;
@ -106,7 +87,6 @@ class Model
} }
/** /**
* @return array
* @throws \Exception * @throws \Exception
*/ */
public function selection(): array public function selection(): array
@ -153,7 +133,6 @@ class Model
} }
/** /**
* @return array
* @throws \Kirby\Exception\NotFoundException * @throws \Kirby\Exception\NotFoundException
* @throws \Exception * @throws \Exception
*/ */
@ -163,7 +142,10 @@ class Model
$result = []; $result = [];
foreach ($this->fields as $key => $resolver) { foreach ($this->fields as $key => $resolver) {
if (array_key_exists($key, $select) === false || is_a($resolver, 'Closure') === false) { if (
array_key_exists($key, $select) === false ||
$resolver instanceof Closure === false
) {
continue; continue;
} }
@ -174,8 +156,8 @@ class Model
} }
if ( if (
is_a($value, 'Kirby\Api\Collection') === true || $value instanceof Collection ||
is_a($value, 'Kirby\Api\Model') === true $value instanceof self
) { ) {
$selection = $select[$key]; $selection = $select[$key];
@ -199,7 +181,6 @@ class Model
} }
/** /**
* @return array
* @throws \Kirby\Exception\NotFoundException * @throws \Kirby\Exception\NotFoundException
* @throws \Exception * @throws \Exception
*/ */
@ -224,11 +205,10 @@ class Model
} }
/** /**
* @param string $name
* @return $this * @return $this
* @throws \Exception * @throws \Exception
*/ */
public function view(string $name) public function view(string $name): static
{ {
if ($name === 'any') { if ($name === 'any') {
return $this->select(null); return $this->select(null);

View file

@ -0,0 +1,90 @@
<?php
namespace Kirby\Blueprint;
use Kirby\Cms\Collection as BaseCollection;
use Kirby\Cms\ModelWithContent;
use Kirby\Toolkit\A;
use TypeError;
/**
* Typed collection
*
* @package Kirby Blueprint
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*
* // TODO: include in test coverage in 3.9
* @codeCoverageIgnore
*/
class Collection extends BaseCollection
{
/**
* The expected object type
*/
public const TYPE = Node::class;
public function __construct(array $objects = [])
{
foreach ($objects as $object) {
$this->__set($object->id, $object);
}
}
/**
* The Kirby Collection class only shows the key to
* avoid huge tress with dump, but for the blueprint
* collections this is really not useful
*/
public function __debugInfo(): array
{
return A::map($this->data, fn ($item) => (array)$item);
}
/**
* Validate the type of every item that is being
* added to the collection. They cneed to have
* the class defined by static::TYPE.
*/
public function __set(string $key, $value): void
{
if (
is_a($value, static::TYPE) === false
) {
throw new TypeError('Each value in the collection must be an instance of ' . static::TYPE);
}
parent::__set($key, $value);
}
public static function factory(array $items)
{
$collection = new static();
$className = static::TYPE;
foreach ($items as $id => $item) {
if (is_array($item) === true) {
$item['id'] ??= $id;
$item = $className::factory($item);
$collection->__set($item->id, $item);
} else {
$collection->__set($id, $className::factory($item));
}
}
return $collection;
}
public function render(ModelWithContent $model)
{
$props = [];
foreach ($this->data as $key => $item) {
$props[$key] = $item->render($model);
}
return $props;
}
}

View file

@ -0,0 +1,75 @@
<?php
namespace Kirby\Blueprint;
use Closure;
use Kirby\Cms\App;
use Kirby\Data\Yaml;
use Kirby\Exception\NotFoundException;
use Kirby\Filesystem\F;
/**
* Config
*
* @package Kirby Blueprint
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*
* // TODO: include in test coverage in 3.9
* @codeCoverageIgnore
*/
class Config
{
public string $file;
public string $id;
public string|array|Closure|null $plugin;
public string $root;
public function __construct(
public string $path
) {
$kirby = App::instance();
$this->id = basename($this->path);
$this->root = $kirby->root('blueprints');
$this->file = $this->root . '/' . $this->path . '.yml';
$this->plugin = $kirby->extension('blueprints', $this->path);
}
public function read(): array
{
if (F::exists($this->file, $this->root) === true) {
return $this->unpack($this->file);
}
return $this->unpack($this->plugin);
}
public function write(array $props): bool
{
return Yaml::write($this->file, $props);
}
public function unpack(string|array|Closure|null $extension): array
{
return match (true) {
// extension does not exist
is_null($extension)
=> throw new NotFoundException('"' . $this->path . '" could not be found'),
// extension is stored as a file path
is_string($extension)
=> Yaml::read($extension),
// extension is a callback to be resolved
is_callable($extension)
=> $extension(App::instance()),
// extension is already defined as array
default
=> $extension
};
}
}

View file

@ -0,0 +1,65 @@
<?php
namespace Kirby\Blueprint;
/**
* Extension
*
* @package Kirby Blueprint
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*
* // TODO: include in test coverage in 3.9
* @codeCoverageIgnore
*/
class Extension
{
public function __construct(
public string $path
) {
}
public static function apply(array $props): array
{
if (isset($props['extends']) === false) {
return $props;
}
// already extended
if (is_a($props['extends'], Extension::class) === true) {
return $props;
}
$extension = new static($props['extends']);
return $extension->extend($props);
}
public function extend(array $props): array
{
$props = array_replace_recursive(
$this->read(),
$props
);
$props['extends'] = $this;
return $props;
}
public static function factory(string|array $path): static
{
if (is_string($path) === true) {
return new static(path: $path);
}
return new static(...$path);
}
public function read(): array
{
$config = new Config($this->path);
return $config->read();
}
}

View file

@ -0,0 +1,119 @@
<?php
namespace Kirby\Blueprint;
use ReflectionException;
use ReflectionNamedType;
use ReflectionProperty;
use ReflectionUnionType;
/**
* Factory
*
* @package Kirby Blueprint
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*
* // TODO: include in test coverage in 3.9
* @codeCoverageIgnore
*/
class Factory
{
/**
* Resolves the properties by
* applying a map of factories (propName => class)
*/
public static function apply(array $properties, array $factories): array
{
foreach ($factories as $property => $class) {
// skip non-existing properties, empty properties
// or properties that are matching objects
if (
isset($properties[$property]) === false ||
$properties[$property] === null ||
is_a($properties[$property], $class) === true
) {
continue;
}
$properties[$property] = $class::factory($properties[$property]);
}
return $properties;
}
public static function forNamedType(ReflectionNamedType|null $type, $value)
{
// get the class name for the single type
$className = $type->getName();
// check if there's a factory for the value
if (method_exists($className, 'factory') === true) {
return $className::factory($value);
}
// try to assign the value directly and trust
// in PHP's type system.
return $value;
}
public static function forProperties(string $class, array $properties): array
{
foreach ($properties as $property => $value) {
try {
$properties[$property] = static::forProperty($class, $property, $value);
} catch (ReflectionException $e) {
// the property does not exist
unset($properties[$property]);
}
}
return $properties;
}
public static function forProperty(string $class, string $property, $value)
{
if (is_null($value) === true) {
return $value;
}
// instantly assign objects
// PHP's type system will find issues automatically
if (is_object($value) === true) {
return $value;
}
// get the type for the property
$reflection = new ReflectionProperty($class, $property);
$propType = $reflection->getType();
// no type given
if ($propType === null) {
return $value;
}
// union types
if (is_a($propType, ReflectionUnionType::class) === true) {
return static::forUnionType($propType, $value);
}
return static::forNamedType($propType, $value);
}
/**
* For properties with union types,
* the first named type is used to create
* the factory or pass a built-in value
*/
public static function forUnionType(ReflectionUnionType $type, $value)
{
return static::forNamedType($type->getTypes()[0], $value);
}
public static function make(string $class, array $properties): object
{
return new $class(...static::forProperties($class, $properties));
}
}

View file

@ -0,0 +1,118 @@
<?php
namespace Kirby\Blueprint;
use Kirby\Cms\ModelWithContent;
/**
* A node of the blueprint
*
* @package Kirby Blueprint
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*
* // TODO: include in test coverage in 3.9
* @codeCoverageIgnore
*/
class Node
{
public const TYPE = 'node';
public function __construct(
public string $id,
public Extension|null $extends = null,
) {
}
/**
* Dynamic getter for properties
*/
public function __call(string $name, array $args)
{
$this->defaults();
return $this->$name;
}
/**
* Apply default values
*/
public function defaults(): static
{
return $this;
}
/**
* Creates an instance by a set of array properties.
*/
public static function factory(array $props): static
{
$props = Extension::apply($props);
$props = static::polyfill($props);
return Factory::make(static::class, $props);
}
public static function load(string|array $props): static
{
// load by path
if (is_string($props) === true) {
$props = static::loadProps($props);
}
return static::factory($props);
}
public static function loadProps(string $path): array
{
$config = new Config($path);
$props = $config->read();
// add the id if it's not set yet
$props['id'] ??= basename($path);
return $props;
}
/**
* Optional method that runs before static::factory sends
* its properties to the instance. This is perfect to clean
* up props or keep deprecated props compatible.
*/
public static function polyfill(array $props): array
{
return $props;
}
public function render(ModelWithContent $model)
{
// apply default values
$this->defaults();
$array = [];
// go through all public properties
foreach (get_object_vars($this) as $key => $value) {
if (is_object($value) === false && is_resource($value) === false) {
$array[$key] = $value;
continue;
}
if (method_exists($value, 'render') === true) {
$array[$key] = $value->render($model);
}
}
return $array;
}
/**
* Universal setter for properties
*/
public function set(string $property, $value): static
{
$this->$property = Factory::forProperty(static::class, $property, $value);
return $this;
}
}

View file

@ -0,0 +1,44 @@
<?php
namespace Kirby\Blueprint;
use Kirby\Cms\ModelWithContent;
use Kirby\Toolkit\I18n;
/**
* Translatable node property
*
* @package Kirby Blueprint
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*
* // TODO: include in test coverage in 3.9
* @codeCoverageIgnore
*/
class NodeI18n extends NodeProperty
{
public function __construct(
public array $translations,
) {
}
public static function factory($value = null): static|null
{
if ($value === false || $value === null) {
return null;
}
if (is_array($value) === false) {
$value = ['en' => $value];
}
return new static($value);
}
public function render(ModelWithContent $model): string|null
{
return I18n::translate($this->translations, $this->translations);
}
}

View file

@ -0,0 +1,27 @@
<?php
namespace Kirby\Blueprint;
/**
* Custom emoji or icon from the Kirby iconset
*
* @package Kirby Blueprint
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*
* // TODO: include in test coverage in 3.9
* @codeCoverageIgnore
*/
class NodeIcon extends NodeString
{
public static function field()
{
$field = parent::field();
$field->id = 'icon';
$field->label->translations = ['en' => 'Icon'];
return $field;
}
}

View file

@ -0,0 +1,27 @@
<?php
namespace Kirby\Blueprint;
use Kirby\Cms\ModelWithContent;
/**
* Represents a property for a node
*
* @package Kirby Blueprint
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*
* // TODO: include in test coverage in 3.9
* @codeCoverageIgnore
*/
abstract class NodeProperty
{
abstract public static function factory($value = null): static|null;
public function render(ModelWithContent $model)
{
return null;
}
}

View file

@ -0,0 +1,39 @@
<?php
namespace Kirby\Blueprint;
use Kirby\Cms\ModelWithContent;
/**
* Simple string blueprint node
*
* @package Kirby Blueprint
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*
* // TODO: include in test coverage in 3.9
* @codeCoverageIgnore
*/
class NodeString extends NodeProperty
{
public function __construct(
public string $value,
) {
}
public static function factory($value = null): static|null
{
if ($value === null) {
return $value;
}
return new static($value);
}
public function render(ModelWithContent $model): string|null
{
return $this->value;
}
}

View file

@ -0,0 +1,30 @@
<?php
namespace Kirby\Blueprint;
use Kirby\Cms\ModelWithContent;
/**
* The text node is translatable
* and will parse query template strings
*
* @package Kirby Blueprint
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*
* // TODO: include in test coverage in 3.9
* @codeCoverageIgnore
*/
class NodeText extends NodeI18n
{
public function render(ModelWithContent $model): ?string
{
if ($text = parent::render($model)) {
return $model->toSafeString($text);
}
return $text;
}
}

View file

@ -15,11 +15,17 @@ use APCUIterator;
*/ */
class ApcuCache extends Cache class ApcuCache extends Cache
{ {
/**
* Returns whether the cache is ready to
* store values
*/
public function enabled(): bool
{
return apcu_enabled();
}
/** /**
* Determines if an item exists in the cache * Determines if an item exists in the cache
*
* @param string $key
* @return bool
*/ */
public function exists(string $key): bool public function exists(string $key): bool
{ {
@ -29,24 +35,19 @@ class ApcuCache extends Cache
/** /**
* Flushes the entire cache and returns * Flushes the entire cache and returns
* whether the operation was successful * whether the operation was successful
*
* @return bool
*/ */
public function flush(): bool public function flush(): bool
{ {
if (empty($this->options['prefix']) === false) { if (empty($this->options['prefix']) === false) {
return apcu_delete(new APCUIterator('!^' . preg_quote($this->options['prefix']) . '!')); return apcu_delete(new APCUIterator('!^' . preg_quote($this->options['prefix']) . '!'));
} else {
return apcu_clear_cache();
} }
return apcu_clear_cache();
} }
/** /**
* Removes an item from the cache and returns * Removes an item from the cache and returns
* whether the operation was successful * whether the operation was successful
*
* @param string $key
* @return bool
*/ */
public function remove(string $key): bool public function remove(string $key): bool
{ {
@ -56,13 +57,11 @@ class ApcuCache extends Cache
/** /**
* Internal method to retrieve the raw cache value; * Internal method to retrieve the raw cache value;
* needs to return a Value object or null if not found * needs to return a Value object or null if not found
*
* @param string $key
* @return \Kirby\Cache\Value|null
*/ */
public function retrieve(string $key) public function retrieve(string $key): Value|null
{ {
return Value::fromJson(apcu_fetch($this->key($key))); $value = apcu_fetch($this->key($key));
return Value::fromJson($value);
} }
/** /**
@ -73,14 +72,12 @@ class ApcuCache extends Cache
* // put an item in the cache for 15 minutes * // put an item in the cache for 15 minutes
* $cache->set('value', 'my value', 15); * $cache->set('value', 'my value', 15);
* </code> * </code>
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return bool
*/ */
public function set(string $key, $value, int $minutes = 0): bool public function set(string $key, $value, int $minutes = 0): bool
{ {
return apcu_store($this->key($key), (new Value($value, $minutes))->toJson(), $this->expiration($minutes)); $key = $this->key($key);
$value = (new Value($value, $minutes))->toJson();
$expires = $this->expiration($minutes);
return apcu_store($key, $value, $expires);
} }
} }

View file

@ -2,6 +2,8 @@
namespace Kirby\Cache; namespace Kirby\Cache;
use Closure;
/** /**
* Cache foundation * Cache foundation
* This abstract class is used as * This abstract class is used as
@ -18,14 +20,11 @@ abstract class Cache
{ {
/** /**
* Stores all options for the driver * Stores all options for the driver
* @var array
*/ */
protected $options = []; protected array $options = [];
/** /**
* Sets all parameters which are needed to connect to the cache storage * Sets all parameters which are needed to connect to the cache storage
*
* @param array $options
*/ */
public function __construct(array $options = []) public function __construct(array $options = [])
{ {
@ -33,87 +32,47 @@ abstract class Cache
} }
/** /**
* Writes an item to the cache for a given number of minutes and * Checks when the cache has been created;
* returns whether the operation was successful; * returns the creation timestamp on success
* this needs to be defined by the driver * and false if the item does not exist
*
* <code>
* // put an item in the cache for 15 minutes
* $cache->set('value', 'my value', 15);
* </code>
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return bool
*/ */
abstract public function set(string $key, $value, int $minutes = 0): bool; public function created(string $key): int|false
/**
* Adds the prefix to the key if given
*
* @param string $key
* @return string
*/
protected function key(string $key): string
{ {
if (empty($this->options['prefix']) === false) { // get the Value object
$key = $this->options['prefix'] . '/' . $key;
}
return $key;
}
/**
* Internal method to retrieve the raw cache value;
* needs to return a Value object or null if not found;
* this needs to be defined by the driver
*
* @param string $key
* @return \Kirby\Cache\Value|null
*/
abstract public function retrieve(string $key);
/**
* Gets an item from the cache
*
* <code>
* // get an item from the cache driver
* $value = $cache->get('value');
*
* // return a default value if the requested item isn't cached
* $value = $cache->get('value', 'default value');
* </code>
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function get(string $key, $default = null)
{
// get the Value
$value = $this->retrieve($key); $value = $this->retrieve($key);
// check for a valid cache value // check for a valid Value object
if (!is_a($value, 'Kirby\Cache\Value')) { if ($value instanceof Value === false) {
return $default; return false;
} }
// remove the item if it is expired // return the expires timestamp
if ($value->expires() > 0 && time() >= $value->expires()) { return $value->created();
$this->remove($key);
return $default;
} }
// return the pure value /**
return $value->value(); * Returns whether the cache is ready to
* store values
*/
public function enabled(): bool
{
// TODO: Make this method abstract in a future
// release to ensure that cache drivers override it;
// until then, we assume that the cache is enabled
return true;
} }
/**
* Determines if an item exists in the cache
*/
public function exists(string $key): bool
{
return $this->expired($key) === false;
}
/** /**
* Calculates the expiration timestamp * Calculates the expiration timestamp
*
* @param int $minutes
* @return int
*/ */
protected function expiration(int $minutes = 0): int protected function expiration(int $minutes = 0): int
{ {
@ -130,17 +89,14 @@ abstract class Cache
* Checks when an item in the cache expires; * Checks when an item in the cache expires;
* returns the expiry timestamp on success, null if the * returns the expiry timestamp on success, null if the
* item never expires and false if the item does not exist * item never expires and false if the item does not exist
*
* @param string $key
* @return int|null|false
*/ */
public function expires(string $key) public function expires(string $key): int|false|null
{ {
// get the Value object // get the Value object
$value = $this->retrieve($key); $value = $this->retrieve($key);
// check for a valid Value object // check for a valid Value object
if (!is_a($value, 'Kirby\Cache\Value')) { if ($value instanceof Value === false) {
return false; return false;
} }
@ -150,9 +106,6 @@ abstract class Cache
/** /**
* Checks if an item in the cache is expired * Checks if an item in the cache is expired
*
* @param string $key
* @return bool
*/ */
public function expired(string $key): bool public function expired(string $key): bool
{ {
@ -160,83 +113,126 @@ abstract class Cache
if ($expires === null) { if ($expires === null) {
return false; return false;
} elseif (!is_int($expires)) {
return true;
} else {
return time() >= $expires;
} }
if (is_int($expires) === false) {
return true;
}
return time() >= $expires;
} }
/** /**
* Checks when the cache has been created; * Flushes the entire cache and returns
* returns the creation timestamp on success * whether the operation was successful;
* and false if the item does not exist * this needs to be defined by the driver
*
* @param string $key
* @return int|false
*/ */
public function created(string $key) abstract public function flush(): bool;
/**
* Gets an item from the cache
*
* <code>
* // get an item from the cache driver
* $value = $cache->get('value');
*
* // return a default value if the requested item isn't cached
* $value = $cache->get('value', 'default value');
* </code>
*/
public function get(string $key, $default = null)
{ {
// get the Value object // get the Value
$value = $this->retrieve($key); $value = $this->retrieve($key);
// check for a valid Value object // check for a valid cache value
if (!is_a($value, 'Kirby\Cache\Value')) { if ($value instanceof Value === false) {
return false; return $default;
} }
// return the expires timestamp // remove the item if it is expired
return $value->created(); if ($value->expires() > 0 && time() >= $value->expires()) {
$this->remove($key);
return $default;
}
// return the pure value
return $value->value();
}
/**
* Returns a value by either getting it from the cache
* or via the callback function which then is stored in
* the cache for future retrieval. This method cannot be
* used for `null` as value to be cached.
* @since 3.8.0
*/
public function getOrSet(
string $key,
Closure $result,
int $minutes = 0
) {
$value = $this->get($key);
$result = $value ?? $result();
if ($value === null) {
$this->set($key, $result, $minutes);
}
return $result;
}
/**
* Adds the prefix to the key if given
*/
protected function key(string $key): string
{
if (empty($this->options['prefix']) === false) {
$key = $this->options['prefix'] . '/' . $key;
}
return $key;
} }
/** /**
* Alternate version for Cache::created($key) * Alternate version for Cache::created($key)
*
* @param string $key
* @return int|false
*/ */
public function modified(string $key) public function modified(string $key): int|false
{ {
return static::created($key); return static::created($key);
} }
/** /**
* Determines if an item exists in the cache * Returns all passed cache options
*
* @param string $key
* @return bool
*/ */
public function exists(string $key): bool public function options(): array
{ {
return $this->expired($key) === false; return $this->options;
} }
/** /**
* Removes an item from the cache and returns * Removes an item from the cache and returns
* whether the operation was successful; * whether the operation was successful;
* this needs to be defined by the driver * this needs to be defined by the driver
*
* @param string $key
* @return bool
*/ */
abstract public function remove(string $key): bool; abstract public function remove(string $key): bool;
/** /**
* Flushes the entire cache and returns * Internal method to retrieve the raw cache value;
* whether the operation was successful; * needs to return a Value object or null if not found;
* this needs to be defined by the driver * this needs to be defined by the driver
*
* @return bool
*/ */
abstract public function flush(): bool; abstract public function retrieve(string $key): Value|null;
/** /**
* Returns all passed cache options * Writes an item to the cache for a given number of minutes and
* returns whether the operation was successful;
* this needs to be defined by the driver
* *
* @return array * <code>
* // put an item in the cache for 15 minutes
* $cache->set('value', 'my value', 15);
* </code>
*/ */
public function options(): array abstract public function set(string $key, $value, int $minutes = 0): bool;
{
return $this->options;
}
} }

View file

@ -20,10 +20,8 @@ class FileCache extends Cache
{ {
/** /**
* Full root including prefix * Full root including prefix
*
* @var string
*/ */
protected $root; protected string $root;
/** /**
* Sets all parameters which are needed for the file cache * Sets all parameters which are needed for the file cache
@ -44,6 +42,7 @@ class FileCache extends Cache
// build the full root including prefix // build the full root including prefix
$this->root = $this->options['root']; $this->root = $this->options['root'];
if (empty($this->options['prefix']) === false) { if (empty($this->options['prefix']) === false) {
$this->root .= '/' . $this->options['prefix']; $this->root .= '/' . $this->options['prefix'];
} }
@ -52,10 +51,17 @@ class FileCache extends Cache
Dir::make($this->root, true); Dir::make($this->root, true);
} }
/**
* Returns whether the cache is ready to
* store values
*/
public function enabled(): bool
{
return is_writable($this->root) === true;
}
/** /**
* Returns the full root including prefix * Returns the full root including prefix
*
* @return string
*/ */
public function root(): string public function root(): string
{ {
@ -64,9 +70,6 @@ class FileCache extends Cache
/** /**
* Returns the full path to a file for a given key * Returns the full path to a file for a given key
*
* @param string $key
* @return string
*/ */
protected function file(string $key): string protected function file(string $key): string
{ {
@ -108,9 +111,9 @@ class FileCache extends Cache
if (isset($this->options['extension'])) { if (isset($this->options['extension'])) {
return $file . '.' . $this->options['extension']; return $file . '.' . $this->options['extension'];
} else {
return $file;
} }
return $file;
} }
/** /**
@ -121,11 +124,6 @@ class FileCache extends Cache
* // put an item in the cache for 15 minutes * // put an item in the cache for 15 minutes
* $cache->set('value', 'my value', 15); * $cache->set('value', 'my value', 15);
* </code> * </code>
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return bool
*/ */
public function set(string $key, $value, int $minutes = 0): bool public function set(string $key, $value, int $minutes = 0): bool
{ {
@ -137,11 +135,8 @@ class FileCache extends Cache
/** /**
* Internal method to retrieve the raw cache value; * Internal method to retrieve the raw cache value;
* needs to return a Value object or null if not found * needs to return a Value object or null if not found
*
* @param string $key
* @return \Kirby\Cache\Value|null
*/ */
public function retrieve(string $key) public function retrieve(string $key): Value|null
{ {
$file = $this->file($key); $file = $this->file($key);
$value = F::read($file); $value = F::read($file);
@ -153,11 +148,8 @@ class FileCache extends Cache
* Checks when the cache has been created; * Checks when the cache has been created;
* returns the creation timestamp on success * returns the creation timestamp on success
* and false if the item does not exist * and false if the item does not exist
*
* @param string $key
* @return mixed
*/ */
public function created(string $key) public function created(string $key): int|false
{ {
// use the modification timestamp // use the modification timestamp
// as indicator when the cache has been created/overwritten // as indicator when the cache has been created/overwritten
@ -165,15 +157,12 @@ class FileCache extends Cache
// get the file for this cache key // get the file for this cache key
$file = $this->file($key); $file = $this->file($key);
return file_exists($file) ? filemtime($this->file($key)) : false; return file_exists($file) ? filemtime($file) : false;
} }
/** /**
* Removes an item from the cache and returns * Removes an item from the cache and returns
* whether the operation was successful * whether the operation was successful
*
* @param string $key
* @return bool
*/ */
public function remove(string $key): bool public function remove(string $key): bool
{ {
@ -190,9 +179,6 @@ class FileCache extends Cache
/** /**
* Removes empty directories safely by checking each directory * Removes empty directories safely by checking each directory
* up to the root directory * up to the root directory
*
* @param string $dir
* @return void
*/ */
protected function removeEmptyDirectories(string $dir): void protected function removeEmptyDirectories(string $dir): void
{ {
@ -202,7 +188,13 @@ class FileCache extends Cache
// checks all directory segments until reaching the root directory // checks all directory segments until reaching the root directory
while (Str::startsWith($dir, $this->root()) === true && $dir !== $this->root()) { while (Str::startsWith($dir, $this->root()) === true && $dir !== $this->root()) {
$files = array_diff(scandir($dir) ?? [], ['.', '..']); $files = scandir($dir);
if ($files === false) {
$files = []; // @codeCoverageIgnore
}
$files = array_diff($files, ['.', '..']);
if (empty($files) === true && Dir::remove($dir) === true) { if (empty($files) === true && Dir::remove($dir) === true) {
// continue with the next level up // continue with the next level up
@ -212,7 +204,7 @@ class FileCache extends Cache
break; break;
} }
} }
} catch (Exception $e) { // @codeCoverageIgnore } catch (Exception) { // @codeCoverageIgnore
// silently stops the process // silently stops the process
} }
} }
@ -220,12 +212,13 @@ class FileCache extends Cache
/** /**
* Flushes the entire cache and returns * Flushes the entire cache and returns
* whether the operation was successful * whether the operation was successful
*
* @return bool
*/ */
public function flush(): bool public function flush(): bool
{ {
if (Dir::remove($this->root) === true && Dir::make($this->root) === true) { if (
Dir::remove($this->root) === true &&
Dir::make($this->root) === true
) {
return true; return true;
} }

Some files were not shown because too many files have changed in this diff Show more