├── .browserslistrc ├── .editorconfig ├── .env.example ├── .eslintrc.js ├── .gitignore ├── .htaccess ├── README.md ├── babel.config.js ├── composer.json ├── content ├── 1_projects │ ├── 1_rgb-255-0-0 │ │ └── project.txt │ ├── 2_rgb-0-255-255 │ │ └── project.txt │ ├── 3_rgb-0-0-255 │ │ └── project.txt │ ├── 4_rgb-255-255-0 │ │ └── project.txt │ ├── 5_rgb-0-255-0 │ │ └── project.txt │ ├── 6_rgb-255-0-255 │ │ └── project.txt │ └── projects.txt ├── 2_about │ └── default.txt ├── home │ └── home.txt └── site.txt ├── index.php ├── kirby ├── .editorconfig ├── SECURITY.md ├── assets │ └── whoops.css ├── bootstrap.php ├── cacert.pem ├── composer.json ├── composer.lock ├── config │ ├── aliases.php │ ├── api │ │ ├── authentication.php │ │ ├── collections.php │ │ ├── models.php │ │ ├── models │ │ │ ├── File.php │ │ │ ├── FileBlueprint.php │ │ │ ├── FileVersion.php │ │ │ ├── Language.php │ │ │ ├── Page.php │ │ │ ├── PageBlueprint.php │ │ │ ├── Role.php │ │ │ ├── Site.php │ │ │ ├── SiteBlueprint.php │ │ │ ├── System.php │ │ │ ├── Translation.php │ │ │ ├── User.php │ │ │ └── UserBlueprint.php │ │ ├── routes.php │ │ └── routes │ │ │ ├── auth.php │ │ │ ├── files.php │ │ │ ├── languages.php │ │ │ ├── lock.php │ │ │ ├── pages.php │ │ │ ├── roles.php │ │ │ ├── site.php │ │ │ ├── system.php │ │ │ ├── translations.php │ │ │ └── users.php │ ├── blocks │ │ ├── code │ │ │ ├── code.php │ │ │ └── code.yml │ │ ├── gallery │ │ │ ├── gallery.php │ │ │ └── gallery.yml │ │ ├── heading │ │ │ ├── heading.php │ │ │ └── heading.yml │ │ ├── image │ │ │ ├── image.php │ │ │ └── image.yml │ │ ├── list │ │ │ ├── list.php │ │ │ └── list.yml │ │ ├── markdown │ │ │ ├── markdown.php │ │ │ └── markdown.yml │ │ ├── quote │ │ │ ├── quote.php │ │ │ └── quote.yml │ │ ├── table │ │ │ └── table.yml │ │ ├── text │ │ │ ├── text.php │ │ │ └── text.yml │ │ └── video │ │ │ ├── video.php │ │ │ └── video.yml │ ├── blueprints.php │ ├── blueprints │ │ ├── blocks │ │ │ ├── code.yml │ │ │ ├── heading.yml │ │ │ ├── image.yml │ │ │ ├── quote.yml │ │ │ ├── table.yml │ │ │ ├── text.yml │ │ │ └── video.yml │ │ ├── files │ │ │ └── default.yml │ │ ├── pages │ │ │ └── default.yml │ │ └── site.yml │ ├── components.php │ ├── fields.php │ ├── fields │ │ ├── checkboxes.php │ │ ├── date.php │ │ ├── email.php │ │ ├── files.php │ │ ├── gap.php │ │ ├── headline.php │ │ ├── hidden.php │ │ ├── info.php │ │ ├── line.php │ │ ├── list.php │ │ ├── mixins │ │ │ ├── datetime.php │ │ │ ├── filepicker.php │ │ │ ├── min.php │ │ │ ├── options.php │ │ │ ├── pagepicker.php │ │ │ ├── picker.php │ │ │ ├── upload.php │ │ │ └── userpicker.php │ │ ├── multiselect.php │ │ ├── number.php │ │ ├── pages.php │ │ ├── radio.php │ │ ├── range.php │ │ ├── select.php │ │ ├── structure.php │ │ ├── tags.php │ │ ├── tel.php │ │ ├── text.php │ │ ├── textarea.php │ │ ├── time.php │ │ ├── toggle.php │ │ ├── url.php │ │ ├── users.php │ │ └── writer.php │ ├── helpers.php │ ├── methods.php │ ├── presets │ │ ├── files.php │ │ ├── page.php │ │ └── pages.php │ ├── roots.php │ ├── routes.php │ ├── sections │ │ ├── fields.php │ │ ├── files.php │ │ ├── info.php │ │ ├── mixins │ │ │ ├── empty.php │ │ │ ├── headline.php │ │ │ ├── help.php │ │ │ ├── layout.php │ │ │ ├── max.php │ │ │ ├── min.php │ │ │ ├── pagination.php │ │ │ └── parent.php │ │ └── pages.php │ ├── setup.php │ ├── snippets.php │ ├── tags.php │ ├── templates.php │ ├── templates │ │ └── emails │ │ │ └── auth │ │ │ ├── login.php │ │ │ └── password-reset.php │ └── urls.php ├── dependencies │ ├── parsedown-extra │ │ └── ParsedownExtra.php │ └── parsedown │ │ └── Parsedown.php ├── i18n │ ├── rules │ │ ├── LICENSE │ │ ├── ar.json │ │ ├── az.json │ │ ├── bg.json │ │ ├── cs.json │ │ ├── da.json │ │ ├── de.json │ │ ├── el.json │ │ ├── eo.json │ │ ├── et.json │ │ ├── fa.json │ │ ├── fi.json │ │ ├── fr.json │ │ ├── hi.json │ │ ├── hr.json │ │ ├── hu.json │ │ ├── hy.json │ │ ├── it.json │ │ ├── ja.json │ │ ├── ka.json │ │ ├── ko.json │ │ ├── lt.json │ │ ├── lv.json │ │ ├── mk.json │ │ ├── my.json │ │ ├── nb.json │ │ ├── pl.json │ │ ├── pt_BR.json │ │ ├── rm.json │ │ ├── ru.json │ │ ├── sr.json │ │ ├── sv_SE.json │ │ ├── tr.json │ │ ├── uk.json │ │ ├── vi.json │ │ └── zh.json │ └── translations │ │ ├── bg.json │ │ ├── ca.json │ │ ├── cs.json │ │ ├── da.json │ │ ├── de.json │ │ ├── el.json │ │ ├── en.json │ │ ├── es_419.json │ │ ├── es_ES.json │ │ ├── fa.json │ │ ├── fi.json │ │ ├── fr.json │ │ ├── hu.json │ │ ├── id.json │ │ ├── it.json │ │ ├── ko.json │ │ ├── lt.json │ │ ├── nb.json │ │ ├── nl.json │ │ ├── pl.json │ │ ├── pt_BR.json │ │ ├── pt_PT.json │ │ ├── ru.json │ │ ├── sk.json │ │ ├── sv_SE.json │ │ └── tr.json ├── kirby.pub ├── panel │ └── dist │ │ ├── apple-touch-icon.png │ │ ├── css │ │ └── app.css │ │ ├── favicon.png │ │ ├── favicon.svg │ │ ├── img │ │ └── icons.svg │ │ └── js │ │ ├── app.js │ │ ├── plugins.js │ │ └── vendor.js ├── router.php ├── src │ ├── Api │ │ ├── Api.php │ │ ├── Collection.php │ │ └── Model.php │ ├── Cache │ │ ├── ApcuCache.php │ │ ├── Cache.php │ │ ├── FileCache.php │ │ ├── MemCached.php │ │ ├── MemoryCache.php │ │ ├── NullCache.php │ │ └── Value.php │ ├── Cms │ │ ├── Api.php │ │ ├── App.php │ │ ├── AppCaches.php │ │ ├── AppErrors.php │ │ ├── AppPlugins.php │ │ ├── AppTranslations.php │ │ ├── AppUsers.php │ │ ├── Asset.php │ │ ├── Auth.php │ │ ├── Auth │ │ │ ├── Challenge.php │ │ │ ├── EmailChallenge.php │ │ │ └── Status.php │ │ ├── Block.php │ │ ├── BlockConverter.php │ │ ├── Blocks.php │ │ ├── Blueprint.php │ │ ├── Collection.php │ │ ├── Collections.php │ │ ├── Content.php │ │ ├── ContentLock.php │ │ ├── ContentLocks.php │ │ ├── ContentTranslation.php │ │ ├── Dir.php │ │ ├── Email.php │ │ ├── Event.php │ │ ├── Field.php │ │ ├── Fieldset.php │ │ ├── Fieldsets.php │ │ ├── File.php │ │ ├── FileActions.php │ │ ├── FileBlueprint.php │ │ ├── FileFoundation.php │ │ ├── FileModifications.php │ │ ├── FilePermissions.php │ │ ├── FilePicker.php │ │ ├── FileRules.php │ │ ├── FileVersion.php │ │ ├── Filename.php │ │ ├── Files.php │ │ ├── Form.php │ │ ├── HasChildren.php │ │ ├── HasFiles.php │ │ ├── HasMethods.php │ │ ├── HasSiblings.php │ │ ├── Html.php │ │ ├── Ingredients.php │ │ ├── Item.php │ │ ├── Items.php │ │ ├── KirbyTag.php │ │ ├── KirbyTags.php │ │ ├── Language.php │ │ ├── LanguageRouter.php │ │ ├── LanguageRoutes.php │ │ ├── LanguageRules.php │ │ ├── Languages.php │ │ ├── Layout.php │ │ ├── LayoutColumn.php │ │ ├── LayoutColumns.php │ │ ├── Layouts.php │ │ ├── Media.php │ │ ├── Model.php │ │ ├── ModelPermissions.php │ │ ├── ModelWithContent.php │ │ ├── Nest.php │ │ ├── NestCollection.php │ │ ├── NestObject.php │ │ ├── Page.php │ │ ├── PageActions.php │ │ ├── PageBlueprint.php │ │ ├── PagePermissions.php │ │ ├── PagePicker.php │ │ ├── PageRules.php │ │ ├── PageSiblings.php │ │ ├── Pages.php │ │ ├── Pagination.php │ │ ├── Panel.php │ │ ├── PanelPlugins.php │ │ ├── Permissions.php │ │ ├── Picker.php │ │ ├── Plugin.php │ │ ├── PluginAssets.php │ │ ├── R.php │ │ ├── Responder.php │ │ ├── Response.php │ │ ├── Role.php │ │ ├── Roles.php │ │ ├── S.php │ │ ├── Search.php │ │ ├── Section.php │ │ ├── Site.php │ │ ├── SiteActions.php │ │ ├── SiteBlueprint.php │ │ ├── SitePermissions.php │ │ ├── SiteRules.php │ │ ├── Structure.php │ │ ├── StructureObject.php │ │ ├── System.php │ │ ├── Template.php │ │ ├── Translation.php │ │ ├── Translations.php │ │ ├── Url.php │ │ ├── User.php │ │ ├── UserActions.php │ │ ├── UserBlueprint.php │ │ ├── UserPermissions.php │ │ ├── UserPicker.php │ │ ├── UserRules.php │ │ ├── Users.php │ │ └── Visitor.php │ ├── Data │ │ ├── Data.php │ │ ├── Handler.php │ │ ├── Json.php │ │ ├── PHP.php │ │ ├── Txt.php │ │ ├── Xml.php │ │ └── Yaml.php │ ├── Database │ │ ├── Database.php │ │ ├── Db.php │ │ ├── Query.php │ │ ├── Sql.php │ │ └── Sql │ │ │ ├── Mysql.php │ │ │ └── Sqlite.php │ ├── Email │ │ ├── Body.php │ │ ├── Email.php │ │ └── PHPMailer.php │ ├── Exception │ │ ├── BadMethodCallException.php │ │ ├── DuplicateException.php │ │ ├── ErrorPageException.php │ │ ├── Exception.php │ │ ├── InvalidArgumentException.php │ │ ├── LogicException.php │ │ ├── NotFoundException.php │ │ └── PermissionException.php │ ├── Form │ │ ├── Field.php │ │ ├── Field │ │ │ ├── BlocksField.php │ │ │ └── LayoutField.php │ │ ├── FieldClass.php │ │ ├── Fields.php │ │ ├── Form.php │ │ ├── Mixin │ │ │ ├── EmptyState.php │ │ │ ├── Max.php │ │ │ └── Min.php │ │ ├── Options.php │ │ ├── OptionsApi.php │ │ ├── OptionsQuery.php │ │ └── Validations.php │ ├── Http │ │ ├── Cookie.php │ │ ├── Exceptions │ │ │ └── NextRouteException.php │ │ ├── Header.php │ │ ├── Idn.php │ │ ├── Params.php │ │ ├── Path.php │ │ ├── Query.php │ │ ├── Remote.php │ │ ├── Request.php │ │ ├── Request │ │ │ ├── Auth │ │ │ │ ├── BasicAuth.php │ │ │ │ └── BearerAuth.php │ │ │ ├── Body.php │ │ │ ├── Data.php │ │ │ ├── Files.php │ │ │ └── Query.php │ │ ├── Response.php │ │ ├── Route.php │ │ ├── Router.php │ │ ├── Server.php │ │ ├── Uri.php │ │ ├── Url.php │ │ └── Visitor.php │ ├── Image │ │ ├── Camera.php │ │ ├── Darkroom.php │ │ ├── Darkroom │ │ │ ├── GdLib.php │ │ │ └── ImageMagick.php │ │ ├── Dimensions.php │ │ ├── Exif.php │ │ ├── Image.php │ │ └── Location.php │ ├── Parsley │ │ ├── Element.php │ │ ├── Inline.php │ │ ├── Parsley.php │ │ ├── Schema.php │ │ └── Schema │ │ │ ├── Blocks.php │ │ │ └── Plain.php │ ├── Sane │ │ ├── Handler.php │ │ ├── Sane.php │ │ ├── Svg.php │ │ ├── Svgz.php │ │ └── Xml.php │ ├── Session │ │ ├── AutoSession.php │ │ ├── FileSessionStore.php │ │ ├── Session.php │ │ ├── SessionData.php │ │ ├── SessionStore.php │ │ └── Sessions.php │ ├── Text │ │ ├── KirbyTag.php │ │ ├── KirbyTags.php │ │ ├── Markdown.php │ │ └── SmartyPants.php │ └── Toolkit │ │ ├── A.php │ │ ├── Collection.php │ │ ├── Component.php │ │ ├── Config.php │ │ ├── Controller.php │ │ ├── Dir.php │ │ ├── Escape.php │ │ ├── F.php │ │ ├── Facade.php │ │ ├── File.php │ │ ├── Html.php │ │ ├── I18n.php │ │ ├── Iterator.php │ │ ├── Locale.php │ │ ├── Mime.php │ │ ├── Obj.php │ │ ├── Pagination.php │ │ ├── Properties.php │ │ ├── Query.php │ │ ├── Silo.php │ │ ├── Str.php │ │ ├── Tpl.php │ │ ├── V.php │ │ ├── View.php │ │ └── Xml.php └── views │ ├── fatal.php │ ├── panel.php │ ├── php.php │ └── snippets │ ├── footer.php │ └── header.php ├── package.json ├── postcss.config.js ├── public ├── favicon.ico └── index.html ├── robots.txt ├── site ├── accounts │ └── index.html ├── blueprints │ ├── files │ │ ├── default.yml │ │ └── image.yml │ ├── pages │ │ ├── default.yml │ │ ├── project.yml │ │ └── projects.yml │ ├── site.yml │ ├── tabs │ │ ├── media.yml │ │ └── meta.yml │ └── users │ │ ├── admin.yml │ │ ├── api.yml │ │ ├── default.yml │ │ └── editor.yml ├── config │ └── config.php ├── plugins │ └── kql │ │ ├── .editorconfig │ │ ├── .github │ │ └── FUNDING.yml │ │ ├── .gitignore │ │ ├── .php_cs │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── composer.json │ │ ├── composer.lock │ │ ├── index.php │ │ ├── phpunit.xml.dist │ │ ├── src │ │ └── Kql │ │ │ ├── Help.php │ │ │ ├── Interceptor.php │ │ │ ├── Interceptors │ │ │ ├── Cms │ │ │ │ ├── App.php │ │ │ │ ├── Block.php │ │ │ │ ├── Blocks.php │ │ │ │ ├── Blueprint.php │ │ │ │ ├── Collection.php │ │ │ │ ├── Content.php │ │ │ │ ├── Field.php │ │ │ │ ├── File.php │ │ │ │ ├── FileVersion.php │ │ │ │ ├── Files.php │ │ │ │ ├── Layout.php │ │ │ │ ├── LayoutColumn.php │ │ │ │ ├── LayoutColumns.php │ │ │ │ ├── Layouts.php │ │ │ │ ├── Model.php │ │ │ │ ├── Page.php │ │ │ │ ├── Pages.php │ │ │ │ ├── Role.php │ │ │ │ ├── Site.php │ │ │ │ ├── Structure.php │ │ │ │ ├── StructureObject.php │ │ │ │ ├── Translation.php │ │ │ │ ├── User.php │ │ │ │ └── Users.php │ │ │ ├── Interceptor.php │ │ │ └── Toolkit │ │ │ │ └── Obj.php │ │ │ ├── Kql.php │ │ │ └── Query.php │ │ └── tests │ │ ├── InterceptorTest.php │ │ ├── KqlTest.php │ │ └── bootstrap.php └── templates │ └── default.php ├── src ├── App.vue ├── assets │ ├── fonts │ │ └── IBMPlexSans-Regular.woff2 │ └── tailwind.css ├── components │ └── Navigation.vue ├── main.js ├── router.js ├── store.js └── views │ ├── About.vue │ ├── Home.vue │ ├── Project.vue │ └── Projects.vue ├── tailwind.config.js └── vue.config.js /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{css,scss,less,js,json,ts,sass,html,hbs,mustache,phtml,html.twig,md,yml}] 2 | charset = utf-8 3 | indent_style = space 4 | indent_size = 2 5 | end_of_line = lf 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [*.md] 11 | indent_size = 4 12 | trim_trailing_whitespace = false 13 | 14 | [site/templates/**.php] 15 | indent_size = 2 16 | 17 | [site/snippets/**.php] 18 | indent_size = 2 19 | 20 | [package.json,.{babelrc,editorconfig,eslintrc,lintstagedrc,stylelintrc}] 21 | indent_style = space 22 | indent_size = 2 23 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | VUE_APP_USERNAME=email@vuekit.com 2 | VUE_APP_PASSWORD=password 3 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | 'extends': [ 7 | 'plugin:vue/essential', 8 | 'eslint:recommended' 9 | ], 10 | rules: { 11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' 13 | }, 14 | parserOptions: { 15 | parser: 'babel-eslint' 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | yarn.lock 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | 15 | 16 | # Editor directories and files 17 | .idea 18 | .nova 19 | .vscode 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw* 25 | 26 | # Kirby 27 | Icon 28 | .DS_Store 29 | /media/ 30 | /media/index.html 31 | /site/cache/ 32 | /site/cache/index.html 33 | /site/accounts/ 34 | /site/accounts/index.html 35 | /site/sessions/ 36 | /site/sessions/index.html 37 | 38 | .env 39 | 40 | /vendor/ 41 | /composer.lock 42 | /vendor/*.php 43 | /package-lock.json 44 | package-lock.json 45 | /storage 46 | -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | # Kirby .htaccess 2 | 3 | # rewrite rules 4 | 5 | 6 | # enable awesome urls. i.e.: 7 | # http://yourdomain.com/about-us/team 8 | RewriteEngine on 9 | 10 | # make sure to set the RewriteBase correctly 11 | # if you are running the site in a subfolder. 12 | # Otherwise links or the entire site will break. 13 | # 14 | # If your homepage is http://yourdomain.com/mysite 15 | # Set the RewriteBase to: 16 | # 17 | # RewriteBase /mysite 18 | 19 | # In some enviroments it's necessary to 20 | # set the RewriteBase to: 21 | # 22 | # RewriteBase / 23 | RewriteCond %{HTTPS} off 24 | RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] 25 | 26 | # block files and folders beginning with a dot, such as .git 27 | # except for the .well-known folder, which is used for Let's Encrypt and security.txt 28 | RewriteRule (^|/)\.(?!well-known\/) index.php [L] 29 | 30 | # block text files in the content folder from being accessed directly 31 | RewriteRule ^content/(.*)\.(txt|md|mdown)$ index.php [L] 32 | 33 | # block all files in the site folder from being accessed directly 34 | # except for requests to plugin assets files 35 | RewriteRule ^site/(.*) index.php [L] 36 | 37 | # Enable authentication header 38 | SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 39 | 40 | # block direct access to kirby and the panel sources 41 | RewriteRule ^kirby/(.*) index.php [L] 42 | 43 | # make site links work 44 | RewriteCond %{REQUEST_FILENAME} !-f 45 | RewriteCond %{REQUEST_FILENAME} !-d 46 | RewriteRule ^(.*) index.php [L] 47 | 48 | 49 | 50 | # compress text file responses 51 | 52 | AddOutputFilterByType DEFLATE text/plain 53 | AddOutputFilterByType DEFLATE text/html 54 | AddOutputFilterByType DEFLATE text/css 55 | AddOutputFilterByType DEFLATE text/javascript 56 | AddOutputFilterByType DEFLATE application/json 57 | AddOutputFilterByType DEFLATE application/javascript 58 | AddOutputFilterByType DEFLATE application/x-javascript 59 | 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vuekit 2 | 3 | [Kirby](https://getkirby.com) + [Vue.js](https://vuejs.org/) + [TailwindCSS](https://tailwindcss.com/) 4 | 5 | ### Requirement 6 | 7 | - A server with php & https (ex. Laravel Valet) 8 | 9 | ### Project setup 10 | 11 | ``` 12 | 1. npm install 13 | 2. composer install 14 | 3. valet secure 15 | 4. Install kirby via .com/panel 16 | 5. Create an API user in the panel and add your username & password to .env.example 17 | 6. Rename .env.example to .env 18 | 7. npm run build/dev 19 | ``` 20 | 21 | ### Development 22 | 23 | ``` 24 | npm run dev 25 | ``` 26 | 27 | ### Build for production 28 | 29 | ``` 30 | npm run build 31 | ``` 32 | 33 | ### Update Kirby 34 | 35 | ``` 36 | composer update 37 | ``` 38 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "php": ">=7.2.0", 4 | "getkirby/cms": "^3.4.5", 5 | "getkirby/kql": "^1.0" 6 | }, 7 | "config": { 8 | "optimize-autoloader": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /content/1_projects/1_rgb-255-0-0/project.txt: -------------------------------------------------------------------------------- 1 | Title: rgb(255,0,0) 2 | 3 | ---- 4 | 5 | Year: 2020 6 | 7 | ---- 8 | 9 | Category: painting 10 | 11 | ---- 12 | 13 | Description: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 14 | 15 | ---- 16 | 17 | Caption: *Title*, Year, Material, Format -------------------------------------------------------------------------------- /content/1_projects/2_rgb-0-255-255/project.txt: -------------------------------------------------------------------------------- 1 | Title: rgb(0,255,255) 2 | 3 | ---- 4 | 5 | Year: 2020 6 | 7 | ---- 8 | 9 | Category: drawing 10 | 11 | ---- 12 | 13 | Description: -------------------------------------------------------------------------------- /content/1_projects/3_rgb-0-0-255/project.txt: -------------------------------------------------------------------------------- 1 | Title: rgb(0,0,255) 2 | 3 | ---- 4 | 5 | Year: 2020 6 | 7 | ---- 8 | 9 | Category: editorial 10 | 11 | ---- 12 | 13 | Description: -------------------------------------------------------------------------------- /content/1_projects/4_rgb-255-255-0/project.txt: -------------------------------------------------------------------------------- 1 | Title: rgb(255,255,0) 2 | 3 | ---- 4 | 5 | Year: 2019 6 | 7 | ---- 8 | 9 | Category: curatorial 10 | 11 | ---- 12 | 13 | Description: -------------------------------------------------------------------------------- /content/1_projects/5_rgb-0-255-0/project.txt: -------------------------------------------------------------------------------- 1 | Title: rgb(0,255,0) 2 | 3 | ---- 4 | 5 | Year: 2019 6 | 7 | ---- 8 | 9 | Category: curatorial 10 | 11 | ---- 12 | 13 | Description: -------------------------------------------------------------------------------- /content/1_projects/6_rgb-255-0-255/project.txt: -------------------------------------------------------------------------------- 1 | Title: rgb(255,0,255) 2 | 3 | ---- 4 | 5 | Year: 2019 6 | 7 | ---- 8 | 9 | Category: curatorial 10 | 11 | ---- 12 | 13 | Description: -------------------------------------------------------------------------------- /content/1_projects/projects.txt: -------------------------------------------------------------------------------- 1 | Title: Projects -------------------------------------------------------------------------------- /content/home/home.txt: -------------------------------------------------------------------------------- 1 | Title: Home -------------------------------------------------------------------------------- /content/site.txt: -------------------------------------------------------------------------------- 1 | Title: Vuekit 2 | 3 | ---- 4 | 5 | Seodescription: Vuekit is a starterkit for Vue.js and Kirby 3 6 | 7 | ---- 8 | 9 | Seoimage: 10 | 11 | ---- 12 | 13 | Copyright: 14 | 15 | ---- 16 | 17 | Facebook: 18 | 19 | ---- 20 | 21 | Instagram: 22 | 23 | ---- 24 | 25 | Metadescription: Vuekit is starter kit for utilising Kirby v3 and Vue.js -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | render(); 6 | -------------------------------------------------------------------------------- /kirby/.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | 4 | # PHP PSR-2 Coding Standards 5 | # http://www.php-fig.org/psr/psr-2/ 6 | 7 | root = true 8 | 9 | [*.php] 10 | charset = utf-8 11 | end_of_line = lf 12 | insert_final_newline = true 13 | trim_trailing_whitespace = true 14 | indent_style = space 15 | indent_size = 4 -------------------------------------------------------------------------------- /kirby/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | Please see the [Security Policy on the Kirby website](https://getkirby.com/security) for a list of the currently supported Kirby versions and of past security incidents as well as for information on how to report security vulnerabilities in the Kirby core or in the Panel. 4 | -------------------------------------------------------------------------------- /kirby/assets/whoops.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #efefef; 3 | font: normal normal 400 12px/1.5 -apple-system, BlinkMacSystemFont, Segoe UI, 4 | Roboto, Helvetica, Arial, sans-serif; 5 | } 6 | 7 | .left-panel { 8 | background: transparent; 9 | } 10 | 11 | header { 12 | background-color: #313740; 13 | } 14 | 15 | .exc-title-primary { 16 | color: hsl(0, 71%, 55%); 17 | } 18 | 19 | .frame.active { 20 | color: hsl(0, 71%, 55%); 21 | box-shadow: inset -5px 0 0 0 #d16464; 22 | } 23 | 24 | .frame:not(.active):hover { 25 | background: rgba(203, 215, 229, 0.5); 26 | } 27 | 28 | .rightButton { 29 | color: #999; 30 | box-shadow: inset 0 0 0 1px #777; 31 | border-radius: 0; 32 | } 33 | 34 | .rightButton:hover { 35 | box-shadow: inset 0 0 0 1px #555; 36 | color: #777; 37 | } 38 | 39 | .details-heading { 40 | color: #7e9abf; 41 | font-weight: 500; 42 | } 43 | 44 | .frame-code { 45 | background: #000; 46 | } 47 | 48 | pre.code-block, 49 | code.code-block, 50 | .frame-args.code-block, 51 | .frame-args.code-block samp { 52 | background: #16171a; 53 | } 54 | 55 | .linenums li.current { 56 | background: transparent; 57 | } 58 | 59 | .linenums li.current.active { 60 | background: rgba(209, 100, 100, 0.3); 61 | } 62 | 63 | pre .atv, 64 | code .atv, 65 | pre .str, 66 | code .str { 67 | color: #a7bd68; 68 | } 69 | 70 | pre .tag, 71 | code .tag { 72 | color: #d16464; 73 | } 74 | 75 | pre .kwd, 76 | code .kwd { 77 | color: #8abeb7; 78 | } 79 | 80 | pre .atn, 81 | code .atn { 82 | color: #de935f; 83 | } 84 | -------------------------------------------------------------------------------- /kirby/bootstrap.php: -------------------------------------------------------------------------------- 1 | =') === false || 9 | version_compare(PHP_VERSION, '8.1.0', '<') === false 10 | ) { 11 | die(include __DIR__ . '/views/php.php'); 12 | } 13 | 14 | if (is_file($autoloader = dirname(__DIR__) . '/vendor/autoload.php')) { 15 | 16 | /** 17 | * Always prefer a site-wide Composer autoloader 18 | * if it exists, it means that the user has probably 19 | * installed additional packages 20 | */ 21 | include $autoloader; 22 | } elseif (is_file($autoloader = __DIR__ . '/vendor/autoload.php')) { 23 | 24 | /** 25 | * Fall back to the local autoloader if that exists 26 | */ 27 | include $autoloader; 28 | } else { 29 | 30 | /** 31 | * If neither one exists, don't bother searching; 32 | * it's a custom directory setup and the users need to 33 | * load the autoloader themselves 34 | */ 35 | } 36 | -------------------------------------------------------------------------------- /kirby/config/api/authentication.php: -------------------------------------------------------------------------------- 1 | kirby()->auth(); 7 | $allowImpersonation = $this->kirby()->option('api.allowImpersonation') ?? false; 8 | 9 | // csrf token check 10 | if ($auth->type($allowImpersonation) === 'session' && $auth->csrf() === false) { 11 | throw new PermissionException('Unauthenticated'); 12 | } 13 | 14 | // get user from session or basic auth 15 | if ($user = $auth->user(null, $allowImpersonation)) { 16 | if ($user->role()->permissions()->for('access', 'panel') === false) { 17 | throw new PermissionException(['key' => 'access.panel']); 18 | } 19 | 20 | return $user; 21 | } 22 | 23 | throw new PermissionException('Unauthenticated'); 24 | }; 25 | -------------------------------------------------------------------------------- /kirby/config/api/collections.php: -------------------------------------------------------------------------------- 1 | [ 12 | 'model' => 'page', 13 | 'type' => 'Kirby\Cms\Pages', 14 | 'view' => 'compact' 15 | ], 16 | 17 | /** 18 | * Files 19 | */ 20 | 'files' => [ 21 | 'model' => 'file', 22 | 'type' => 'Kirby\Cms\Files' 23 | ], 24 | 25 | /** 26 | * Languages 27 | */ 28 | 'languages' => [ 29 | 'model' => 'language', 30 | 'type' => 'Kirby\Cms\Languages' 31 | ], 32 | 33 | /** 34 | * Pages 35 | */ 36 | 'pages' => [ 37 | 'model' => 'page', 38 | 'type' => 'Kirby\Cms\Pages', 39 | 'view' => 'compact' 40 | ], 41 | 42 | /** 43 | * Roles 44 | */ 45 | 'roles' => [ 46 | 'model' => 'role', 47 | 'type' => 'Kirby\Cms\Roles', 48 | 'view' => 'compact' 49 | ], 50 | 51 | /** 52 | * Translations 53 | */ 54 | 'translations' => [ 55 | 'model' => 'translation', 56 | 'type' => 'Kirby\Cms\Translations', 57 | 'view' => 'compact' 58 | ], 59 | 60 | /** 61 | * Users 62 | */ 63 | 'users' => [ 64 | 'default' => function () { 65 | return $this->users(); 66 | }, 67 | 'model' => 'user', 68 | 'type' => 'Kirby\Cms\Users', 69 | 'view' => 'compact' 70 | ] 71 | 72 | ]; 73 | -------------------------------------------------------------------------------- /kirby/config/api/models.php: -------------------------------------------------------------------------------- 1 | include __DIR__ . '/models/File.php', 8 | 'FileBlueprint' => include __DIR__ . '/models/FileBlueprint.php', 9 | 'FileVersion' => include __DIR__ . '/models/FileVersion.php', 10 | 'Language' => include __DIR__ . '/models/Language.php', 11 | 'Page' => include __DIR__ . '/models/Page.php', 12 | 'PageBlueprint' => include __DIR__ . '/models/PageBlueprint.php', 13 | 'Role' => include __DIR__ . '/models/Role.php', 14 | 'Site' => include __DIR__ . '/models/Site.php', 15 | 'SiteBlueprint' => include __DIR__ . '/models/SiteBlueprint.php', 16 | 'System' => include __DIR__ . '/models/System.php', 17 | 'Translation' => include __DIR__ . '/models/Translation.php', 18 | 'User' => include __DIR__ . '/models/User.php', 19 | 'UserBlueprint' => include __DIR__ . '/models/UserBlueprint.php', 20 | ]; 21 | -------------------------------------------------------------------------------- /kirby/config/api/models/FileBlueprint.php: -------------------------------------------------------------------------------- 1 | [ 10 | 'name' => function (FileBlueprint $blueprint) { 11 | return $blueprint->name(); 12 | }, 13 | 'options' => function (FileBlueprint $blueprint) { 14 | return $blueprint->options(); 15 | }, 16 | 'tabs' => function (FileBlueprint $blueprint) { 17 | return $blueprint->tabs(); 18 | }, 19 | 'title' => function (FileBlueprint $blueprint) { 20 | return $blueprint->title(); 21 | }, 22 | ], 23 | 'type' => 'Kirby\Cms\FileBlueprint', 24 | 'views' => [ 25 | ], 26 | ]; 27 | -------------------------------------------------------------------------------- /kirby/config/api/models/Language.php: -------------------------------------------------------------------------------- 1 | [ 10 | 'code' => function (Language $language) { 11 | return $language->code(); 12 | }, 13 | 'default' => function (Language $language) { 14 | return $language->isDefault(); 15 | }, 16 | 'direction' => function (Language $language) { 17 | return $language->direction(); 18 | }, 19 | 'locale' => function (Language $language) { 20 | return $language->locale(); 21 | }, 22 | 'name' => function (Language $language) { 23 | return $language->name(); 24 | }, 25 | 'rules' => function (Language $language) { 26 | return $language->rules(); 27 | }, 28 | 'url' => function (Language $language) { 29 | return $language->url(); 30 | }, 31 | ], 32 | 'type' => 'Kirby\Cms\Language', 33 | 'views' => [ 34 | 'default' => [ 35 | 'code', 36 | 'default', 37 | 'direction', 38 | 'locale', 39 | 'name', 40 | 'rules', 41 | 'url' 42 | ] 43 | ] 44 | ]; 45 | -------------------------------------------------------------------------------- /kirby/config/api/models/PageBlueprint.php: -------------------------------------------------------------------------------- 1 | [ 10 | 'name' => function (PageBlueprint $blueprint) { 11 | return $blueprint->name(); 12 | }, 13 | 'num' => function (PageBlueprint $blueprint) { 14 | return $blueprint->num(); 15 | }, 16 | 'options' => function (PageBlueprint $blueprint) { 17 | return $blueprint->options(); 18 | }, 19 | 'preview' => function (PageBlueprint $blueprint) { 20 | return $blueprint->preview(); 21 | }, 22 | 'status' => function (PageBlueprint $blueprint) { 23 | return $blueprint->status(); 24 | }, 25 | 'tabs' => function (PageBlueprint $blueprint) { 26 | return $blueprint->tabs(); 27 | }, 28 | 'title' => function (PageBlueprint $blueprint) { 29 | return $blueprint->title(); 30 | }, 31 | ], 32 | 'type' => 'Kirby\Cms\PageBlueprint', 33 | 'views' => [ 34 | ], 35 | ]; 36 | -------------------------------------------------------------------------------- /kirby/config/api/models/Role.php: -------------------------------------------------------------------------------- 1 | [ 10 | 'description' => function (Role $role) { 11 | return $role->description(); 12 | }, 13 | 'name' => function (Role $role) { 14 | return $role->name(); 15 | }, 16 | 'permissions' => function (Role $role) { 17 | return $role->permissions()->toArray(); 18 | }, 19 | 'title' => function (Role $role) { 20 | return $role->title(); 21 | }, 22 | ], 23 | 'type' => 'Kirby\Cms\Role', 24 | 'views' => [ 25 | 'compact' => [ 26 | 'description', 27 | 'name', 28 | 'title' 29 | ] 30 | ] 31 | ]; 32 | -------------------------------------------------------------------------------- /kirby/config/api/models/SiteBlueprint.php: -------------------------------------------------------------------------------- 1 | [ 10 | 'name' => function (SiteBlueprint $blueprint) { 11 | return $blueprint->name(); 12 | }, 13 | 'options' => function (SiteBlueprint $blueprint) { 14 | return $blueprint->options(); 15 | }, 16 | 'tabs' => function (SiteBlueprint $blueprint) { 17 | return $blueprint->tabs(); 18 | }, 19 | 'title' => function (SiteBlueprint $blueprint) { 20 | return $blueprint->title(); 21 | }, 22 | ], 23 | 'type' => 'Kirby\Cms\SiteBlueprint', 24 | 'views' => [ 25 | ], 26 | ]; 27 | -------------------------------------------------------------------------------- /kirby/config/api/models/Translation.php: -------------------------------------------------------------------------------- 1 | [ 10 | 'author' => function (Translation $translation) { 11 | return $translation->author(); 12 | }, 13 | 'data' => function (Translation $translation) { 14 | return $translation->dataWithFallback(); 15 | }, 16 | 'direction' => function (Translation $translation) { 17 | return $translation->direction(); 18 | }, 19 | 'id' => function (Translation $translation) { 20 | return $translation->id(); 21 | }, 22 | 'name' => function (Translation $translation) { 23 | return $translation->name(); 24 | }, 25 | ], 26 | 'type' => 'Kirby\Cms\Translation', 27 | 'views' => [ 28 | 'compact' => [ 29 | 'direction', 30 | 'id', 31 | 'name' 32 | ] 33 | ] 34 | ]; 35 | -------------------------------------------------------------------------------- /kirby/config/api/models/UserBlueprint.php: -------------------------------------------------------------------------------- 1 | [ 10 | 'name' => function (UserBlueprint $blueprint) { 11 | return $blueprint->name(); 12 | }, 13 | 'options' => function (UserBlueprint $blueprint) { 14 | return $blueprint->options(); 15 | }, 16 | 'tabs' => function (UserBlueprint $blueprint) { 17 | return $blueprint->tabs(); 18 | }, 19 | 'title' => function (UserBlueprint $blueprint) { 20 | return $blueprint->title(); 21 | }, 22 | ], 23 | 'type' => 'Kirby\Cms\UserBlueprint', 24 | 'views' => [ 25 | ], 26 | ]; 27 | -------------------------------------------------------------------------------- /kirby/config/api/routes.php: -------------------------------------------------------------------------------- 1 | option('languages', false) !== false) { 22 | $routes = array_merge($routes, include __DIR__ . '/routes/languages.php'); 23 | } 24 | 25 | return $routes; 26 | }; 27 | -------------------------------------------------------------------------------- /kirby/config/api/routes/languages.php: -------------------------------------------------------------------------------- 1 | 'languages', 9 | 'method' => 'GET', 10 | 'action' => function () { 11 | return $this->kirby()->languages(); 12 | } 13 | ], 14 | [ 15 | 'pattern' => 'languages', 16 | 'method' => 'POST', 17 | 'action' => function () { 18 | return $this->kirby()->languages()->create($this->requestBody()); 19 | } 20 | ], 21 | [ 22 | 'pattern' => 'languages/(:any)', 23 | 'method' => 'GET', 24 | 'action' => function (string $code) { 25 | return $this->kirby()->languages()->find($code); 26 | } 27 | ], 28 | [ 29 | 'pattern' => 'languages/(:any)', 30 | 'method' => 'PATCH', 31 | 'action' => function (string $code) { 32 | if ($language = $this->kirby()->languages()->find($code)) { 33 | return $language->update($this->requestBody()); 34 | } 35 | } 36 | ], 37 | [ 38 | 'pattern' => 'languages/(:any)', 39 | 'method' => 'DELETE', 40 | 'action' => function (string $code) { 41 | if ($language = $this->kirby()->languages()->find($code)) { 42 | return $language->delete(); 43 | } 44 | } 45 | ] 46 | ]; 47 | -------------------------------------------------------------------------------- /kirby/config/api/routes/roles.php: -------------------------------------------------------------------------------- 1 | 'roles', 9 | 'method' => 'GET', 10 | 'action' => function () { 11 | switch (get('canBe')) { 12 | case 'changed': 13 | return $this->kirby()->roles()->canBeChanged(); 14 | case 'created': 15 | return $this->kirby()->roles()->canBeCreated(); 16 | default: 17 | return $this->kirby()->roles(); 18 | } 19 | } 20 | ], 21 | [ 22 | 'pattern' => 'roles/(:any)', 23 | 'method' => 'GET', 24 | 'action' => function (string $name) { 25 | return $this->kirby()->roles()->find($name); 26 | } 27 | ] 28 | ]; 29 | -------------------------------------------------------------------------------- /kirby/config/api/routes/translations.php: -------------------------------------------------------------------------------- 1 | 'translations', 9 | 'method' => 'GET', 10 | 'auth' => false, 11 | 'action' => function () { 12 | return $this->kirby()->translations(); 13 | } 14 | ], 15 | [ 16 | 'pattern' => 'translations/(:any)', 17 | 'method' => 'GET', 18 | 'auth' => false, 19 | 'action' => function (string $code) { 20 | return $this->kirby()->translations()->find($code); 21 | } 22 | ] 23 | 24 | ]; 25 | -------------------------------------------------------------------------------- /kirby/config/blocks/code/code.php: -------------------------------------------------------------------------------- 1 | 2 |
code()->html(false) ?>
3 | -------------------------------------------------------------------------------- /kirby/config/blocks/code/code.yml: -------------------------------------------------------------------------------- 1 | name: field.blocks.code.name 2 | icon: code 3 | wysiwyg: true 4 | preview: code 5 | fields: 6 | code: 7 | label: field.blocks.code.name 8 | type: textarea 9 | placeholder: field.blocks.code.placeholder 10 | buttons: false 11 | font: monospace 12 | language: 13 | label: field.blocks.code.language 14 | type: select 15 | default: text 16 | options: 17 | bash: Bash 18 | basic: BASIC 19 | c: C 20 | clojure: Clojure 21 | cpp: C++ 22 | csharp: C# 23 | css: CSS 24 | diff: Diff 25 | elixir: Elixir 26 | elm: Elm 27 | erlang: Erlang 28 | go: Go 29 | graphql: GraphQL 30 | haskell: Haskell 31 | html: HTML 32 | java: Java 33 | js: JavaScript 34 | json: JSON 35 | latext: LaTeX 36 | less: Less 37 | lisp: Lisp 38 | lua: Lua 39 | makefile: Makefile 40 | markdown: Markdown 41 | markup: Markup 42 | objectivec: Objective-C 43 | pascal: Pascal 44 | perl: Perl 45 | php: PHP 46 | text: Plain Text 47 | python: Python 48 | r: R 49 | ruby: Ruby 50 | rust: Rust 51 | sass: Sass 52 | scss: SCSS 53 | shell: Shell 54 | sql: SQL 55 | swift: Swift 56 | typescript: TypeScript 57 | vbnet: VB.net 58 | xml: XML 59 | yaml: YAML 60 | -------------------------------------------------------------------------------- /kirby/config/blocks/gallery/gallery.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | 10 |
11 | -------------------------------------------------------------------------------- /kirby/config/blocks/gallery/gallery.yml: -------------------------------------------------------------------------------- 1 | name: field.blocks.gallery.name 2 | icon: dashboard 3 | preview: gallery 4 | fields: 5 | images: 6 | label: field.blocks.gallery.images.label 7 | type: files 8 | multiple: true 9 | layout: cards 10 | size: tiny 11 | empty: field.blocks.gallery.images.empty 12 | uploads: 13 | template: blocks/image 14 | image: 15 | ratio: 1/1 16 | -------------------------------------------------------------------------------- /kirby/config/blocks/heading/heading.php: -------------------------------------------------------------------------------- 1 | 2 | <level()->or('h2') ?>>text() ?>> 3 | -------------------------------------------------------------------------------- /kirby/config/blocks/heading/heading.yml: -------------------------------------------------------------------------------- 1 | name: field.blocks.heading.name 2 | icon: title 3 | wysiwyg: true 4 | preview: heading 5 | fields: 6 | level: 7 | label: field.blocks.heading.level 8 | type: select 9 | empty: false 10 | default: "h2" 11 | width: 1/6 12 | options: 13 | - h1 14 | - h2 15 | - h3 16 | - h4 17 | - h5 18 | - h6 19 | text: 20 | label: field.blocks.heading.text 21 | type: writer 22 | inline: true 23 | width: 5/6 24 | placeholder: field.blocks.heading.placeholder 25 | -------------------------------------------------------------------------------- /kirby/config/blocks/image/image.php: -------------------------------------------------------------------------------- 1 | alt(); 5 | $caption = $block->caption(); 6 | $crop = $block->crop()->isTrue(); 7 | $link = $block->link(); 8 | $ratio = $block->ratio()->or('auto'); 9 | $src = null; 10 | 11 | if ($block->location() == 'web') { 12 | $src = $block->src(); 13 | } elseif ($image = $block->image()->toFile()) { 14 | $alt = $alt ?? $image->alt(); 15 | $src = $image->url(); 16 | } 17 | 18 | ?> 19 | 20 | $ratio, 'data-crop' => $crop], ' ') ?>> 21 | isNotEmpty()): ?> 22 | 23 | <?= $alt ?> 24 | 25 | 26 | <?= $alt ?> 27 | 28 | 29 | isNotEmpty()): ?> 30 |
31 | 32 |
33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /kirby/config/blocks/image/image.yml: -------------------------------------------------------------------------------- 1 | name: field.blocks.image.name 2 | icon: image 3 | preview: image 4 | fields: 5 | location: 6 | label: field.blocks.image.location 7 | type: radio 8 | columns: 2 9 | default: "kirby" 10 | options: 11 | kirby: Kirby 12 | web: Web 13 | image: 14 | label: field.blocks.image.name 15 | type: files 16 | multiple: false 17 | image: 18 | back: black 19 | uploads: 20 | template: blocks/image 21 | when: 22 | location: kirby 23 | src: 24 | label: field.blocks.image.url 25 | type: url 26 | when: 27 | location: web 28 | alt: 29 | label: field.blocks.image.alt 30 | type: text 31 | icon: title 32 | caption: 33 | label: field.blocks.image.caption 34 | type: writer 35 | icon: text 36 | inline: true 37 | link: 38 | label: field.blocks.image.link 39 | type: text 40 | icon: url 41 | ratio: 42 | label: field.blocks.image.ratio 43 | type: select 44 | placeholder: Auto 45 | width: 1/2 46 | options: 47 | 1/1: "1:1" 48 | 16/9: "16:9" 49 | 10/8: "10:8" 50 | 21/9: "21:9" 51 | 7/5: "7:5" 52 | 4/3: "4:3" 53 | 5/3: "5:3" 54 | 3/2: "3:2" 55 | 3/1: "3:1" 56 | crop: 57 | label: field.blocks.image.crop 58 | type: toggle 59 | width: 1/2 60 | -------------------------------------------------------------------------------- /kirby/config/blocks/list/list.php: -------------------------------------------------------------------------------- 1 | 2 | text(); 3 | -------------------------------------------------------------------------------- /kirby/config/blocks/list/list.yml: -------------------------------------------------------------------------------- 1 | name: field.blocks.list.name 2 | icon: list-bullet 3 | wysiwyg: true 4 | preview: list 5 | fields: 6 | text: 7 | label: field.blocks.list.name 8 | type: list 9 | -------------------------------------------------------------------------------- /kirby/config/blocks/markdown/markdown.php: -------------------------------------------------------------------------------- 1 | 2 | text()->kt(); 3 | -------------------------------------------------------------------------------- /kirby/config/blocks/markdown/markdown.yml: -------------------------------------------------------------------------------- 1 | name: field.blocks.markdown.name 2 | icon: markdown 3 | preview: markdown 4 | wysiwyg: true 5 | fields: 6 | text: 7 | label: field.blocks.markdown.label 8 | placeholder: field.blocks.markdown.placeholder 9 | type: textarea 10 | buttons: false 11 | font: monospace 12 | -------------------------------------------------------------------------------- /kirby/config/blocks/quote/quote.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | text() ?> 4 | citation()->isNotEmpty()): ?> 5 |
6 | citation() ?> 7 |
8 | 9 |
10 | -------------------------------------------------------------------------------- /kirby/config/blocks/quote/quote.yml: -------------------------------------------------------------------------------- 1 | name: field.blocks.quote.name 2 | icon: quote 3 | wysiwyg: true 4 | preview: quote 5 | fields: 6 | text: 7 | label: field.blocks.quote.text.label 8 | placeholder: field.blocks.quote.text.placeholder 9 | type: writer 10 | inline: true 11 | icon: quote 12 | citation: 13 | label: field.blocks.quote.citation.label 14 | placeholder: field.blocks.quote.citation.placeholder 15 | type: writer 16 | inline: true 17 | icon: user 18 | -------------------------------------------------------------------------------- /kirby/config/blocks/table/table.yml: -------------------------------------------------------------------------------- 1 | name: Table 2 | icon: menu 3 | preview: table 4 | -------------------------------------------------------------------------------- /kirby/config/blocks/text/text.php: -------------------------------------------------------------------------------- 1 | 2 | text(); 3 | -------------------------------------------------------------------------------- /kirby/config/blocks/text/text.yml: -------------------------------------------------------------------------------- 1 | name: field.blocks.text.name 2 | icon: text 3 | wysiwyg: true 4 | preview: text 5 | fields: 6 | text: 7 | type: writer 8 | nodes: false 9 | placeholder: field.blocks.text.placeholder 10 | -------------------------------------------------------------------------------- /kirby/config/blocks/video/video.php: -------------------------------------------------------------------------------- 1 | 2 | url()->isNotEmpty()): ?> 3 |
4 | url()) ?> 5 | caption()->isNotEmpty()): ?> 6 |
caption() ?>
7 | 8 |
9 | 10 | -------------------------------------------------------------------------------- /kirby/config/blocks/video/video.yml: -------------------------------------------------------------------------------- 1 | name: field.blocks.video.name 2 | icon: video 3 | preview: video 4 | fields: 5 | url: 6 | label: field.blocks.video.url.label 7 | type: url 8 | placeholder: field.blocks.video.url.placeholder 9 | caption: 10 | label: field.blocks.video.caption 11 | type: writer 12 | inline: true 13 | -------------------------------------------------------------------------------- /kirby/config/blueprints.php: -------------------------------------------------------------------------------- 1 | $blocksRoot . '/code/code.yml', 8 | 'blocks/gallery' => $blocksRoot . '/gallery/gallery.yml', 9 | 'blocks/heading' => $blocksRoot . '/heading/heading.yml', 10 | 'blocks/image' => $blocksRoot . '/image/image.yml', 11 | 'blocks/list' => $blocksRoot . '/list/list.yml', 12 | 'blocks/markdown' => $blocksRoot . '/markdown/markdown.yml', 13 | 'blocks/quote' => $blocksRoot . '/quote/quote.yml', 14 | 'blocks/table' => $blocksRoot . '/table/table.yml', 15 | 'blocks/text' => $blocksRoot . '/text/text.yml', 16 | 'blocks/video' => $blocksRoot . '/video/video.yml', 17 | 18 | // file blueprints 19 | 'files/default' => __DIR__ . '/blueprints/files/default.yml', 20 | 21 | // page blueprints 22 | 'pages/default' => __DIR__ . '/blueprints/pages/default.yml', 23 | 24 | // site blueprints 25 | 'site' => __DIR__ . '/blueprints/site.yml' 26 | ]; 27 | -------------------------------------------------------------------------------- /kirby/config/blueprints/blocks/code.yml: -------------------------------------------------------------------------------- 1 | name: Code 2 | icon: code 3 | fields: 4 | code: 5 | label: Code 6 | type: textarea 7 | buttons: false 8 | font: monospace 9 | language: 10 | label: Language 11 | type: select 12 | default: text 13 | options: 14 | bash: Bash 15 | basic: BASIC 16 | c: C 17 | clojure: Clojure 18 | cpp: C++ 19 | csharp: C# 20 | css: CSS 21 | diff: Diff 22 | elixir: Elixir 23 | elm: Elm 24 | erlang: Erlang 25 | go: Go 26 | graphql: GraphQL 27 | haskell: Haskell 28 | html: HTML 29 | java: Java 30 | js: JavaScript 31 | json: JSON 32 | latext: LaTeX 33 | less: Less 34 | lisp: Lisp 35 | lua: Lua 36 | makefile: Makefile 37 | markdown: Markdown 38 | markup: Markup 39 | objectivec: Objective-C 40 | pascal: Pascal 41 | perl: Perl 42 | php: PHP 43 | text: Plain Text 44 | python: Python 45 | r: R 46 | ruby: Ruby 47 | rust: Rust 48 | sass: Sass 49 | scss: SCSS 50 | shell: Shell 51 | sql: SQL 52 | swift: Swift 53 | typescript: TypeScript 54 | vbnet: VB.net 55 | xml: XML 56 | yaml: YAML 57 | -------------------------------------------------------------------------------- /kirby/config/blueprints/blocks/heading.yml: -------------------------------------------------------------------------------- 1 | icon: title 2 | fields: 3 | text: 4 | type: text 5 | level: 6 | type: select 7 | width: 1/2 8 | default: 1 9 | empty: false 10 | default: "2" 11 | options: 12 | - value: "1" 13 | text: Heading 1 14 | - value: "2" 15 | text: Heading 2 16 | - value: "3" 17 | text: Heading 3 18 | id: 19 | type: text 20 | label: ID 21 | width: 1/2 22 | -------------------------------------------------------------------------------- /kirby/config/blueprints/blocks/image.yml: -------------------------------------------------------------------------------- 1 | name: Image 2 | icon: image 3 | fields: 4 | image: 5 | type: files 6 | multiple: false 7 | alt: 8 | type: text 9 | icon: title 10 | caption: 11 | type: writer 12 | inline: true 13 | icon: text 14 | link: 15 | type: text 16 | icon: url 17 | -------------------------------------------------------------------------------- /kirby/config/blueprints/blocks/quote.yml: -------------------------------------------------------------------------------- 1 | name: Quote 2 | icon: quote 3 | fields: 4 | text: 5 | label: Quote Text 6 | type: writer 7 | inline: true 8 | citation: 9 | label: Citation 10 | type: writer 11 | inline: true 12 | placeholder: by … 13 | -------------------------------------------------------------------------------- /kirby/config/blueprints/blocks/table.yml: -------------------------------------------------------------------------------- 1 | name: Table 2 | icon: menu 3 | fields: 4 | rows: 5 | label: Menu 6 | type: structure 7 | columns: 8 | dish: true 9 | description: true 10 | price: 11 | before: € 12 | width: 1/4 13 | align: right 14 | fields: 15 | dish: 16 | label: Dish 17 | type: text 18 | description: 19 | label: Description 20 | type: text 21 | price: 22 | label: Price 23 | type: number 24 | before: € 25 | step: 0.01 26 | -------------------------------------------------------------------------------- /kirby/config/blueprints/blocks/text.yml: -------------------------------------------------------------------------------- 1 | name: Text 2 | icon: text 3 | fields: 4 | text: 5 | type: writer 6 | -------------------------------------------------------------------------------- /kirby/config/blueprints/blocks/video.yml: -------------------------------------------------------------------------------- 1 | name: Video 2 | icon: video 3 | label: "{{ url }}" 4 | fields: 5 | url: 6 | type: url 7 | caption: 8 | type: writer 9 | -------------------------------------------------------------------------------- /kirby/config/blueprints/files/default.yml: -------------------------------------------------------------------------------- 1 | name: File 2 | title: file 3 | -------------------------------------------------------------------------------- /kirby/config/blueprints/pages/default.yml: -------------------------------------------------------------------------------- 1 | name: Page 2 | title: Page 3 | 4 | -------------------------------------------------------------------------------- /kirby/config/blueprints/site.yml: -------------------------------------------------------------------------------- 1 | name: Site 2 | title: Site 3 | sections: 4 | pages: 5 | headline: Pages 6 | type: pages 7 | 8 | -------------------------------------------------------------------------------- /kirby/config/fields.php: -------------------------------------------------------------------------------- 1 | 'Kirby\Form\Field\BlocksField', 5 | 'checkboxes' => __DIR__ . '/fields/checkboxes.php', 6 | 'date' => __DIR__ . '/fields/date.php', 7 | 'email' => __DIR__ . '/fields/email.php', 8 | 'files' => __DIR__ . '/fields/files.php', 9 | 'gap' => __DIR__ . '/fields/gap.php', 10 | 'headline' => __DIR__ . '/fields/headline.php', 11 | 'hidden' => __DIR__ . '/fields/hidden.php', 12 | 'info' => __DIR__ . '/fields/info.php', 13 | 'layout' => 'Kirby\Form\Field\LayoutField', 14 | 'line' => __DIR__ . '/fields/line.php', 15 | 'list' => __DIR__ . '/fields/list.php', 16 | 'multiselect' => __DIR__ . '/fields/multiselect.php', 17 | 'number' => __DIR__ . '/fields/number.php', 18 | 'pages' => __DIR__ . '/fields/pages.php', 19 | 'radio' => __DIR__ . '/fields/radio.php', 20 | 'range' => __DIR__ . '/fields/range.php', 21 | 'select' => __DIR__ . '/fields/select.php', 22 | 'structure' => __DIR__ . '/fields/structure.php', 23 | 'tags' => __DIR__ . '/fields/tags.php', 24 | 'tel' => __DIR__ . '/fields/tel.php', 25 | 'text' => __DIR__ . '/fields/text.php', 26 | 'textarea' => __DIR__ . '/fields/textarea.php', 27 | 'time' => __DIR__ . '/fields/time.php', 28 | 'toggle' => __DIR__ . '/fields/toggle.php', 29 | 'url' => __DIR__ . '/fields/url.php', 30 | 'users' => __DIR__ . '/fields/users.php', 31 | 'writer' => __DIR__ . '/fields/writer.php' 32 | ]; 33 | -------------------------------------------------------------------------------- /kirby/config/fields/checkboxes.php: -------------------------------------------------------------------------------- 1 | ['min', 'options'], 8 | 'props' => [ 9 | /** 10 | * Unset inherited props 11 | */ 12 | 'after' => null, 13 | 'before' => null, 14 | 'icon' => null, 15 | 'placeholder' => null, 16 | 17 | /** 18 | * Arranges the checkboxes in the given number of columns 19 | */ 20 | 'columns' => function (int $columns = 1) { 21 | return $columns; 22 | }, 23 | /** 24 | * Default value for the field, which will be used when a page/file/user is created 25 | */ 26 | 'default' => function ($default = null) { 27 | return Str::split($default, ','); 28 | }, 29 | /** 30 | * Maximum number of checked boxes 31 | */ 32 | 'max' => function (int $max = null) { 33 | return $max; 34 | }, 35 | /** 36 | * Minimum number of checked boxes 37 | */ 38 | 'min' => function (int $min = null) { 39 | return $min; 40 | }, 41 | 'value' => function ($value = null) { 42 | return Str::split($value, ','); 43 | }, 44 | ], 45 | 'computed' => [ 46 | 'default' => function () { 47 | return $this->sanitizeOptions($this->default); 48 | }, 49 | 'value' => function () { 50 | return $this->sanitizeOptions($this->value); 51 | }, 52 | ], 53 | 'save' => function ($value): string { 54 | return A::join($value, ', '); 55 | }, 56 | 'validations' => [ 57 | 'options', 58 | 'max', 59 | 'min' 60 | ] 61 | ]; 62 | -------------------------------------------------------------------------------- /kirby/config/fields/email.php: -------------------------------------------------------------------------------- 1 | 'text', 7 | 'props' => [ 8 | /** 9 | * Unset inherited props 10 | */ 11 | 'converter' => null, 12 | 'counter' => null, 13 | 14 | /** 15 | * Sets the HTML5 autocomplete mode for the input 16 | */ 17 | 'autocomplete' => function (string $autocomplete = 'email') { 18 | return $autocomplete; 19 | }, 20 | 21 | /** 22 | * Changes the email icon to something custom 23 | */ 24 | 'icon' => function (string $icon = 'email') { 25 | return $icon; 26 | }, 27 | 28 | /** 29 | * Custom placeholder text, when the field is empty. 30 | */ 31 | 'placeholder' => function ($value = null) { 32 | return I18n::translate($value, $value) ?? I18n::translate('email.placeholder'); 33 | } 34 | ], 35 | 'validations' => [ 36 | 'minlength', 37 | 'maxlength', 38 | 'email' 39 | ] 40 | ]; 41 | -------------------------------------------------------------------------------- /kirby/config/fields/gap.php: -------------------------------------------------------------------------------- 1 | false 5 | ]; 6 | -------------------------------------------------------------------------------- /kirby/config/fields/headline.php: -------------------------------------------------------------------------------- 1 | false, 5 | 'props' => [ 6 | /** 7 | * Unset inherited props 8 | */ 9 | 'after' => null, 10 | 'autofocus' => null, 11 | 'before' => null, 12 | 'default' => null, 13 | 'disabled' => null, 14 | 'icon' => null, 15 | 'placeholder' => null, 16 | 'required' => null, 17 | 'translate' => null, 18 | 19 | /** 20 | * If `false`, the prepended number will be hidden 21 | */ 22 | 'numbered' => function (bool $numbered = true) { 23 | return $numbered; 24 | } 25 | ] 26 | ]; 27 | -------------------------------------------------------------------------------- /kirby/config/fields/hidden.php: -------------------------------------------------------------------------------- 1 | [ 7 | /** 8 | * Unset inherited props 9 | */ 10 | 'after' => null, 11 | 'autofocus' => null, 12 | 'before' => null, 13 | 'default' => null, 14 | 'disabled' => null, 15 | 'icon' => null, 16 | 'placeholder' => null, 17 | 'required' => null, 18 | 'translate' => null, 19 | 20 | /** 21 | * Text to be displayed 22 | */ 23 | 'text' => function ($value = null) { 24 | return I18n::translate($value, $value); 25 | }, 26 | 27 | /** 28 | * Change the design of the info box 29 | */ 30 | 'theme' => function (string $theme = null) { 31 | return $theme; 32 | } 33 | ], 34 | 'computed' => [ 35 | 'text' => function () { 36 | if ($text = $this->text) { 37 | $text = $this->model()->toString($text); 38 | $text = $this->kirby()->kirbytext($text); 39 | return $text; 40 | } 41 | } 42 | ], 43 | 'save' => false, 44 | ]; 45 | -------------------------------------------------------------------------------- /kirby/config/fields/line.php: -------------------------------------------------------------------------------- 1 | false 5 | ]; 6 | -------------------------------------------------------------------------------- /kirby/config/fields/list.php: -------------------------------------------------------------------------------- 1 | [ 5 | /** 6 | * Sets the allowed HTML formats. Available formats: `bold`, `italic`, `underline`, `strike`, `code`, `link`. Activate them all by passing `true`. Deactivate them all by passing `false` 7 | */ 8 | 'marks' => function ($marks = true) { 9 | return $marks; 10 | } 11 | ], 12 | 'computed' => [ 13 | 'value' => function () { 14 | return trim($this->value); 15 | } 16 | ] 17 | ]; 18 | -------------------------------------------------------------------------------- /kirby/config/fields/mixins/datetime.php: -------------------------------------------------------------------------------- 1 | [ 5 | /** 6 | * Defines a custom format that is used when the field is saved 7 | */ 8 | 'format' => function (string $format = null) { 9 | return $format; 10 | } 11 | ], 12 | 'methods' => [ 13 | 'toDatetime' => function ($value, string $format = 'Y-m-d H:i:s') { 14 | if ($timestamp = timestamp($value, $this->step)) { 15 | return date($format, $timestamp); 16 | } 17 | 18 | return null; 19 | } 20 | ], 21 | 'save' => function ($value) { 22 | if ($value !== null && $timestamp = strtotime($value)) { 23 | return date($this->format, $timestamp); 24 | } 25 | 26 | return ''; 27 | }, 28 | ]; 29 | -------------------------------------------------------------------------------- /kirby/config/fields/mixins/filepicker.php: -------------------------------------------------------------------------------- 1 | [ 7 | 'filepicker' => function (array $params = []) { 8 | // fetch the parent model 9 | $params['model'] = $this->model(); 10 | 11 | return (new FilePicker($params))->toArray(); 12 | } 13 | ] 14 | ]; 15 | -------------------------------------------------------------------------------- /kirby/config/fields/mixins/min.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'min' => function () { 6 | // set min to at least 1, if required 7 | if ($this->required === true) { 8 | return $this->min ?? 1; 9 | } 10 | 11 | return $this->min; 12 | }, 13 | 'required' => function () { 14 | // set required to true if min is set 15 | if ($this->min) { 16 | return true; 17 | } 18 | 19 | return $this->required; 20 | } 21 | ] 22 | ]; 23 | -------------------------------------------------------------------------------- /kirby/config/fields/mixins/options.php: -------------------------------------------------------------------------------- 1 | [ 7 | /** 8 | * API settings for options requests. This will only take affect when `options` is set to `api`. 9 | */ 10 | 'api' => function ($api = null) { 11 | return $api; 12 | }, 13 | /** 14 | * An array with options 15 | */ 16 | 'options' => function ($options = []) { 17 | return $options; 18 | }, 19 | /** 20 | * Query settings for options queries. This will only take affect when `options` is set to `query`. 21 | */ 22 | 'query' => function ($query = null) { 23 | return $query; 24 | }, 25 | ], 26 | 'computed' => [ 27 | 'options' => function (): array { 28 | return $this->getOptions(); 29 | } 30 | ], 31 | 'methods' => [ 32 | 'getOptions' => function () { 33 | return Options::factory( 34 | $this->options(), 35 | $this->props, 36 | $this->model() 37 | ); 38 | }, 39 | 'sanitizeOption' => function ($option) { 40 | $allowed = array_column($this->options(), 'value'); 41 | return in_array($option, $allowed, true) === true ? $option : null; 42 | }, 43 | 'sanitizeOptions' => function ($options) { 44 | $allowed = array_column($this->options(), 'value'); 45 | return array_intersect($options, $allowed); 46 | }, 47 | ] 48 | ]; 49 | -------------------------------------------------------------------------------- /kirby/config/fields/mixins/pagepicker.php: -------------------------------------------------------------------------------- 1 | [ 7 | 'pagepicker' => function (array $params = []) { 8 | // inject the current model 9 | $params['model'] = $this->model(); 10 | 11 | return (new PagePicker($params))->toArray(); 12 | } 13 | ] 14 | ]; 15 | -------------------------------------------------------------------------------- /kirby/config/fields/mixins/userpicker.php: -------------------------------------------------------------------------------- 1 | [ 7 | 'userpicker' => function (array $params = []) { 8 | $params['model'] = $this->model(); 9 | 10 | return (new UserPicker($params))->toArray(); 11 | } 12 | ] 13 | ]; 14 | -------------------------------------------------------------------------------- /kirby/config/fields/multiselect.php: -------------------------------------------------------------------------------- 1 | 'tags', 5 | 'props' => [ 6 | /** 7 | * Unset inherited props 8 | */ 9 | 'accept' => null, 10 | /** 11 | * Custom icon to replace the arrow down. 12 | */ 13 | 'icon' => function (string $icon = null) { 14 | return $icon; 15 | }, 16 | /** 17 | * Enable/disable the search in the dropdown 18 | * Also limit displayed items (display: 20) 19 | * and set minimum number of characters to search (min: 3) 20 | */ 21 | 'search' => function ($search = true) { 22 | return $search; 23 | }, 24 | /** 25 | * If `true`, selected entries will be sorted 26 | * according to their position in the dropdown 27 | */ 28 | 'sort' => function (bool $sort = false) { 29 | return $sort; 30 | }, 31 | ] 32 | ]; 33 | -------------------------------------------------------------------------------- /kirby/config/fields/number.php: -------------------------------------------------------------------------------- 1 | [ 7 | /** 8 | * Default number that will be saved when a new page/user/file is created 9 | */ 10 | 'default' => function ($default = null) { 11 | return $this->toNumber($default); 12 | }, 13 | /** 14 | * The lowest allowed number 15 | */ 16 | 'min' => function (float $min = null) { 17 | return $min; 18 | }, 19 | /** 20 | * The highest allowed number 21 | */ 22 | 'max' => function (float $max = null) { 23 | return $max; 24 | }, 25 | /** 26 | * Allowed incremental steps between numbers (i.e `0.5`) 27 | */ 28 | 'step' => function ($step = null) { 29 | return $this->toNumber($step); 30 | }, 31 | 'value' => function ($value = null) { 32 | return $this->toNumber($value); 33 | } 34 | ], 35 | 'methods' => [ 36 | 'toNumber' => function ($value) { 37 | if ($this->isEmpty($value) === true) { 38 | return null; 39 | } 40 | 41 | return is_float($value) === true ? $value : (float)Str::float($value); 42 | } 43 | ], 44 | 'validations' => [ 45 | 'min', 46 | 'max' 47 | ] 48 | ]; 49 | -------------------------------------------------------------------------------- /kirby/config/fields/radio.php: -------------------------------------------------------------------------------- 1 | ['options'], 5 | 'props' => [ 6 | /** 7 | * Unset inherited props 8 | */ 9 | 'after' => null, 10 | 'before' => null, 11 | 'icon' => null, 12 | 'placeholder' => null, 13 | 14 | /** 15 | * Arranges the radio buttons in the given number of columns 16 | */ 17 | 'columns' => function (int $columns = 1) { 18 | return $columns; 19 | }, 20 | ], 21 | 'computed' => [ 22 | 'default' => function () { 23 | return $this->sanitizeOption($this->default); 24 | }, 25 | 'value' => function () { 26 | return $this->sanitizeOption($this->value) ?? ''; 27 | } 28 | ] 29 | ]; 30 | -------------------------------------------------------------------------------- /kirby/config/fields/range.php: -------------------------------------------------------------------------------- 1 | 'number', 5 | 'props' => [ 6 | /** 7 | * Unset inherited props 8 | */ 9 | 'placeholder' => null, 10 | 11 | /** 12 | * The maximum value on the slider 13 | */ 14 | 'max' => function (float $max = 100) { 15 | return $max; 16 | }, 17 | /** 18 | * Enables/disables the tooltip and set the before and after values 19 | */ 20 | 'tooltip' => function ($tooltip = true) { 21 | return $tooltip; 22 | }, 23 | ] 24 | ]; 25 | -------------------------------------------------------------------------------- /kirby/config/fields/select.php: -------------------------------------------------------------------------------- 1 | 'radio', 5 | 'props' => [ 6 | /** 7 | * Unset inherited props 8 | */ 9 | 'columns' => null, 10 | 11 | /** 12 | * Custom icon to replace the arrow down. 13 | */ 14 | 'icon' => function (string $icon = null) { 15 | return $icon; 16 | }, 17 | /** 18 | * Custom placeholder string for empty option. 19 | */ 20 | 'placeholder' => function (string $placeholder = '—') { 21 | return $placeholder; 22 | }, 23 | ] 24 | ]; 25 | -------------------------------------------------------------------------------- /kirby/config/fields/tel.php: -------------------------------------------------------------------------------- 1 | 'text', 5 | 'props' => [ 6 | /** 7 | * Unset inherited props 8 | */ 9 | 'converter' => null, 10 | 'counter' => null, 11 | 'spellcheck' => null, 12 | 13 | /** 14 | * Sets the HTML5 autocomplete attribute 15 | */ 16 | 'autocomplete' => function (string $autocomplete = 'tel') { 17 | return $autocomplete; 18 | }, 19 | 20 | /** 21 | * Changes the phone icon 22 | */ 23 | 'icon' => function (string $icon = 'phone') { 24 | return $icon; 25 | } 26 | ] 27 | ]; 28 | -------------------------------------------------------------------------------- /kirby/config/fields/url.php: -------------------------------------------------------------------------------- 1 | 'text', 7 | 'props' => [ 8 | /** 9 | * Unset inherited props 10 | */ 11 | 'converter' => null, 12 | 'counter' => null, 13 | 'spellcheck' => null, 14 | 15 | /** 16 | * Sets the HTML5 autocomplete attribute 17 | */ 18 | 'autocomplete' => function (string $autocomplete = 'url') { 19 | return $autocomplete; 20 | }, 21 | 22 | /** 23 | * Changes the link icon 24 | */ 25 | 'icon' => function (string $icon = 'url') { 26 | return $icon; 27 | }, 28 | 29 | /** 30 | * Sets custom placeholder text, when the field is empty 31 | */ 32 | 'placeholder' => function ($value = null) { 33 | return I18n::translate($value, $value) ?? 'https://example.com'; 34 | } 35 | ], 36 | 'validations' => [ 37 | 'minlength', 38 | 'maxlength', 39 | 'url' 40 | ], 41 | ]; 42 | -------------------------------------------------------------------------------- /kirby/config/fields/writer.php: -------------------------------------------------------------------------------- 1 | [ 5 | /** 6 | * Enables inline mode, which will not wrap new lines in paragraphs and creates hard breaks instead. 7 | * 8 | * @param bool $inline 9 | */ 10 | 'inline' => function (bool $inline = false) { 11 | return $inline; 12 | }, 13 | /** 14 | * Sets the allowed HTML formats. Available formats: `bold`, `italic`, `underline`, `strike`, `code`, `link`. Activate them all by passing `true`. Deactivate them all by passing `false` 15 | * @param array|bool $marks 16 | */ 17 | 'marks' => function ($marks = true) { 18 | return $marks; 19 | }, 20 | /** 21 | * Sets the allowed nodes. Available nodes: `bulletList`, `orderedList`, `heading`, `horizontalRule`, `listItem`. Activate/deactivate them all by passing `true`/`false`. Default nodes are `heading`, `bulletList`, `orderedList`. 22 | * @param array|bool|null $nodes 23 | */ 24 | 'nodes' => function ($nodes = null) { 25 | return $nodes; 26 | } 27 | ], 28 | 'computed' => [ 29 | 'value' => function () { 30 | return trim($this->value); 31 | } 32 | ], 33 | ]; 34 | -------------------------------------------------------------------------------- /kirby/config/presets/files.php: -------------------------------------------------------------------------------- 1 | [ 6 | 'headline' => $props['headline'] ?? t('files'), 7 | 'type' => 'files', 8 | 'layout' => $props['layout'] ?? 'cards', 9 | 'template' => $props['template'] ?? null, 10 | 'image' => $props['image'] ?? null, 11 | 'info' => '{{ file.dimensions }}' 12 | ] 13 | ]; 14 | 15 | // remove global options 16 | unset( 17 | $props['headline'], 18 | $props['layout'], 19 | $props['template'], 20 | $props['image'] 21 | ); 22 | 23 | return $props; 24 | }; 25 | -------------------------------------------------------------------------------- /kirby/config/presets/pages.php: -------------------------------------------------------------------------------- 1 | $headline, 11 | 'type' => 'pages', 12 | 'layout' => 'list', 13 | 'status' => $status 14 | ]; 15 | 16 | if ($props === true) { 17 | $props = []; 18 | } 19 | 20 | if (is_string($props) === true) { 21 | $props = [ 22 | 'headline' => $props 23 | ]; 24 | } 25 | 26 | // inject the global templates definition 27 | if (empty($templates) === false) { 28 | $props['templates'] = $props['templates'] ?? $templates; 29 | } 30 | 31 | return array_replace_recursive($defaults, $props); 32 | }; 33 | 34 | $sections = []; 35 | 36 | $drafts = $props['drafts'] ?? []; 37 | $unlisted = $props['unlisted'] ?? false; 38 | $listed = $props['listed'] ?? []; 39 | 40 | 41 | if ($drafts !== false) { 42 | $sections['drafts'] = $section(t('pages.status.draft'), 'drafts', $drafts); 43 | } 44 | 45 | if ($unlisted !== false) { 46 | $sections['unlisted'] = $section(t('pages.status.unlisted'), 'unlisted', $unlisted); 47 | } 48 | 49 | if ($listed !== false) { 50 | $sections['listed'] = $section(t('pages.status.listed'), 'listed', $listed); 51 | } 52 | 53 | // cleaning up 54 | unset($props['drafts'], $props['unlisted'], $props['listed'], $props['templates']); 55 | 56 | return array_merge($props, ['sections' => $sections]); 57 | }; 58 | -------------------------------------------------------------------------------- /kirby/config/sections/fields.php: -------------------------------------------------------------------------------- 1 | [ 7 | 'fields' => function (array $fields = []) { 8 | return $fields; 9 | } 10 | ], 11 | 'computed' => [ 12 | 'form' => function () { 13 | $fields = $this->fields; 14 | $disabled = $this->model->permissions()->update() === false; 15 | $content = $this->model->content()->toArray(); 16 | 17 | if ($disabled === true) { 18 | foreach ($fields as $key => $props) { 19 | $fields[$key]['disabled'] = true; 20 | } 21 | } 22 | 23 | return new Form([ 24 | 'fields' => $fields, 25 | 'values' => $content, 26 | 'model' => $this->model, 27 | 'strict' => true 28 | ]); 29 | }, 30 | 'fields' => function () { 31 | $fields = $this->form->fields()->toArray(); 32 | 33 | if (is_a($this->model, 'Kirby\Cms\Page') === true || is_a($this->model, 'Kirby\Cms\Site') === true) { 34 | // the title should never be updated directly via 35 | // fields section to avoid conflicts with the rename dialog 36 | unset($fields['title']); 37 | } 38 | 39 | foreach ($fields as $index => $props) { 40 | unset($fields[$index]['value']); 41 | } 42 | 43 | return $fields; 44 | } 45 | ], 46 | 'methods' => [ 47 | 'errors' => function () { 48 | return $this->form->errors(); 49 | } 50 | ], 51 | 'toArray' => function () { 52 | return [ 53 | 'fields' => $this->fields, 54 | ]; 55 | } 56 | ]; 57 | -------------------------------------------------------------------------------- /kirby/config/sections/info.php: -------------------------------------------------------------------------------- 1 | [ 7 | 'headline', 8 | ], 9 | 'props' => [ 10 | 'text' => function ($text = null) { 11 | return I18n::translate($text, $text); 12 | }, 13 | 'theme' => function (string $theme = null) { 14 | return $theme; 15 | } 16 | ], 17 | 'computed' => [ 18 | 'text' => function () { 19 | if ($this->text) { 20 | $text = $this->model()->toString($this->text); 21 | $text = $this->kirby()->kirbytext($text); 22 | return $text; 23 | } 24 | }, 25 | ], 26 | 'toArray' => function () { 27 | return [ 28 | 'options' => [ 29 | 'headline' => $this->headline, 30 | 'text' => $this->text, 31 | 'theme' => $this->theme 32 | ] 33 | ]; 34 | } 35 | ]; 36 | -------------------------------------------------------------------------------- /kirby/config/sections/mixins/empty.php: -------------------------------------------------------------------------------- 1 | [ 7 | /** 8 | * Sets the text for the empty state box 9 | */ 10 | 'empty' => function ($empty = null) { 11 | return I18n::translate($empty, $empty); 12 | } 13 | ], 14 | 'computed' => [ 15 | 'empty' => function () { 16 | if ($this->empty) { 17 | return $this->model()->toString($this->empty); 18 | } 19 | } 20 | ] 21 | ]; 22 | -------------------------------------------------------------------------------- /kirby/config/sections/mixins/headline.php: -------------------------------------------------------------------------------- 1 | [ 7 | /** 8 | * The headline for the section. This can be a simple string or a template with additional info from the parent page. 9 | */ 10 | 'headline' => function ($headline = null) { 11 | return I18n::translate($headline, $headline); 12 | } 13 | ], 14 | 'computed' => [ 15 | 'headline' => function () { 16 | if ($this->headline) { 17 | return $this->model()->toString($this->headline); 18 | } 19 | 20 | return ucfirst($this->name); 21 | } 22 | ] 23 | ]; 24 | -------------------------------------------------------------------------------- /kirby/config/sections/mixins/help.php: -------------------------------------------------------------------------------- 1 | [ 7 | /** 8 | * Sets the help text 9 | */ 10 | 'help' => function ($help = null) { 11 | return I18n::translate($help, $help); 12 | } 13 | ], 14 | 'computed' => [ 15 | 'help' => function () { 16 | if ($this->help) { 17 | $help = $this->model()->toString($this->help); 18 | $help = $this->kirby()->kirbytext($help); 19 | return $help; 20 | } 21 | } 22 | ] 23 | ]; 24 | -------------------------------------------------------------------------------- /kirby/config/sections/mixins/layout.php: -------------------------------------------------------------------------------- 1 | [ 5 | /** 6 | * Section layout. Available layout methods: `list`, `cards`. 7 | */ 8 | 'layout' => function (string $layout = 'list') { 9 | return $layout === 'cards' ? 'cards' : 'list'; 10 | } 11 | ] 12 | ]; 13 | -------------------------------------------------------------------------------- /kirby/config/sections/mixins/max.php: -------------------------------------------------------------------------------- 1 | [ 5 | /** 6 | * Sets the maximum number of allowed entries in the section 7 | */ 8 | 'max' => function (int $max = null) { 9 | return $max; 10 | } 11 | ], 12 | 'methods' => [ 13 | 'isFull' => function () { 14 | if ($this->max) { 15 | return $this->total >= $this->max; 16 | } 17 | 18 | return false; 19 | }, 20 | 'validateMax' => function () { 21 | if ($this->max && $this->total > $this->max) { 22 | return false; 23 | } 24 | 25 | return true; 26 | } 27 | ] 28 | ]; 29 | -------------------------------------------------------------------------------- /kirby/config/sections/mixins/min.php: -------------------------------------------------------------------------------- 1 | [ 5 | /** 6 | * Sets the minimum number of required entries in the section 7 | */ 8 | 'min' => function (int $min = null) { 9 | return $min; 10 | } 11 | ], 12 | 'methods' => [ 13 | 'validateMin' => function () { 14 | if ($this->min && $this->min > $this->total) { 15 | return false; 16 | } 17 | 18 | return true; 19 | } 20 | ] 21 | ]; 22 | -------------------------------------------------------------------------------- /kirby/config/sections/mixins/pagination.php: -------------------------------------------------------------------------------- 1 | [ 7 | /** 8 | * Sets the number of items per page. If there are more items the pagination navigation will be shown at the bottom of the section. 9 | */ 10 | 'limit' => function (int $limit = 20) { 11 | return $limit; 12 | }, 13 | /** 14 | * Sets the default page for the pagination. This will overwrite default pagination. 15 | */ 16 | 'page' => function (int $page = null) { 17 | return get('page', $page); 18 | }, 19 | ], 20 | 'methods' => [ 21 | 'pagination' => function () { 22 | $pagination = new Pagination([ 23 | 'limit' => $this->limit, 24 | 'page' => $this->page, 25 | 'total' => $this->total 26 | ]); 27 | 28 | return [ 29 | 'limit' => $pagination->limit(), 30 | 'offset' => $pagination->offset(), 31 | 'page' => $pagination->page(), 32 | 'total' => $pagination->total(), 33 | ]; 34 | }, 35 | ] 36 | ]; 37 | -------------------------------------------------------------------------------- /kirby/config/sections/mixins/parent.php: -------------------------------------------------------------------------------- 1 | [ 7 | /** 8 | * Sets the query to a parent to find items for the list 9 | */ 10 | 'parent' => function (string $parent = null) { 11 | return $parent; 12 | } 13 | ], 14 | 'methods' => [ 15 | 'parentModel' => function () { 16 | $parent = $this->parent; 17 | 18 | if (is_string($parent) === true) { 19 | $query = $parent; 20 | $parent = $this->model->query($query); 21 | 22 | if (!$parent) { 23 | throw new Exception('The parent for the query "' . $query . '" cannot be found in the section "' . $this->name() . '"'); 24 | } 25 | 26 | if ( 27 | is_a($parent, 'Kirby\Cms\Page') === false && 28 | is_a($parent, 'Kirby\Cms\Site') === false && 29 | is_a($parent, 'Kirby\Cms\File') === false && 30 | is_a($parent, 'Kirby\Cms\User') === false 31 | ) { 32 | throw new Exception('The parent for the section "' . $this->name() . '" has to be a page, site or user object'); 33 | } 34 | } 35 | 36 | if ($parent === null) { 37 | return $this->model; 38 | } 39 | 40 | return $parent; 41 | } 42 | ] 43 | ]; 44 | -------------------------------------------------------------------------------- /kirby/config/setup.php: -------------------------------------------------------------------------------- 1 | $blocksRoot . '/code/code.php', 8 | 'blocks/gallery' => $blocksRoot . '/gallery/gallery.php', 9 | 'blocks/heading' => $blocksRoot . '/heading/heading.php', 10 | 'blocks/image' => $blocksRoot . '/image/image.php', 11 | 'blocks/list' => $blocksRoot . '/list/list.php', 12 | 'blocks/markdown' => $blocksRoot . '/markdown/markdown.php', 13 | 'blocks/quote' => $blocksRoot . '/quote/quote.php', 14 | 'blocks/table' => $blocksRoot . '/table/table.php', 15 | 'blocks/text' => $blocksRoot . '/text/text.php', 16 | 'blocks/video' => $blocksRoot . '/video/video.php', 17 | ]; 18 | -------------------------------------------------------------------------------- /kirby/config/templates.php: -------------------------------------------------------------------------------- 1 | __DIR__ . '/templates/emails/auth/login.php', 6 | 'emails/auth/password-reset' => __DIR__ . '/templates/emails/auth/password-reset.php' 7 | ]; 8 | // @codeCoverageIgnoreEnd 9 | -------------------------------------------------------------------------------- /kirby/config/templates/emails/auth/login.php: -------------------------------------------------------------------------------- 1 | language()); 9 | -------------------------------------------------------------------------------- /kirby/config/templates/emails/auth/password-reset.php: -------------------------------------------------------------------------------- 1 | language()); 9 | -------------------------------------------------------------------------------- /kirby/config/urls.php: -------------------------------------------------------------------------------- 1 | function () { 7 | return Url::index(); 8 | }, 9 | 'base' => function (array $urls) { 10 | return rtrim($urls['index'], '/'); 11 | }, 12 | 'current' => function (array $urls) { 13 | $path = trim($this->path(), '/'); 14 | 15 | if (empty($path) === true) { 16 | return $urls['index']; 17 | } else { 18 | return $urls['base'] . '/' . $path; 19 | } 20 | }, 21 | 'assets' => function (array $urls) { 22 | return $urls['base'] . '/assets'; 23 | }, 24 | 'api' => function (array $urls) { 25 | return $urls['base'] . '/' . ($this->options['api']['slug'] ?? 'api'); 26 | }, 27 | 'media' => function (array $urls) { 28 | return $urls['base'] . '/media'; 29 | }, 30 | 'panel' => function (array $urls) { 31 | return $urls['base'] . '/' . ($this->options['panel']['slug'] ?? 'panel'); 32 | } 33 | ]; 34 | -------------------------------------------------------------------------------- /kirby/i18n/rules/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2012-217 Florian Eckerstorfer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /kirby/i18n/rules/ar.json: -------------------------------------------------------------------------------- 1 | { 2 | "أ" : "a", 3 | "ب" : "b", 4 | "ت" : "t", 5 | "ث" : "th", 6 | "ج" : "g", 7 | "ح" : "h", 8 | "خ" : "kh", 9 | "د" : "d", 10 | "ذ" : "th", 11 | "ر" : "r", 12 | "ز" : "z", 13 | "س" : "s", 14 | "ش" : "sh", 15 | "ص" : "s", 16 | "ض" : "d", 17 | "ط" : "t", 18 | "ظ" : "th", 19 | "ع" : "aa", 20 | "غ" : "gh", 21 | "ف" : "f", 22 | "ق" : "k", 23 | "ك" : "k", 24 | "ل" : "l", 25 | "م" : "m", 26 | "ن" : "n", 27 | "ه" : "h", 28 | "و" : "o", 29 | "ي" : "y" 30 | } 31 | -------------------------------------------------------------------------------- /kirby/i18n/rules/az.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ə": "E", 3 | "Ç": "C", 4 | "Ğ": "G", 5 | "İ": "I", 6 | "Ş": "S", 7 | "Ö": "O", 8 | "Ü": "U", 9 | "ə": "e", 10 | "ç": "c", 11 | "ğ": "g", 12 | "ı": "i", 13 | "ş": "s", 14 | "ö": "o", 15 | "ü": "u" 16 | } 17 | -------------------------------------------------------------------------------- /kirby/i18n/rules/bg.json: -------------------------------------------------------------------------------- 1 | { 2 | "А": "A", 3 | "Б": "B", 4 | "В": "V", 5 | "Г": "G", 6 | "Д": "D", 7 | "Е": "E", 8 | "Ж": "J", 9 | "З": "Z", 10 | "И": "I", 11 | "Й": "Y", 12 | "К": "K", 13 | "Л": "L", 14 | "М": "M", 15 | "Н": "N", 16 | "О": "O", 17 | "П": "P", 18 | "Р": "R", 19 | "С": "S", 20 | "Т": "T", 21 | "У": "U", 22 | "Ф": "F", 23 | "Х": "H", 24 | "Ц": "Ts", 25 | "Ч": "Ch", 26 | "Ш": "Sh", 27 | "Щ": "Sht", 28 | "Ъ": "A", 29 | "Ь": "I", 30 | "Ю": "Iu", 31 | "Я": "Ia", 32 | "а": "a", 33 | "б": "b", 34 | "в": "v", 35 | "г": "g", 36 | "д": "d", 37 | "е": "e", 38 | "ж": "j", 39 | "з": "z", 40 | "и": "i", 41 | "й": "y", 42 | "к": "k", 43 | "л": "l", 44 | "м": "m", 45 | "н": "n", 46 | "о": "o", 47 | "п": "p", 48 | "р": "r", 49 | "с": "s", 50 | "т": "t", 51 | "у": "u", 52 | "ф": "f", 53 | "х": "h", 54 | "ц": "ts", 55 | "ч": "ch", 56 | "ш": "sh", 57 | "щ": "sht", 58 | "ъ": "a", 59 | "ь": "i", 60 | "ю": "iu", 61 | "я": "ia", 62 | "ия": "ia", 63 | "йо": "iо", 64 | "ьо": "io" 65 | } 66 | -------------------------------------------------------------------------------- /kirby/i18n/rules/cs.json: -------------------------------------------------------------------------------- 1 | { 2 | "Č": "C", 3 | "Ď": "D", 4 | "Ě": "E", 5 | "Ň": "N", 6 | "Ř": "R", 7 | "Š": "S", 8 | "Ť": "T", 9 | "Ů": "U", 10 | "Ž": "Z", 11 | "č": "c", 12 | "ď": "d", 13 | "ě": "e", 14 | "ň": "n", 15 | "ř": "r", 16 | "š": "s", 17 | "ť": "t", 18 | "ů": "u", 19 | "ž": "z" 20 | } 21 | -------------------------------------------------------------------------------- /kirby/i18n/rules/da.json: -------------------------------------------------------------------------------- 1 | { 2 | "Æ": "Ae", 3 | "æ": "ae", 4 | "Ø": "Oe", 5 | "ø": "oe", 6 | "Å": "Aa", 7 | "å": "aa", 8 | "É": "E", 9 | "é": "e" 10 | } 11 | -------------------------------------------------------------------------------- /kirby/i18n/rules/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ä": "AE", 3 | "Ö": "OE", 4 | "Ü": "UE", 5 | "ß": "ss", 6 | "ä": "ae", 7 | "ö": "oe", 8 | "ü": "ue" 9 | } 10 | -------------------------------------------------------------------------------- /kirby/i18n/rules/eo.json: -------------------------------------------------------------------------------- 1 | { 2 | "ĉ": "cx", 3 | "ĝ": "gx", 4 | "ĥ": "hx", 5 | "ĵ": "jx", 6 | "ŝ": "sx", 7 | "ŭ": "ux", 8 | "Ĉ": "CX", 9 | "Ĝ": "GX", 10 | "Ĥ": "HX", 11 | "Ĵ": "JX", 12 | "Ŝ": "SX", 13 | "Ŭ": "UX" 14 | } 15 | -------------------------------------------------------------------------------- /kirby/i18n/rules/et.json: -------------------------------------------------------------------------------- 1 | { 2 | "Š": "S", 3 | "Ž": "Z", 4 | "Õ": "O", 5 | "Ä": "A", 6 | "Ö": "O", 7 | "Ü": "U", 8 | "š": "s", 9 | "ž": "z", 10 | "õ": "o", 11 | "ä": "a", 12 | "ö": "o", 13 | "ü": "u" 14 | } -------------------------------------------------------------------------------- /kirby/i18n/rules/fa.json: -------------------------------------------------------------------------------- 1 | { 2 | "آ" : "A", 3 | "ا" : "a", 4 | "ب" : "b", 5 | "پ" : "p", 6 | "ت" : "t", 7 | "ث" : "th", 8 | "ج" : "j", 9 | "چ" : "ch", 10 | "ح" : "h", 11 | "خ" : "kh", 12 | "د" : "d", 13 | "ذ" : "th", 14 | "ر" : "r", 15 | "ز" : "z", 16 | "ژ" : "zh", 17 | "س" : "s", 18 | "ش" : "sh", 19 | "ص" : "s", 20 | "ض" : "z", 21 | "ط" : "t", 22 | "ظ" : "z", 23 | "ع" : "a", 24 | "غ" : "gh", 25 | "ف" : "f", 26 | "ق" : "g", 27 | "ك" : "k", 28 | "ک" : "k", 29 | "گ" : "g", 30 | "ل" : "l", 31 | "م" : "m", 32 | "ن" : "n", 33 | "و" : "o", 34 | "ه" : "h", 35 | "ی" : "y" 36 | } 37 | -------------------------------------------------------------------------------- /kirby/i18n/rules/fi.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ä": "A", 3 | "Ö": "O", 4 | "ä": "a", 5 | "ö": "o" 6 | } 7 | -------------------------------------------------------------------------------- /kirby/i18n/rules/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "À": "A", 3 | "Â": "A", 4 | "Æ": "AE", 5 | "Ç": "C", 6 | "É": "E", 7 | "È": "E", 8 | "Ê": "E", 9 | "Ë": "E", 10 | "Ï": "I", 11 | "Î": "I", 12 | "Ô": "O", 13 | "Œ": "OE", 14 | "Ù": "U", 15 | "Û": "U", 16 | "Ü": "U", 17 | "à": "a", 18 | "â": "a", 19 | "æ": "ae", 20 | "ç": "c", 21 | "é": "e", 22 | "è": "e", 23 | "ê": "e", 24 | "ë": "e", 25 | "ï": "i", 26 | "î": "i", 27 | "ô": "o", 28 | "œ": "oe", 29 | "ù": "u", 30 | "û": "u", 31 | "ü": "u", 32 | "ÿ": "y", 33 | "Ÿ": "Y" 34 | } 35 | -------------------------------------------------------------------------------- /kirby/i18n/rules/hi.json: -------------------------------------------------------------------------------- 1 | { 2 | "अ": "a", 3 | "आ": "aa", 4 | "ए": "e", 5 | "ई": "ii", 6 | "ऍ": "ei", 7 | "ऎ": "ae", 8 | "ऐ": "ai", 9 | "इ": "i", 10 | "ओ": "o", 11 | "ऑ": "oi", 12 | "ऒ": "oii", 13 | "ऊ": "uu", 14 | "औ": "ou", 15 | "उ": "u", 16 | "ब": "B", 17 | "भ": "Bha", 18 | "च": "Ca", 19 | "छ": "Chha", 20 | "ड": "Da", 21 | "ढ": "Dha", 22 | "फ": "Fa", 23 | "फ़": "Fi", 24 | "ग": "Ga", 25 | "घ": "Gha", 26 | "ग़": "Ghi", 27 | "ह": "Ha", 28 | "ज": "Ja", 29 | "झ": "Jha", 30 | "क": "Ka", 31 | "ख": "Kha", 32 | "ख़": "Khi", 33 | "ल": "L", 34 | "ळ": "Li", 35 | "ऌ": "Li", 36 | "ऴ": "Lii", 37 | "ॡ": "Lii", 38 | "म": "Ma", 39 | "न": "Na", 40 | "ङ": "Na", 41 | "ञ": "Nia", 42 | "ण": "Nae", 43 | "ऩ": "Ni", 44 | "ॐ": "oms", 45 | "प": "Pa", 46 | "क़": "Qi", 47 | "र": "Ra", 48 | "ऋ": "Ri", 49 | "ॠ": "Ri", 50 | "ऱ": "Ri", 51 | "स": "Sa", 52 | "श": "Sha", 53 | "ष": "Shha", 54 | "ट": "Ta", 55 | "त": "Ta", 56 | "ठ": "Tha", 57 | "द": "Tha", 58 | "थ": "Tha", 59 | "ध": "Thha", 60 | "ड़": "ugDha", 61 | "ढ़": "ugDhha", 62 | "व": "Va", 63 | "य": "Ya", 64 | "य़": "Yi", 65 | "ज़": "Za" 66 | } 67 | -------------------------------------------------------------------------------- /kirby/i18n/rules/hr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Č": "C", 3 | "Ć": "C", 4 | "Ž": "Z", 5 | "Š": "S", 6 | "Đ": "Dj", 7 | "č": "c", 8 | "ć": "c", 9 | "ž": "z", 10 | "š": "s", 11 | "đ": "dj" 12 | } -------------------------------------------------------------------------------- /kirby/i18n/rules/hu.json: -------------------------------------------------------------------------------- 1 | { 2 | "Á": "a", 3 | "É": "e", 4 | "Í": "i", 5 | "Ó": "o", 6 | "Ö": "o", 7 | "Ő": "o", 8 | "Ú": "u", 9 | "Ü": "u", 10 | "Ű": "u", 11 | "á": "a", 12 | "é": "e", 13 | "í": "i", 14 | "ó": "o", 15 | "ö": "o", 16 | "ő": "o", 17 | "ú": "u", 18 | "ü": "u", 19 | "ű": "u" 20 | } 21 | -------------------------------------------------------------------------------- /kirby/i18n/rules/hy.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ա": "A", 3 | "Բ": "B", 4 | "Գ": "G", 5 | "Դ": "D", 6 | "Ե": "E", 7 | "Զ": "Z", 8 | "Է": "E", 9 | "Ը": "Y", 10 | "Թ": "Th", 11 | "Ժ": "Zh", 12 | "Ի": "I", 13 | "Լ": "L", 14 | "Խ": "Kh", 15 | "Ծ": "Ts", 16 | "Կ": "K", 17 | "Հ": "H", 18 | "Ձ": "Dz", 19 | "Ղ": "Gh", 20 | "Ճ": "Tch", 21 | "Մ": "M", 22 | "Յ": "Y", 23 | "Ն": "N", 24 | "Շ": "Sh", 25 | "Ո": "Vo", 26 | "Չ": "Ch", 27 | "Պ": "P", 28 | "Ջ": "J", 29 | "Ռ": "R", 30 | "Ս": "S", 31 | "Վ": "V", 32 | "Տ": "T", 33 | "Ր": "R", 34 | "Ց": "C", 35 | "Ւ": "u", 36 | "Փ": "Ph", 37 | "Ք": "Q", 38 | "և": "ev", 39 | "Օ": "O", 40 | "Ֆ": "F", 41 | "ա": "a", 42 | "բ": "b", 43 | "գ": "g", 44 | "դ": "d", 45 | "ե": "e", 46 | "զ": "z", 47 | "է": "e", 48 | "ը": "y", 49 | "թ": "th", 50 | "ժ": "zh", 51 | "ի": "i", 52 | "լ": "l", 53 | "խ": "kh", 54 | "ծ": "ts", 55 | "կ": "k", 56 | "հ": "h", 57 | "ձ": "dz", 58 | "ղ": "gh", 59 | "ճ": "tch", 60 | "մ": "m", 61 | "յ": "y", 62 | "ն": "n", 63 | "շ": "sh", 64 | "ո": "vo", 65 | "չ": "ch", 66 | "պ": "p", 67 | "ջ": "j", 68 | "ռ": "r", 69 | "ս": "s", 70 | "վ": "v", 71 | "տ": "t", 72 | "ր": "r", 73 | "ց": "c", 74 | "ւ": "u", 75 | "փ": "ph", 76 | "ք": "q", 77 | "օ": "o", 78 | "ֆ": "f" 79 | } 80 | -------------------------------------------------------------------------------- /kirby/i18n/rules/it.json: -------------------------------------------------------------------------------- 1 | { 2 | "À": "a", 3 | "È": "e", 4 | "Ì": "i", 5 | "Ò": "o", 6 | "Ù": "u", 7 | "à": "a", 8 | "é": "e", 9 | "è": "e", 10 | "ì": "i", 11 | "ò": "o", 12 | "ù": "u" 13 | } 14 | -------------------------------------------------------------------------------- /kirby/i18n/rules/ka.json: -------------------------------------------------------------------------------- 1 | { 2 | "ა": "a", 3 | "ბ": "b", 4 | "გ": "g", 5 | "დ": "d", 6 | "ე": "e", 7 | "ვ": "v", 8 | "ზ": "z", 9 | "თ": "t", 10 | "ი": "i", 11 | "კ": "k", 12 | "ლ": "l", 13 | "მ": "m", 14 | "ნ": "n", 15 | "ო": "o", 16 | "პ": "p", 17 | "ჟ": "zh", 18 | "რ": "r", 19 | "ს": "s", 20 | "ტ": "t", 21 | "უ": "u", 22 | "ფ": "f", 23 | "ქ": "k", 24 | "ღ": "gh", 25 | "ყ": "q", 26 | "შ": "sh", 27 | "ჩ": "ch", 28 | "ც": "ts", 29 | "ძ": "dz", 30 | "წ": "ts", 31 | "ჭ": "ch", 32 | "ხ": "kh", 33 | "ჯ": "j", 34 | "ჰ": "h" 35 | } 36 | -------------------------------------------------------------------------------- /kirby/i18n/rules/lt.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ą": "A", 3 | "Č": "C", 4 | "Ę": "E", 5 | "Ė": "E", 6 | "Į": "I", 7 | "Š": "S", 8 | "Ų": "U", 9 | "Ū": "U", 10 | "Ž": "Z", 11 | "ą": "a", 12 | "č": "c", 13 | "ę": "e", 14 | "ė": "e", 15 | "į": "i", 16 | "š": "s", 17 | "ų": "u", 18 | "ū": "u", 19 | "ž": "z" 20 | } 21 | -------------------------------------------------------------------------------- /kirby/i18n/rules/lv.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ā": "A", 3 | "Ē": "E", 4 | "Ģ": "G", 5 | "Ī": "I", 6 | "Ķ": "K", 7 | "Ļ": "L", 8 | "Ņ": "N", 9 | "Ū": "U", 10 | "ā": "a", 11 | "ē": "e", 12 | "ģ": "g", 13 | "ī": "i", 14 | "ķ": "k", 15 | "ļ": "l", 16 | "ņ": "n", 17 | "ū": "u" 18 | } 19 | -------------------------------------------------------------------------------- /kirby/i18n/rules/mk.json: -------------------------------------------------------------------------------- 1 | { 2 | "А": "A", 3 | "Б": "B", 4 | "В": "V", 5 | "Г": "G", 6 | "Д": "D", 7 | "Ѓ": "Gj", 8 | "Е": "E", 9 | "Ж": "Zh", 10 | "З": "Z", 11 | "Ѕ": "Dz", 12 | "И": "I", 13 | "Ј": "J", 14 | "К": "K", 15 | "Л": "L", 16 | "Љ": "Lj", 17 | "М": "M", 18 | "Н": "N", 19 | "Њ": "Nj", 20 | "О": "O", 21 | "П": "P", 22 | "Р": "R", 23 | "С": "S", 24 | "Т": "T", 25 | "Ќ": "Kj", 26 | "У": "U", 27 | "Ф": "F", 28 | "Х": "H", 29 | "Ц": "C", 30 | "Ч": "Ch", 31 | "Џ": "Dj", 32 | "Ш": "Sh", 33 | "а": "a", 34 | "б": "b", 35 | "в": "v", 36 | "г": "g", 37 | "д": "d", 38 | "ѓ": "gj", 39 | "е": "e", 40 | "ж": "zh", 41 | "з": "z", 42 | "ѕ": "dz", 43 | "и": "i", 44 | "ј": "j", 45 | "к": "k", 46 | "л": "l", 47 | "љ": "lj", 48 | "м": "m", 49 | "н": "n", 50 | "њ": "nj", 51 | "о": "o", 52 | "п": "p", 53 | "р": "r", 54 | "с": "s", 55 | "т": "t", 56 | "ќ": "kj", 57 | "у": "u", 58 | "ф": "f", 59 | "х": "h", 60 | "ц": "c", 61 | "ч": "ch", 62 | "џ": "dj", 63 | "ш": "sh" 64 | } 65 | -------------------------------------------------------------------------------- /kirby/i18n/rules/nb.json: -------------------------------------------------------------------------------- 1 | { 2 | "Æ": "AE", 3 | "Ø": "OE", 4 | "Å": "AA", 5 | "æ": "ae", 6 | "ø": "oe", 7 | "å": "aa" 8 | } 9 | -------------------------------------------------------------------------------- /kirby/i18n/rules/pl.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ą": "A", 3 | "Ć": "C", 4 | "Ę": "E", 5 | "Ł": "L", 6 | "Ń": "N", 7 | "Ó": "O", 8 | "Ś": "S", 9 | "Ź": "Z", 10 | "Ż": "Z", 11 | "ą": "a", 12 | "ć": "c", 13 | "ę": "e", 14 | "ł": "l", 15 | "ń": "n", 16 | "ó": "o", 17 | "ś": "s", 18 | "ź": "z", 19 | "ż": "z" 20 | } 21 | -------------------------------------------------------------------------------- /kirby/i18n/rules/rm.json: -------------------------------------------------------------------------------- 1 | { 2 | "ă": "a", 3 | "î": "i", 4 | "â": "a", 5 | "ş": "s", 6 | "ș": "s", 7 | "ţ": "t", 8 | "ț": "t", 9 | "Ă": "A", 10 | "Î": "I", 11 | "Â": "A", 12 | "Ş": "S", 13 | "Ș": "S", 14 | "Ţ": "T", 15 | "Ț": "T" 16 | } 17 | -------------------------------------------------------------------------------- /kirby/i18n/rules/ru.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ъ": "", 3 | "Ь": "", 4 | "А": "A", 5 | "Б": "B", 6 | "Ц": "C", 7 | "Ч": "Ch", 8 | "Д": "D", 9 | "Е": "E", 10 | "Ё": "E", 11 | "Э": "E", 12 | "Ф": "F", 13 | "Г": "G", 14 | "Х": "H", 15 | "И": "I", 16 | "Й": "Y", 17 | "Я": "Ya", 18 | "Ю": "Yu", 19 | "К": "K", 20 | "Л": "L", 21 | "М": "M", 22 | "Н": "N", 23 | "О": "O", 24 | "П": "P", 25 | "Р": "R", 26 | "С": "S", 27 | "Ш": "Sh", 28 | "Щ": "Shch", 29 | "Т": "T", 30 | "У": "U", 31 | "В": "V", 32 | "Ы": "Y", 33 | "З": "Z", 34 | "Ж": "Zh", 35 | "ъ": "", 36 | "ь": "", 37 | "а": "a", 38 | "б": "b", 39 | "ц": "c", 40 | "ч": "ch", 41 | "д": "d", 42 | "е": "e", 43 | "ё": "e", 44 | "э": "e", 45 | "ф": "f", 46 | "г": "g", 47 | "х": "h", 48 | "и": "i", 49 | "й": "y", 50 | "я": "ya", 51 | "ю": "yu", 52 | "к": "k", 53 | "л": "l", 54 | "м": "m", 55 | "н": "n", 56 | "о": "o", 57 | "п": "p", 58 | "р": "r", 59 | "с": "s", 60 | "ш": "sh", 61 | "щ": "shch", 62 | "т": "t", 63 | "у": "u", 64 | "в": "v", 65 | "ы": "y", 66 | "з": "z", 67 | "ж": "zh" 68 | } 69 | -------------------------------------------------------------------------------- /kirby/i18n/rules/sr.json: -------------------------------------------------------------------------------- 1 | { 2 | "а": "a", 3 | "б": "b", 4 | "в": "v", 5 | "г": "g", 6 | "д": "d", 7 | "ђ": "dj", 8 | "е": "e", 9 | "ж": "z", 10 | "з": "z", 11 | "и": "i", 12 | "ј": "j", 13 | "к": "k", 14 | "л": "l", 15 | "љ": "lj", 16 | "м": "m", 17 | "н": "n", 18 | "њ": "nj", 19 | "о": "o", 20 | "п": "p", 21 | "р": "r", 22 | "с": "s", 23 | "т": "t", 24 | "ћ": "c", 25 | "у": "u", 26 | "ф": "f", 27 | "х": "h", 28 | "ц": "c", 29 | "ч": "c", 30 | "џ": "dz", 31 | "ш": "s", 32 | "А": "A", 33 | "Б": "B", 34 | "В": "V", 35 | "Г": "G", 36 | "Д": "D", 37 | "Ђ": "Dj", 38 | "Е": "E", 39 | "Ж": "Z", 40 | "З": "Z", 41 | "И": "I", 42 | "Ј": "J", 43 | "К": "K", 44 | "Л": "L", 45 | "Љ": "Lj", 46 | "М": "M", 47 | "Н": "N", 48 | "Њ": "Nj", 49 | "О": "O", 50 | "П": "P", 51 | "Р": "R", 52 | "С": "S", 53 | "Т": "T", 54 | "Ћ": "C", 55 | "У": "U", 56 | "Ф": "F", 57 | "Х": "H", 58 | "Ц": "C", 59 | "Ч": "C", 60 | "Џ": "Dz", 61 | "Ш": "S", 62 | "š": "s", 63 | "đ": "dj", 64 | "ž": "z", 65 | "ć": "c", 66 | "č": "c", 67 | "Š": "S", 68 | "Đ": "DJ", 69 | "Ž": "Z", 70 | "Ć": "C", 71 | "Č": "C" 72 | } -------------------------------------------------------------------------------- /kirby/i18n/rules/sv_SE.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ä": "A", 3 | "Å": "a", 4 | "Ö": "O", 5 | "ä": "a", 6 | "å": "a", 7 | "ö": "o" 8 | } 9 | -------------------------------------------------------------------------------- /kirby/i18n/rules/tr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ç": "C", 3 | "Ğ": "G", 4 | "İ": "I", 5 | "Ş": "S", 6 | "Ö": "O", 7 | "Ü": "U", 8 | "ç": "c", 9 | "ğ": "g", 10 | "ı": "i", 11 | "ş": "s", 12 | "ö": "o", 13 | "ü": "u" 14 | } 15 | -------------------------------------------------------------------------------- /kirby/i18n/rules/uk.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ґ": "G", 3 | "І": "I", 4 | "Ї": "Ji", 5 | "Є": "Ye", 6 | "ґ": "g", 7 | "і": "i", 8 | "ї": "ji", 9 | "є": "ye" 10 | } 11 | -------------------------------------------------------------------------------- /kirby/kirby.pub: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Ux4q7LmQ5hfTYTtz3/a 3 | mohFJMWo/iCnxVcY84PZjLwWnT+G2DTKGaEWydB77TteJQnmsgtvO5734oj3Ga3r 4 | QCfwr2gxo/0WDEBq7C5HP+YNJiuZ/iD/tYV+gloF+Aaa3Mo8AK5DYH3dnjuyfHc1 5 | veIlYX1D2MXji2IRqdweAzVi1dfI4I3Ys8awhzv653vFLj5LvAtlwlYlmYeRwci7 6 | GkAOWw709CuKQNdPBXGFQQ/pEB5mnp8mI31j8og845u6v/Sk4+85gFORSufIRfnQ 7 | GFYrPOeavxfAWQGjh7JQjr/sbKSXaJ3nDlrYsOPIrC0Rwn/jsQPO7OLdVwkc9ofL 8 | GQIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /kirby/panel/dist/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/f-mahler/vuekit/1d23b74fc0f8a5b470dc3429cf371c464fcd3695/kirby/panel/dist/apple-touch-icon.png -------------------------------------------------------------------------------- /kirby/panel/dist/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/f-mahler/vuekit/1d23b74fc0f8a5b470dc3429cf371c464fcd3695/kirby/panel/dist/favicon.png -------------------------------------------------------------------------------- /kirby/panel/dist/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | -------------------------------------------------------------------------------- /kirby/router.php: -------------------------------------------------------------------------------- 1 | 10 | * @link https://getkirby.com 11 | * @copyright Bastian Allgeier GmbH 12 | * @license https://opensource.org/licenses/MIT 13 | */ 14 | class NullCache extends Cache 15 | { 16 | /** 17 | * Writes an item to the cache for a given number of minutes and 18 | * returns whether the operation was successful 19 | * 20 | * 21 | * // put an item in the cache for 15 minutes 22 | * $cache->set('value', 'my value', 15); 23 | * 24 | * 25 | * @param string $key 26 | * @param mixed $value 27 | * @param int $minutes 28 | * @return bool 29 | */ 30 | public function set(string $key, $value, int $minutes = 0): bool 31 | { 32 | return true; 33 | } 34 | 35 | /** 36 | * Internal method to retrieve the raw cache value; 37 | * needs to return a Value object or null if not found 38 | * 39 | * @param string $key 40 | * @return \Kirby\Cache\Value|null 41 | */ 42 | public function retrieve(string $key) 43 | { 44 | return null; 45 | } 46 | 47 | /** 48 | * Removes an item from the cache and returns 49 | * whether the operation was successful 50 | * 51 | * @param string $key 52 | * @return bool 53 | */ 54 | public function remove(string $key): bool 55 | { 56 | return true; 57 | } 58 | 59 | /** 60 | * Flushes the entire cache and returns 61 | * whether the operation was successful 62 | * 63 | * @return bool 64 | */ 65 | public function flush(): bool 66 | { 67 | return true; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /kirby/src/Cms/FilePermissions.php: -------------------------------------------------------------------------------- 1 | 10 | * @link https://getkirby.com 11 | * @copyright Bastian Allgeier GmbH 12 | * @license https://getkirby.com/license 13 | */ 14 | class FilePermissions extends ModelPermissions 15 | { 16 | protected $category = 'files'; 17 | } 18 | -------------------------------------------------------------------------------- /kirby/src/Cms/Html.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier GmbH 14 | * @license https://getkirby.com/license 15 | */ 16 | class Html extends \Kirby\Toolkit\Html 17 | { 18 | /** 19 | * Generates an `a` tag with an absolute Url 20 | * 21 | * @param string|null $href Relative or absolute Url 22 | * @param string|array|null $text If `null`, the link will be used as link text. If an array is passed, each element will be added unencoded 23 | * @param array $attr Additional attributes for the a tag. 24 | * @return string 25 | */ 26 | public static function link(string $href = null, $text = null, array $attr = []): string 27 | { 28 | return parent::link(Url::to($href), $text, $attr); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /kirby/src/Cms/KirbyTag.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier GmbH 13 | * @license https://getkirby.com/license 14 | */ 15 | class KirbyTag extends \Kirby\Text\KirbyTag 16 | { 17 | /** 18 | * Finds a file for the given path. 19 | * The method first searches the file 20 | * in the current parent, if it's a page. 21 | * Afterwards it uses Kirby's global file finder. 22 | * 23 | * @param string $path 24 | * @return \Kirby\Cms\File|null 25 | */ 26 | public function file(string $path) 27 | { 28 | $parent = $this->parent(); 29 | 30 | if ( 31 | is_object($parent) === true && 32 | method_exists($parent, 'file') === true && 33 | $file = $parent->file($path) 34 | ) { 35 | return $file; 36 | } 37 | 38 | if (is_a($parent, 'Kirby\Cms\File') === true && $file = $parent->page()->file($path)) { 39 | return $file; 40 | } 41 | 42 | return $this->kirby()->file($path, null, true); 43 | } 44 | 45 | /** 46 | * Returns the current Kirby instance 47 | * 48 | * @return \Kirby\Cms\App 49 | */ 50 | public function kirby() 51 | { 52 | return $this->data['kirby'] ?? App::instance(); 53 | } 54 | 55 | /** 56 | * Returns the parent model 57 | * 58 | * @return \Kirby\Cms\Model|null 59 | */ 60 | public function parent() 61 | { 62 | return $this->data['parent']; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /kirby/src/Cms/KirbyTags.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier GmbH 13 | * @license https://getkirby.com/license 14 | */ 15 | class KirbyTags extends \Kirby\Text\KirbyTags 16 | { 17 | /** 18 | * The KirbyTag rendering class 19 | * 20 | * @var string 21 | */ 22 | protected static $tagClass = 'Kirby\Cms\KirbyTag'; 23 | 24 | /** 25 | * @param string|null $text 26 | * @param array $data 27 | * @param array $options 28 | * @param \Kirby\Cms\App|null $app 29 | * @return string 30 | */ 31 | public static function parse(string $text = null, array $data = [], array $options = [], ?App $app = null): string 32 | { 33 | if ($app !== null) { 34 | $text = $app->apply('kirbytags:before', compact('text', 'data', 'options'), 'text'); 35 | } 36 | 37 | $text = parent::parse($text, $data, $options); 38 | 39 | if ($app !== null) { 40 | $text = $app->apply('kirbytags:after', compact('text', 'data', 'options'), 'text'); 41 | } 42 | 43 | return $text; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /kirby/src/Cms/LayoutColumns.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier GmbH 13 | * @license https://getkirby.com/license 14 | */ 15 | class LayoutColumns extends Items 16 | { 17 | const ITEM_CLASS = '\Kirby\Cms\LayoutColumn'; 18 | } 19 | -------------------------------------------------------------------------------- /kirby/src/Cms/Layouts.php: -------------------------------------------------------------------------------- 1 | 14 | * @link https://getkirby.com 15 | * @copyright Bastian Allgeier GmbH 16 | * @license https://getkirby.com/license 17 | */ 18 | class Layouts extends Items 19 | { 20 | const ITEM_CLASS = '\Kirby\Cms\Layout'; 21 | 22 | public static function factory(array $items = null, array $params = []) 23 | { 24 | $first = $items[0] ?? []; 25 | 26 | // if there are no wrapping layouts for blocks yet … 27 | if (array_key_exists('content', $first) === true || array_key_exists('type', $first) === true) { 28 | $items = [ 29 | [ 30 | 'id' => uuid(), 31 | 'columns' => [ 32 | [ 33 | 'width' => '1/1', 34 | 'blocks' => $items 35 | ] 36 | ] 37 | ] 38 | ]; 39 | } 40 | 41 | return parent::factory($items, $params); 42 | } 43 | 44 | /** 45 | * Parse layouts data 46 | * 47 | * @param array|string $input 48 | * @return array 49 | */ 50 | public static function parse($input): array 51 | { 52 | if (empty($input) === false && is_array($input) === false) { 53 | try { 54 | $input = Data::decode($input, 'json'); 55 | } catch (Throwable $e) { 56 | return []; 57 | } 58 | } 59 | 60 | if (empty($input) === true) { 61 | return []; 62 | } 63 | 64 | return $input; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /kirby/src/Cms/Nest.php: -------------------------------------------------------------------------------- 1 | 15 | * @link https://getkirby.com 16 | * @copyright Bastian Allgeier GmbH 17 | * @license https://getkirby.com/license 18 | */ 19 | class Nest 20 | { 21 | /** 22 | * @param $data 23 | * @param null $parent 24 | * @return mixed 25 | */ 26 | public static function create($data, $parent = null) 27 | { 28 | if (is_scalar($data) === true) { 29 | return new Field($parent, $data, $data); 30 | } 31 | 32 | $result = []; 33 | 34 | foreach ($data as $key => $value) { 35 | if (is_array($value) === true) { 36 | $result[$key] = static::create($value, $parent); 37 | } elseif (is_scalar($value) === true) { 38 | $result[$key] = new Field($parent, $key, $value); 39 | } 40 | } 41 | 42 | if (is_int(key($data))) { 43 | return new NestCollection($result); 44 | } else { 45 | return new NestObject($result); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /kirby/src/Cms/NestCollection.php: -------------------------------------------------------------------------------- 1 | 13 | * @link https://getkirby.com 14 | * @copyright Bastian Allgeier GmbH 15 | * @license https://getkirby.com/license 16 | */ 17 | class NestCollection extends BaseCollection 18 | { 19 | /** 20 | * Converts all objects in the collection 21 | * to an array. This can also take a callback 22 | * function to further modify the array result. 23 | * 24 | * @param \Closure|null $map 25 | * @return array 26 | */ 27 | public function toArray(Closure $map = null): array 28 | { 29 | return parent::toArray($map ?? function ($object) { 30 | return $object->toArray(); 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /kirby/src/Cms/NestObject.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier GmbH 14 | * @license https://getkirby.com/license 15 | */ 16 | class NestObject extends Obj 17 | { 18 | /** 19 | * Converts the object to an array 20 | * 21 | * @return array 22 | */ 23 | public function toArray(): array 24 | { 25 | $result = []; 26 | 27 | foreach ((array)$this as $key => $value) { 28 | if (is_a($value, 'Kirby\Cms\Field') === true) { 29 | $result[$key] = $value->value(); 30 | continue; 31 | } 32 | 33 | if (is_object($value) === true && method_exists($value, 'toArray')) { 34 | $result[$key] = $value->toArray(); 35 | continue; 36 | } 37 | 38 | $result[$key] = $value; 39 | } 40 | 41 | return $result; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /kirby/src/Cms/PagePermissions.php: -------------------------------------------------------------------------------- 1 | 10 | * @link https://getkirby.com 11 | * @copyright Bastian Allgeier GmbH 12 | * @license https://getkirby.com/license 13 | */ 14 | class PagePermissions extends ModelPermissions 15 | { 16 | /** 17 | * @var string 18 | */ 19 | protected $category = 'pages'; 20 | 21 | /** 22 | * @return bool 23 | */ 24 | protected function canChangeSlug(): bool 25 | { 26 | return $this->model->isHomeOrErrorPage() !== true; 27 | } 28 | 29 | /** 30 | * @return bool 31 | */ 32 | protected function canChangeStatus(): bool 33 | { 34 | return $this->model->isErrorPage() !== true; 35 | } 36 | 37 | /** 38 | * @return bool 39 | */ 40 | protected function canChangeTemplate(): bool 41 | { 42 | if ($this->model->isHomeOrErrorPage() === true) { 43 | return false; 44 | } 45 | 46 | if (count($this->model->blueprints()) <= 1) { 47 | return false; 48 | } 49 | 50 | return true; 51 | } 52 | 53 | /** 54 | * @return bool 55 | */ 56 | protected function canDelete(): bool 57 | { 58 | return $this->model->isHomeOrErrorPage() !== true; 59 | } 60 | 61 | /** 62 | * @return bool 63 | */ 64 | protected function canSort(): bool 65 | { 66 | if ($this->model->isErrorPage() === true) { 67 | return false; 68 | } 69 | 70 | if ($this->model->isListed() !== true) { 71 | return false; 72 | } 73 | 74 | if ($this->model->blueprint()->num() !== 'default') { 75 | return false; 76 | } 77 | 78 | return true; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /kirby/src/Cms/R.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier GmbH 14 | * @license https://getkirby.com/license 15 | */ 16 | class R extends Facade 17 | { 18 | /** 19 | * @return \Kirby\Http\Request 20 | */ 21 | public static function instance() 22 | { 23 | return App::instance()->request(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /kirby/src/Cms/Response.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier GmbH 13 | * @license https://getkirby.com/license 14 | */ 15 | class Response extends \Kirby\Http\Response 16 | { 17 | /** 18 | * Adjusted redirect creation which 19 | * parses locations with the Url::to method 20 | * first. 21 | * 22 | * @param string $location 23 | * @param int $code 24 | * @return static 25 | */ 26 | public static function redirect(string $location = '/', int $code = 302) 27 | { 28 | return parent::redirect(Url::to($location), $code); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /kirby/src/Cms/S.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier GmbH 14 | * @license https://getkirby.com/license 15 | */ 16 | class S extends Facade 17 | { 18 | /** 19 | * @return \Kirby\Session\Session 20 | */ 21 | public static function instance() 22 | { 23 | return App::instance()->session(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /kirby/src/Cms/Search.php: -------------------------------------------------------------------------------- 1 | 13 | * @link https://getkirby.com 14 | * @copyright Bastian Allgeier GmbH 15 | * @license https://getkirby.com/license 16 | */ 17 | class Search 18 | { 19 | /** 20 | * @param string|null $query 21 | * @param array $params 22 | * @return \Kirby\Cms\Files 23 | */ 24 | public static function files(string $query = null, $params = []) 25 | { 26 | return App::instance()->site()->index()->files()->search($query, $params); 27 | } 28 | 29 | /** 30 | * Native search method to search for anything within the collection 31 | * 32 | * @param \Kirby\Cms\Collection $collection 33 | * @param string|null $query 34 | * @param mixed $params 35 | * @return \Kirby\Cms\Collection|bool 36 | */ 37 | public static function collection(Collection $collection, string $query = null, $params = []) 38 | { 39 | $kirby = App::instance(); 40 | return ($kirby->component('search'))($kirby, $collection, $query, $params); 41 | } 42 | 43 | /** 44 | * @param string|null $query 45 | * @param array $params 46 | * @return \Kirby\Cms\Pages 47 | */ 48 | public static function pages(string $query = null, $params = []) 49 | { 50 | return App::instance()->site()->index()->search($query, $params); 51 | } 52 | 53 | /** 54 | * @param string|null $query 55 | * @param array $params 56 | * @return \Kirby\Cms\Users 57 | */ 58 | public static function users(string $query = null, $params = []) 59 | { 60 | return App::instance()->users()->search($query, $params); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /kirby/src/Cms/SiteBlueprint.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier GmbH 13 | * @license https://getkirby.com/license 14 | */ 15 | class SiteBlueprint extends Blueprint 16 | { 17 | /** 18 | * Creates a new page blueprint object 19 | * with the given props 20 | * 21 | * @param array $props 22 | */ 23 | public function __construct(array $props) 24 | { 25 | parent::__construct($props); 26 | 27 | // normalize all available page options 28 | $this->props['options'] = $this->normalizeOptions( 29 | $props['options'] ?? true, 30 | // defaults 31 | [ 32 | 'changeTitle' => null, 33 | 'update' => null, 34 | ], 35 | // aliases 36 | [ 37 | 'title' => 'changeTitle', 38 | ] 39 | ); 40 | } 41 | 42 | /** 43 | * Returns the preview settings 44 | * The preview setting controls the "Open" 45 | * button in the panel and redirects it to a 46 | * different URL if necessary. 47 | * 48 | * @return string|bool 49 | */ 50 | public function preview() 51 | { 52 | $preview = $this->props['options']['preview'] ?? true; 53 | 54 | if (is_string($preview) === true) { 55 | return $this->model->toString($preview); 56 | } 57 | 58 | return $preview; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /kirby/src/Cms/SitePermissions.php: -------------------------------------------------------------------------------- 1 | 10 | * @link https://getkirby.com 11 | * @copyright Bastian Allgeier GmbH 12 | * @license https://getkirby.com/license 13 | */ 14 | class SitePermissions extends ModelPermissions 15 | { 16 | protected $category = 'site'; 17 | } 18 | -------------------------------------------------------------------------------- /kirby/src/Cms/SiteRules.php: -------------------------------------------------------------------------------- 1 | 14 | * @link https://getkirby.com 15 | * @copyright Bastian Allgeier GmbH 16 | * @license https://getkirby.com/license 17 | */ 18 | class SiteRules 19 | { 20 | /** 21 | * Validates if the site title can be changed 22 | * 23 | * @param \Kirby\Cms\Site $site 24 | * @param string $title 25 | * @return bool 26 | * @throws \Kirby\Exception\InvalidArgumentException If the title is empty 27 | * @throws \Kirby\Exception\PermissionException If the user is not allowed to change the title 28 | */ 29 | public static function changeTitle(Site $site, string $title): bool 30 | { 31 | if ($site->permissions()->changeTitle() !== true) { 32 | throw new PermissionException(['key' => 'site.changeTitle.permission']); 33 | } 34 | 35 | if (Str::length($title) === 0) { 36 | throw new InvalidArgumentException(['key' => 'site.changeTitle.empty']); 37 | } 38 | 39 | return true; 40 | } 41 | 42 | /** 43 | * Validates if the site can be updated 44 | * 45 | * @param \Kirby\Cms\Site $site 46 | * @param array $content 47 | * @return bool 48 | * @throws \Kirby\Exception\PermissionException If the user is not allowed to update the site 49 | */ 50 | public static function update(Site $site, array $content = []): bool 51 | { 52 | if ($site->permissions()->update() !== true) { 53 | throw new PermissionException(['key' => 'site.update.permission']); 54 | } 55 | 56 | return true; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /kirby/src/Cms/UserBlueprint.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier GmbH 13 | * @license https://getkirby.com/license 14 | */ 15 | class UserBlueprint extends Blueprint 16 | { 17 | /** 18 | * UserBlueprint constructor. 19 | * 20 | * @param array $props 21 | * @throws \Kirby\Exception\InvalidArgumentException 22 | */ 23 | public function __construct(array $props) 24 | { 25 | // normalize and translate the description 26 | $props['description'] = $this->i18n($props['description'] ?? null); 27 | 28 | // register the other props 29 | parent::__construct($props); 30 | 31 | // normalize all available page options 32 | $this->props['options'] = $this->normalizeOptions( 33 | $props['options'] ?? true, 34 | // defaults 35 | [ 36 | 'create' => null, 37 | 'changeEmail' => null, 38 | 'changeLanguage' => null, 39 | 'changeName' => null, 40 | 'changePassword' => null, 41 | 'changeRole' => null, 42 | 'delete' => null, 43 | 'update' => null, 44 | ] 45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /kirby/src/Cms/UserPermissions.php: -------------------------------------------------------------------------------- 1 | 10 | * @link https://getkirby.com 11 | * @copyright Bastian Allgeier GmbH 12 | * @license https://getkirby.com/license 13 | */ 14 | class UserPermissions extends ModelPermissions 15 | { 16 | /** 17 | * @var string 18 | */ 19 | protected $category = 'users'; 20 | 21 | /** 22 | * UserPermissions constructor 23 | * 24 | * @param \Kirby\Cms\Model $model 25 | */ 26 | public function __construct(Model $model) 27 | { 28 | parent::__construct($model); 29 | 30 | // change the scope of the permissions, when the current user is this user 31 | $this->category = $this->user && $this->user->is($model) ? 'user' : 'users'; 32 | } 33 | 34 | /** 35 | * @return bool 36 | */ 37 | protected function canChangeRole(): bool 38 | { 39 | return $this->model->roles()->count() > 1; 40 | } 41 | 42 | /** 43 | * @return bool 44 | */ 45 | protected function canCreate(): bool 46 | { 47 | // the admin can always create new users 48 | if ($this->user->isAdmin() === true) { 49 | return true; 50 | } 51 | 52 | // users who are not admins cannot create admins 53 | if ($this->model->isAdmin() === true) { 54 | return false; 55 | } 56 | 57 | return true; 58 | } 59 | 60 | /** 61 | * @return bool 62 | */ 63 | protected function canDelete(): bool 64 | { 65 | return $this->model->isLastAdmin() !== true; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /kirby/src/Cms/Visitor.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier GmbH 14 | * @license https://getkirby.com/license 15 | */ 16 | class Visitor extends Facade 17 | { 18 | /** 19 | * @return \Kirby\Http\Visitor 20 | */ 21 | public static function instance() 22 | { 23 | return App::instance()->visitor(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /kirby/src/Data/Handler.php: -------------------------------------------------------------------------------- 1 | 15 | * @link https://getkirby.com 16 | * @copyright Bastian Allgeier GmbH 17 | * @license https://opensource.org/licenses/MIT 18 | */ 19 | abstract class Handler 20 | { 21 | /** 22 | * Parses an encoded string and returns a multi-dimensional array 23 | * 24 | * Needs to throw an Exception if the file can't be parsed. 25 | * 26 | * @param mixed $string 27 | * @return array 28 | */ 29 | abstract public static function decode($string): array; 30 | 31 | /** 32 | * Converts an array to an encoded string 33 | * 34 | * @param mixed $data 35 | * @return string 36 | */ 37 | abstract public static function encode($data): string; 38 | 39 | /** 40 | * Reads data from a file 41 | * 42 | * @param string $file 43 | * @return array 44 | */ 45 | public static function read(string $file): array 46 | { 47 | $contents = F::read($file); 48 | if ($contents === false) { 49 | throw new Exception('The file "' . $file . '" does not exist'); 50 | } 51 | 52 | return static::decode($contents); 53 | } 54 | 55 | /** 56 | * Writes data to a file 57 | * 58 | * @param string $file 59 | * @param mixed $data 60 | * @return bool 61 | */ 62 | public static function write(string $file = null, $data = []): bool 63 | { 64 | return F::write($file, static::encode($data)); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /kirby/src/Data/Json.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier GmbH 14 | * @license https://opensource.org/licenses/MIT 15 | */ 16 | class Json extends Handler 17 | { 18 | /** 19 | * Converts an array to an encoded JSON string 20 | * 21 | * @param mixed $data 22 | * @return string 23 | */ 24 | public static function encode($data): string 25 | { 26 | return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); 27 | } 28 | 29 | /** 30 | * Parses an encoded JSON string and returns a multi-dimensional array 31 | * 32 | * @param mixed $string 33 | * @return array 34 | */ 35 | public static function decode($string): array 36 | { 37 | if ($string === null) { 38 | return []; 39 | } 40 | 41 | if (is_array($string) === true) { 42 | return $string; 43 | } 44 | 45 | if (is_string($string) === false) { 46 | throw new InvalidArgumentException('Invalid JSON data; please pass a string'); 47 | } 48 | 49 | $result = json_decode($string, true); 50 | 51 | if (is_array($result) === true) { 52 | return $result; 53 | } else { 54 | throw new InvalidArgumentException('JSON string is invalid'); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /kirby/src/Data/Xml.php: -------------------------------------------------------------------------------- 1 | 13 | * @link https://getkirby.com 14 | * @copyright Bastian Allgeier GmbH 15 | * @license https://opensource.org/licenses/MIT 16 | */ 17 | class Xml extends Handler 18 | { 19 | /** 20 | * Converts an array to an encoded XML string 21 | * 22 | * @param mixed $data 23 | * @return string 24 | */ 25 | public static function encode($data): string 26 | { 27 | return XmlConverter::create($data, 'data'); 28 | } 29 | 30 | /** 31 | * Parses an encoded XML string and returns a multi-dimensional array 32 | * 33 | * @param mixed $string 34 | * @return array 35 | */ 36 | public static function decode($string): array 37 | { 38 | if ($string === null) { 39 | return []; 40 | } 41 | 42 | if (is_array($string) === true) { 43 | return $string; 44 | } 45 | 46 | if (is_string($string) === false) { 47 | throw new InvalidArgumentException('Invalid XML data; please pass a string'); 48 | } 49 | 50 | $result = XmlConverter::parse($string); 51 | 52 | if (is_array($result) === true) { 53 | // remove the root's name if it is the default to ensure that 54 | // the decoded data is the same as the input to the encode() method 55 | if ($result['@name'] === 'data') { 56 | unset($result['@name']); 57 | } 58 | 59 | return $result; 60 | } else { 61 | throw new InvalidArgumentException('XML string is invalid'); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /kirby/src/Database/Sql/Mysql.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier GmbH 14 | * @license https://opensource.org/licenses/MIT 15 | */ 16 | class Mysql extends Sql 17 | { 18 | /** 19 | * Returns a query to list the columns of a specified table; 20 | * the query needs to return rows with a column `name` 21 | * 22 | * @param string $table Table name 23 | * @return array 24 | */ 25 | public function columns(string $table): array 26 | { 27 | $databaseBinding = $this->bindingName('database'); 28 | $tableBinding = $this->bindingName('table'); 29 | 30 | $query = 'SELECT COLUMN_NAME AS name FROM INFORMATION_SCHEMA.COLUMNS '; 31 | $query .= 'WHERE TABLE_SCHEMA = ' . $databaseBinding . ' AND TABLE_NAME = ' . $tableBinding; 32 | 33 | return [ 34 | 'query' => $query, 35 | 'bindings' => [ 36 | $databaseBinding => $this->database->name(), 37 | $tableBinding => $table, 38 | ] 39 | ]; 40 | } 41 | 42 | /** 43 | * Returns a query to list the tables of the current database; 44 | * the query needs to return rows with a column `name` 45 | * 46 | * @return array 47 | */ 48 | public function tables(): array 49 | { 50 | $binding = $this->bindingName('database'); 51 | 52 | return [ 53 | 'query' => 'SELECT TABLE_NAME AS name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ' . $binding, 54 | 'bindings' => [ 55 | $binding => $this->database->name() 56 | ] 57 | ]; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /kirby/src/Email/Body.php: -------------------------------------------------------------------------------- 1 | , 13 | * Nico Hoffmann 14 | * @link https://getkirby.com 15 | * @copyright Bastian Allgeier GmbH 16 | * @license https://opensource.org/licenses/MIT 17 | */ 18 | class Body 19 | { 20 | use Properties; 21 | 22 | /** 23 | * @var string|null 24 | */ 25 | protected $html; 26 | 27 | /** 28 | * @var string|null 29 | */ 30 | protected $text; 31 | 32 | /** 33 | * Email body constructor 34 | * 35 | * @param array $props 36 | */ 37 | public function __construct(array $props = []) 38 | { 39 | $this->setProperties($props); 40 | } 41 | 42 | /** 43 | * Returns the HTML content of the email body 44 | * 45 | * @return string|null 46 | */ 47 | public function html() 48 | { 49 | return $this->html; 50 | } 51 | 52 | /** 53 | * Returns the plain text content of the email body 54 | * 55 | * @return string|null 56 | */ 57 | public function text() 58 | { 59 | return $this->text; 60 | } 61 | 62 | /** 63 | * Sets the HTML content for the email body 64 | * 65 | * @param string|null $html 66 | * @return $this 67 | */ 68 | protected function setHtml(string $html = null) 69 | { 70 | $this->html = $html; 71 | return $this; 72 | } 73 | 74 | /** 75 | * Sets the plain text content for the email body 76 | * 77 | * @param string|null $text 78 | * @return $this 79 | */ 80 | protected function setText(string $text = null) 81 | { 82 | $this->text = $text; 83 | return $this; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /kirby/src/Exception/BadMethodCallException.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier GmbH 13 | * @license https://opensource.org/licenses/MIT 14 | */ 15 | class BadMethodCallException extends Exception 16 | { 17 | protected static $defaultKey = 'invalidMethod'; 18 | protected static $defaultFallback = 'The method "{ method }" does not exist'; 19 | protected static $defaultHttpCode = 400; 20 | protected static $defaultData = ['method' => null]; 21 | } 22 | -------------------------------------------------------------------------------- /kirby/src/Exception/DuplicateException.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier GmbH 14 | * @license https://opensource.org/licenses/MIT 15 | */ 16 | class DuplicateException extends Exception 17 | { 18 | protected static $defaultKey = 'duplicate'; 19 | protected static $defaultFallback = 'The entry exists'; 20 | protected static $defaultHttpCode = 400; 21 | } 22 | -------------------------------------------------------------------------------- /kirby/src/Exception/ErrorPageException.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier GmbH 14 | * @license https://opensource.org/licenses/MIT 15 | */ 16 | class ErrorPageException extends Exception 17 | { 18 | protected static $defaultKey = 'errorPage'; 19 | protected static $defaultFallback = 'Triggered error page'; 20 | protected static $defaultHttpCode = 404; 21 | } 22 | -------------------------------------------------------------------------------- /kirby/src/Exception/InvalidArgumentException.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier GmbH 13 | * @license https://opensource.org/licenses/MIT 14 | */ 15 | class InvalidArgumentException extends Exception 16 | { 17 | protected static $defaultKey = 'invalidArgument'; 18 | protected static $defaultFallback = 'Invalid argument "{ argument }" in method "{ method }"'; 19 | protected static $defaultHttpCode = 400; 20 | protected static $defaultData = ['argument' => null, 'method' => null]; 21 | } 22 | -------------------------------------------------------------------------------- /kirby/src/Exception/LogicException.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier GmbH 13 | * @license https://opensource.org/licenses/MIT 14 | */ 15 | class LogicException extends Exception 16 | { 17 | protected static $defaultKey = 'logic'; 18 | protected static $defaultFallback = 'This task cannot be finished'; 19 | protected static $defaultHttpCode = 400; 20 | } 21 | -------------------------------------------------------------------------------- /kirby/src/Exception/NotFoundException.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier GmbH 13 | * @license https://opensource.org/licenses/MIT 14 | */ 15 | class NotFoundException extends Exception 16 | { 17 | protected static $defaultKey = 'notFound'; 18 | protected static $defaultFallback = 'Not found'; 19 | protected static $defaultHttpCode = 404; 20 | } 21 | -------------------------------------------------------------------------------- /kirby/src/Exception/PermissionException.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier GmbH 14 | * @license https://opensource.org/licenses/MIT 15 | */ 16 | class PermissionException extends Exception 17 | { 18 | protected static $defaultKey = 'permission'; 19 | protected static $defaultFallback = 'You are not allowed to do this'; 20 | protected static $defaultHttpCode = 403; 21 | } 22 | -------------------------------------------------------------------------------- /kirby/src/Form/Fields.php: -------------------------------------------------------------------------------- 1 | 13 | * @link https://getkirby.com 14 | * @copyright Bastian Allgeier GmbH 15 | * @license https://opensource.org/licenses/MIT 16 | */ 17 | class Fields extends Collection 18 | { 19 | /** 20 | * Internal setter for each object in the Collection. 21 | * This takes care of validation and of setting 22 | * the collection prop on each object correctly. 23 | * 24 | * @param string $name 25 | * @param object|array $field 26 | * @return $this 27 | */ 28 | public function __set(string $name, $field) 29 | { 30 | if (is_array($field) === true) { 31 | // use the array key as name if the name is not set 32 | $field['name'] = $field['name'] ?? $name; 33 | $field = Field::factory($field['type'], $field, $this); 34 | } 35 | 36 | return parent::__set($field->name(), $field); 37 | } 38 | 39 | /** 40 | * Converts the fields collection to an 41 | * array and also does that for every 42 | * included field. 43 | * 44 | * @param \Closure|null $map 45 | * @return array 46 | */ 47 | public function toArray(Closure $map = null): array 48 | { 49 | $array = []; 50 | 51 | foreach ($this as $field) { 52 | $array[$field->name()] = $field->toArray(); 53 | } 54 | 55 | return $array; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /kirby/src/Form/Mixin/EmptyState.php: -------------------------------------------------------------------------------- 1 | empty = $this->i18n($empty); 12 | } 13 | 14 | public function empty(): ?string 15 | { 16 | return $this->stringTemplate($this->empty); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /kirby/src/Form/Mixin/Max.php: -------------------------------------------------------------------------------- 1 | max; 12 | } 13 | 14 | protected function setMax(int $max = null) 15 | { 16 | $this->max = $max; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /kirby/src/Form/Mixin/Min.php: -------------------------------------------------------------------------------- 1 | min; 12 | } 13 | 14 | protected function setMin(int $min = null) 15 | { 16 | $this->min = $min; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /kirby/src/Http/Exceptions/NextRouteException.php: -------------------------------------------------------------------------------- 1 | 10 | * @link https://getkirby.com 11 | * @copyright Bastian Allgeier GmbH 12 | * @license https://opensource.org/licenses/MIT 13 | */ 14 | class NextRouteException extends \Exception 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /kirby/src/Http/Idn.php: -------------------------------------------------------------------------------- 1 | 13 | * @link https://getkirby.com 14 | * @copyright Bastian Allgeier GmbH 15 | * @license https://opensource.org/licenses/MIT 16 | */ 17 | class Idn 18 | { 19 | public static function decode(string $domain) 20 | { 21 | return (new Punycode())->decode($domain); 22 | } 23 | 24 | public static function encode(string $domain) 25 | { 26 | return (new Punycode())->encode($domain); 27 | } 28 | 29 | /** 30 | * Decodes a email address to the Unicode format 31 | * 32 | * @param string $email 33 | * @return string 34 | */ 35 | public static function decodeEmail(string $email): string 36 | { 37 | if (Str::contains($email, 'xn--') === true) { 38 | $parts = Str::split($email, '@'); 39 | $address = $parts[0]; 40 | $domain = Idn::decode($parts[1] ?? ''); 41 | $email = $address . '@' . $domain; 42 | } 43 | 44 | return $email; 45 | } 46 | 47 | /** 48 | * Encodes a email address to the Punycode format 49 | * 50 | * @param string $email 51 | * @return string 52 | */ 53 | public static function encodeEmail(string $email): string 54 | { 55 | if (mb_detect_encoding($email, 'ASCII', true) === false) { 56 | $parts = Str::split($email, '@'); 57 | $address = $parts[0]; 58 | $domain = Idn::encode($parts[1] ?? ''); 59 | $email = $address . '@' . $domain; 60 | } 61 | 62 | return $email; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /kirby/src/Http/Path.php: -------------------------------------------------------------------------------- 1 | 14 | * @link https://getkirby.com 15 | * @copyright Bastian Allgeier GmbH 16 | * @license https://opensource.org/licenses/MIT 17 | */ 18 | class Path extends Collection 19 | { 20 | public function __construct($items) 21 | { 22 | if (is_string($items) === true) { 23 | $items = Str::split($items, '/'); 24 | } 25 | 26 | parent::__construct($items ?? []); 27 | } 28 | 29 | public function __toString(): string 30 | { 31 | return $this->toString(); 32 | } 33 | 34 | public function toString(bool $leadingSlash = false, bool $trailingSlash = false): string 35 | { 36 | if (empty($this->data) === true) { 37 | return ''; 38 | } 39 | 40 | $path = implode('/', $this->data); 41 | 42 | $leadingSlash = $leadingSlash === true ? '/' : null; 43 | $trailingSlash = $trailingSlash === true ? '/' : null; 44 | 45 | return $leadingSlash . $path . $trailingSlash; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /kirby/src/Http/Query.php: -------------------------------------------------------------------------------- 1 | 14 | * @link https://getkirby.com 15 | * @copyright Bastian Allgeier GmbH 16 | * @license https://opensource.org/licenses/MIT 17 | */ 18 | class Query extends Obj 19 | { 20 | public function __construct($query) 21 | { 22 | if (is_string($query) === true) { 23 | parse_str(ltrim($query, '?'), $query); 24 | } 25 | 26 | parent::__construct($query ?? []); 27 | } 28 | 29 | public function isEmpty(): bool 30 | { 31 | return empty((array)$this) === true; 32 | } 33 | 34 | public function isNotEmpty(): bool 35 | { 36 | return empty((array)$this) === false; 37 | } 38 | 39 | public function __toString(): string 40 | { 41 | return $this->toString(); 42 | } 43 | 44 | public function toString($questionMark = false): string 45 | { 46 | $query = http_build_query($this); 47 | 48 | if (empty($query) === true) { 49 | return ''; 50 | } 51 | 52 | if ($questionMark === true) { 53 | $query = '?' . $query; 54 | } 55 | 56 | return $query; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /kirby/src/Http/Request/Auth/BasicAuth.php: -------------------------------------------------------------------------------- 1 | credentials = base64_decode($token); 35 | $this->username = Str::before($this->credentials, ':'); 36 | $this->password = Str::after($this->credentials, ':'); 37 | } 38 | 39 | /** 40 | * Returns the entire unencoded credentials string 41 | * 42 | * @return string 43 | */ 44 | public function credentials(): string 45 | { 46 | return $this->credentials; 47 | } 48 | 49 | /** 50 | * Returns the password 51 | * 52 | * @return string|null 53 | */ 54 | public function password(): ?string 55 | { 56 | return $this->password; 57 | } 58 | 59 | /** 60 | * Returns the authentication type 61 | * 62 | * @return string 63 | */ 64 | public function type(): string 65 | { 66 | return 'basic'; 67 | } 68 | 69 | /** 70 | * Returns the username 71 | * 72 | * @return string|null 73 | */ 74 | public function username(): ?string 75 | { 76 | return $this->username; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /kirby/src/Http/Request/Auth/BearerAuth.php: -------------------------------------------------------------------------------- 1 | token = $token; 23 | } 24 | 25 | /** 26 | * Converts the object to a string 27 | * 28 | * @return string 29 | */ 30 | public function __toString(): string 31 | { 32 | return ucfirst($this->type()) . ' ' . $this->token(); 33 | } 34 | 35 | /** 36 | * Returns the authentication token 37 | * 38 | * @return string 39 | */ 40 | public function token(): string 41 | { 42 | return $this->token; 43 | } 44 | 45 | /** 46 | * Returns the auth type 47 | * 48 | * @return string 49 | */ 50 | public function type(): string 51 | { 52 | return 'bearer'; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /kirby/src/Parsley/Schema.php: -------------------------------------------------------------------------------- 1 | 'text', 20 | 'content' => [ 21 | 'text' => $text 22 | ] 23 | ]; 24 | } 25 | 26 | public function marks(): array 27 | { 28 | return []; 29 | } 30 | 31 | public function nodes(): array 32 | { 33 | return []; 34 | } 35 | 36 | public function skip(): array 37 | { 38 | return ['meta', 'script', 'style']; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /kirby/src/Sane/Handler.php: -------------------------------------------------------------------------------- 1 | 16 | * @link https://getkirby.com 17 | * @copyright Bastian Allgeier GmbH 18 | * @license https://opensource.org/licenses/MIT 19 | */ 20 | abstract class Handler 21 | { 22 | /** 23 | * Validates file contents 24 | * 25 | * @param string $string 26 | * @return void 27 | * 28 | * @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation 29 | * @throws \Kirby\Exception\Exception On other errors 30 | */ 31 | abstract public static function validate(string $string): void; 32 | 33 | /** 34 | * Validates the contents of a file 35 | * 36 | * @param string $file 37 | * @return void 38 | * 39 | * @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation 40 | * @throws \Kirby\Exception\Exception On other errors 41 | */ 42 | public static function validateFile(string $file): void 43 | { 44 | $contents = F::read($file); 45 | if ($contents === false) { 46 | throw new Exception('The file "' . $file . '" does not exist'); 47 | } 48 | 49 | static::validate($contents); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /kirby/src/Sane/Svgz.php: -------------------------------------------------------------------------------- 1 | 13 | * @link https://getkirby.com 14 | * @copyright Bastian Allgeier GmbH 15 | * @license https://opensource.org/licenses/MIT 16 | */ 17 | class Svgz extends Svg 18 | { 19 | /** 20 | * Validates file contents 21 | * 22 | * @param string $string 23 | * @return void 24 | * 25 | * @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation 26 | */ 27 | public static function validate(string $string): void 28 | { 29 | // only support uncompressed files up to 10 MB to 30 | // prevent gzip bombs from crashing the process 31 | $uncompressed = @gzdecode($string, 10000000); 32 | 33 | if (is_string($uncompressed) !== true) { 34 | throw new InvalidArgumentException('Could not uncompress gzip data'); 35 | } 36 | 37 | parent::validate($uncompressed); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /kirby/src/Toolkit/Config.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier GmbH 13 | * @license https://opensource.org/licenses/MIT 14 | */ 15 | class Config extends Silo 16 | { 17 | /** 18 | * @var array 19 | */ 20 | public static $data = []; 21 | } 22 | -------------------------------------------------------------------------------- /kirby/src/Toolkit/Controller.php: -------------------------------------------------------------------------------- 1 | 15 | * @link https://getkirby.com 16 | * @copyright Bastian Allgeier GmbH 17 | * @license https://opensource.org/licenses/MIT 18 | */ 19 | class Controller 20 | { 21 | protected $function; 22 | 23 | public function __construct(Closure $function) 24 | { 25 | $this->function = $function; 26 | } 27 | 28 | public function arguments(array $data = []): array 29 | { 30 | $info = new ReflectionFunction($this->function); 31 | $args = []; 32 | 33 | foreach ($info->getParameters() as $parameter) { 34 | $name = $parameter->getName(); 35 | $args[] = $data[$name] ?? null; 36 | } 37 | 38 | return $args; 39 | } 40 | 41 | public function call($bind = null, $data = []) 42 | { 43 | $args = $this->arguments($data); 44 | 45 | if ($bind === null) { 46 | return call_user_func($this->function, ...$args); 47 | } 48 | 49 | return $this->function->call($bind, ...$args); 50 | } 51 | 52 | public static function load(string $file) 53 | { 54 | if (is_file($file) === false) { 55 | return null; 56 | } 57 | 58 | $function = F::load($file); 59 | 60 | if (is_a($function, 'Closure') === false) { 61 | return null; 62 | } 63 | 64 | return new static($function); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /kirby/src/Toolkit/Facade.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier GmbH 13 | * @license https://opensource.org/licenses/MIT 14 | */ 15 | abstract class Facade 16 | { 17 | /** 18 | * Returns the instance that should be 19 | * available statically 20 | * 21 | * @return mixed 22 | */ 23 | abstract public static function instance(); 24 | 25 | /** 26 | * Proxy for all public instance calls 27 | * 28 | * @param string $method 29 | * @param array $args 30 | * @return mixed 31 | */ 32 | public static function __callStatic(string $method, array $args = null) 33 | { 34 | return static::instance()->$method(...$args); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /kirby/src/Toolkit/Silo.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier GmbH 14 | * @license https://opensource.org/licenses/MIT 15 | */ 16 | class Silo 17 | { 18 | /** 19 | * @var array 20 | */ 21 | public static $data = []; 22 | 23 | /** 24 | * Setter for new data. 25 | * 26 | * @param string|array $key 27 | * @param mixed $value 28 | * @return array 29 | */ 30 | public static function set($key, $value = null): array 31 | { 32 | if (is_array($key) === true) { 33 | return static::$data = array_merge(static::$data, $key); 34 | } else { 35 | static::$data[$key] = $value; 36 | return static::$data; 37 | } 38 | } 39 | 40 | /** 41 | * @param string|array $key 42 | * @param mixed $default 43 | * @return mixed 44 | */ 45 | public static function get($key = null, $default = null) 46 | { 47 | if ($key === null) { 48 | return static::$data; 49 | } 50 | 51 | return A::get(static::$data, $key, $default); 52 | } 53 | 54 | /** 55 | * Removes an item from the data array 56 | * 57 | * @param string|null $key 58 | * @return array 59 | */ 60 | public static function remove(string $key = null): array 61 | { 62 | // reset the entire array 63 | if ($key === null) { 64 | return static::$data = []; 65 | } 66 | 67 | // unset a single key 68 | unset(static::$data[$key]); 69 | 70 | // return the array without the removed key 71 | return static::$data; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /kirby/src/Toolkit/Tpl.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier GmbH 14 | * @license https://opensource.org/licenses/MIT 15 | */ 16 | class Tpl 17 | { 18 | /** 19 | * Renders the template 20 | * 21 | * @param string $file 22 | * @param array $data 23 | * @return string 24 | */ 25 | public static function load(string $file = null, array $data = []): string 26 | { 27 | if (is_file($file) === false) { 28 | return ''; 29 | } 30 | 31 | ob_start(); 32 | 33 | $exception = null; 34 | try { 35 | F::load($file, null, $data); 36 | } catch (Throwable $e) { 37 | $exception = $e; 38 | } 39 | 40 | $content = ob_get_contents(); 41 | ob_end_clean(); 42 | 43 | if ($exception === null) { 44 | return $content; 45 | } 46 | 47 | throw $exception; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /kirby/views/fatal.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

4 | This page is currently offline due to an unexpected error. We are very sorry for the inconvenience and will fix it as soon as possible. 5 |

6 |

7 | Advice for developers and administrators:
8 | Enable debug mode to get further information about the error. 9 |

10 | 11 | 12 | -------------------------------------------------------------------------------- /kirby/views/php.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

4 | This page is currently offline. We are very sorry for the inconvenience and will fix it as soon as possible. 5 |

6 |

7 | Advice for developers and administrators:
8 | Change the PHP version to 7.3, 7.4 or 8.0 (PHP 7.4 is recommended) 9 |

10 | 11 | 12 | -------------------------------------------------------------------------------- /kirby/views/snippets/footer.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /kirby/views/snippets/header.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Error 8 | 9 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vuekit", 3 | "version": "1.1.7", 4 | "private": true, 5 | "scripts": { 6 | "build": "vue-cli-service build", 7 | "lint": "vue-cli-service lint", 8 | "dev": "vue-cli-service build --watch" 9 | }, 10 | "dependencies": { 11 | "@tailwindcss/postcss7-compat": "^2.2.7", 12 | "autoprefixer": "^9.8.6", 13 | "axios": "^0.21.1", 14 | "core-js": "^3.16.1", 15 | "postcss": "^7.0.36", 16 | "reset-css": "^4.0.1", 17 | "tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.7", 18 | "vue": "^2.6.14", 19 | "vue-axios": "^2.1.5", 20 | "vue-infinite-scroll": "^2.0.2", 21 | "vue-lazyload": "^1.3.3", 22 | "vue-meta": "^2.3.3", 23 | "vue-router": "^3.5.2", 24 | "vuex": "^3.1.2" 25 | }, 26 | "devDependencies": { 27 | "@vue/cli-plugin-babel": "~4.2.3", 28 | "@vue/cli-plugin-eslint": "~4.2.3", 29 | "@vue/cli-service": "~4.2.3", 30 | "babel-eslint": "^10.0.3", 31 | "eslint": "^6.7.2", 32 | "eslint-plugin-vue": "^6.1.2", 33 | "node-sass": "^4.13.1", 34 | "sass-loader": "^10.0.2", 35 | "vue-template-compiler": "^2.6.14" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/f-mahler/vuekit/1d23b74fc0f8a5b470dc3429cf371c464fcd3695/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | isHomePage()) { $title = $site->title(); } else { $title = 4 | $site->title() . ' – ' . $page->title(); } $description = 5 | $page->text()->or($site->seoDescription())->excerpt(160); $thumbnail = ($image = 6 | $page->images()->sortBy('sort')->first()) ? $image->resize(1280)->url() : 7 | (($siteImage = $site->seoImage()->toFile()) ? $siteImage->resize(1280)->url() : 8 | ''); ?> 9 | 10 | 11 | 12 | 13 | 17 | 18 | 19 | 20 | <?= $site->title() ?> 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 34 |
35 | 36 | 37 | -------------------------------------------------------------------------------- /robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: /content/*.txt$ 3 | Disallow: /kirby/ 4 | Disallow: /site/ 5 | Disallow: /panel/ 6 | Disallow: /*.md$ 7 | # Sitemap: sitemap.xml 8 | -------------------------------------------------------------------------------- /site/accounts/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/f-mahler/vuekit/1d23b74fc0f8a5b470dc3429cf371c464fcd3695/site/accounts/index.html -------------------------------------------------------------------------------- /site/blueprints/files/default.yml: -------------------------------------------------------------------------------- 1 | title: Default 2 | -------------------------------------------------------------------------------- /site/blueprints/files/image.yml: -------------------------------------------------------------------------------- 1 | title: Image 2 | 3 | accept: 4 | mime: image/jpeg, image/png 5 | 6 | fields: 7 | caption: 8 | label: Caption 9 | type: text 10 | -------------------------------------------------------------------------------- /site/blueprints/pages/default.yml: -------------------------------------------------------------------------------- 1 | title: Default Page 2 | 3 | fields: 4 | text: 5 | label: Text 6 | type: textarea 7 | buttons: 8 | - italic 9 | - link 10 | - email 11 | -------------------------------------------------------------------------------- /site/blueprints/pages/project.yml: -------------------------------------------------------------------------------- 1 | title: Project 2 | pages: false 3 | 4 | tabs: 5 | project: 6 | columns: 7 | - width: 2/3 8 | sections: 9 | gallery: 10 | headline: Gallery 11 | type: files 12 | layout: cards 13 | template: image 14 | size: tiny 15 | image: 16 | cover: true 17 | - width: 1/3 18 | sections: 19 | info: 20 | type: fields 21 | fields: 22 | year: 23 | label: Year 24 | type: number 25 | placeholder: 2019 26 | category: 27 | label: Category 28 | type: select 29 | options: 30 | painting: Painting 31 | drawing: Drawing 32 | curatorial: Curatorial 33 | editorial: Editorial 34 | description: 35 | label: Description 36 | type: textarea 37 | media: tabs/media 38 | meta: tabs/meta 39 | -------------------------------------------------------------------------------- /site/blueprints/pages/projects.yml: -------------------------------------------------------------------------------- 1 | title: Projects 2 | 3 | options: 4 | url: false 5 | delete: false 6 | changeTemplate: false 7 | 8 | columns: 9 | left: 10 | width: 2/3 11 | sections: 12 | published: 13 | headline: Published 14 | type: pages 15 | status: published 16 | layout: list 17 | size: tiny 18 | image: false 19 | right: 20 | width: 1/3 21 | sections: 22 | drafts: 23 | headline: Drafts 24 | type: pages 25 | status: drafts 26 | template: project 27 | layout: list 28 | size: tiny 29 | image: false 30 | -------------------------------------------------------------------------------- /site/blueprints/site.yml: -------------------------------------------------------------------------------- 1 | title: Site 2 | 3 | tabs: 4 | pages: 5 | label: Pages 6 | icon: layers 7 | columns: 8 | - width: 1/3 9 | sections: 10 | pages: 11 | headline: Main Pages 12 | type: pages 13 | layout: list 14 | size: tiny 15 | status: listed 16 | image: false 17 | - width: 1/3 18 | sections: 19 | unlisted: 20 | headline: Hidden 21 | type: pages 22 | layout: list 23 | size: tiny 24 | status: unlisted 25 | image: false 26 | seo: 27 | label: SEO 28 | icon: search 29 | fields: 30 | seoDescription: 31 | label: SEO Description 32 | help: This text will appear on search engines 33 | type: textarea 34 | maxlength: 160 35 | buttons: false 36 | width: 1/2 37 | seoImage: 38 | type: files 39 | size: large 40 | layout: cards 41 | label: SEO Image 42 | template: image 43 | help: This image will appear in links on social media 44 | max: 1 45 | width: 1/2 46 | -------------------------------------------------------------------------------- /site/blueprints/tabs/media.yml: -------------------------------------------------------------------------------- 1 | label: Media 2 | sections: 3 | media: 4 | headline: Media 5 | type: files 6 | layout: cards 7 | info: "{{ file.niceSize }} / {{ file.dimensions }}" 8 | size: small 9 | image: 10 | back: black 11 | -------------------------------------------------------------------------------- /site/blueprints/tabs/meta.yml: -------------------------------------------------------------------------------- 1 | label: 2 | en: Meta 3 | columns: 4 | - width: 2/3 5 | sections: 6 | meta: 7 | type: fields 8 | fields: 9 | meta_title: 10 | label: Title 11 | type: text 12 | meta_desc: 13 | label: Description 14 | type: textarea 15 | size: small 16 | buttons: false 17 | - width: 1/3 18 | fields: 19 | shareimg: 20 | label: Share image 21 | type: files 22 | max: 1 23 | layout: cards 24 | info: "{{ file.dimensions }}" 25 | sortable: false 26 | template: share 27 | size: large 28 | help: "Select or upload image" 29 | image: 30 | back: black 31 | ratio: 3/2 32 | - width: 1/1 33 | sections: 34 | head: 35 | type: info 36 | headline: Help 37 | text: | 38 | Edit these fields to overwrite the default title, descriptions or share image. 39 | Preview here → [__opengraphy.xyz__](https://www.opengraph.xyz/) 40 | -------------------------------------------------------------------------------- /site/blueprints/users/admin.yml: -------------------------------------------------------------------------------- 1 | title: Admin 2 | description: Access to everything 3 | extends: users/default 4 | -------------------------------------------------------------------------------- /site/blueprints/users/api.yml: -------------------------------------------------------------------------------- 1 | title: API 2 | description: API Access 3 | extends: users/default 4 | 5 | permissions: 6 | access: 7 | panel: true 8 | users: false 9 | site: false 10 | site: 11 | update: false 12 | pages: 13 | create: false 14 | changeTemplate: false 15 | changeTitle: false 16 | changeURL: false 17 | hide: false 18 | sort: false 19 | update: false 20 | delete: false 21 | users: 22 | create: false 23 | createAvatar: false 24 | deleteAvatar: false 25 | changeName: false 26 | changeEmail: false 27 | changePassword: false 28 | changeRole: false 29 | delete: false 30 | update: false 31 | files: 32 | create: false 33 | changeName: false 34 | delete: false 35 | replace: false 36 | update: false 37 | -------------------------------------------------------------------------------- /site/blueprints/users/default.yml: -------------------------------------------------------------------------------- 1 | title: User 2 | 3 | fields: 4 | info: 5 | label: Info 6 | type: info 7 | text: | 8 | Use the settings to modify name, email or password. 9 | -------------------------------------------------------------------------------- /site/blueprints/users/editor.yml: -------------------------------------------------------------------------------- 1 | title: Editor 2 | extends: users/default 3 | description: Access to panel, site 4 | 5 | permissions: 6 | access: 7 | panel: true 8 | users: false 9 | site: true 10 | settings: false 11 | user: 12 | delete: false 13 | create: false 14 | changeRole: false 15 | -------------------------------------------------------------------------------- /site/config/config.php: -------------------------------------------------------------------------------- 1 | true, 5 | 'api' => [ 6 | 'basicAuth' => true, 7 | ] 8 | ]; 9 | -------------------------------------------------------------------------------- /site/plugins/kql/.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.php] 13 | indent_size = 4 14 | 15 | [*.md,*.txt] 16 | trim_trailing_whitespace = false 17 | insert_final_newline = false 18 | 19 | [composer.json] 20 | indent_size = 4 21 | -------------------------------------------------------------------------------- /site/plugins/kql/.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: ['https://getkirby.com/buy'] 2 | -------------------------------------------------------------------------------- /site/plugins/kql/.gitignore: -------------------------------------------------------------------------------- 1 | # OS files 2 | .DS_Store 3 | 4 | # npm modules 5 | /node_modules 6 | 7 | # files of Composer dependencies that are not needed for the plugin 8 | /vendor/**/.* 9 | /vendor/**/*.json 10 | /vendor/**/*.txt 11 | /vendor/**/*.md 12 | /vendor/**/*.yml 13 | /vendor/**/*.yaml 14 | /vendor/**/*.xml 15 | /vendor/**/*.dist 16 | /vendor/**/readme.php 17 | /vendor/**/LICENSE 18 | /vendor/**/COPYING 19 | /vendor/**/VERSION 20 | /vendor/**/docs/* 21 | /vendor/**/example/* 22 | /vendor/**/examples/* 23 | /vendor/**/test/* 24 | /vendor/**/tests/* 25 | /vendor/**/php4/* 26 | /vendor/getkirby/composer-installer 27 | /.php_cs.cache 28 | /.phpunit.result.cache 29 | -------------------------------------------------------------------------------- /site/plugins/kql/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /site/plugins/kql/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "getkirby/kql", 3 | "description": "Kirby Query Language", 4 | "license": "MIT", 5 | "keywords": ["kirby", "cms", "api", "json", "query"], 6 | "homepage": "https://getkirby.com", 7 | "type": "kirby-plugin", 8 | "authors": [ 9 | { 10 | "name": "Bastian Allgeier", 11 | "email": "bastian@getkirby.com" 12 | } 13 | ], 14 | "require": { 15 | "getkirby/composer-installer": "^1.2.0" 16 | }, 17 | "config": { 18 | "optimize-autoloader": true 19 | }, 20 | "autoload": { 21 | "psr-4": { 22 | "Kirby\\": "src/" 23 | } 24 | }, 25 | "scripts": { 26 | "fix": "php-cs-fixer fix --config .php_cs" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /site/plugins/kql/index.php: -------------------------------------------------------------------------------- 1 | [ 14 | 'routes' => [ 15 | [ 16 | 'pattern' => 'query', 17 | 'method' => 'POST|GET', 18 | 'action' => function () { 19 | $result = Kql::run([ 20 | 'query' => get('query'), 21 | 'select' => get('select'), 22 | 'pagination' => [ 23 | 'page' => get('page', 1), 24 | 'limit' => get('limit', 100) 25 | ] 26 | ]); 27 | 28 | return [ 29 | 'code' => 200, 30 | 'result' => $result, 31 | 'status' => 'ok', 32 | ]; 33 | } 34 | ] 35 | ] 36 | ] 37 | ]); 38 | -------------------------------------------------------------------------------- /site/plugins/kql/phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | ./src 16 | 17 | 18 | 19 | 20 | 21 | ./tests/ 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /site/plugins/kql/src/Kql/Interceptor.php: -------------------------------------------------------------------------------- 1 | allowedMethodsForSiblings(), 21 | [ 22 | 'content', 23 | 'id', 24 | 'isEmpty', 25 | 'isHidden', 26 | 'isNotEmpty', 27 | 'toField', 28 | 'toHtml', 29 | 'parent', 30 | 'type' 31 | ] 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /site/plugins/kql/src/Kql/Interceptors/Cms/Blocks.php: -------------------------------------------------------------------------------- 1 | object->toArray(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /site/plugins/kql/src/Kql/Interceptors/Cms/Blueprint.php: -------------------------------------------------------------------------------- 1 | object->fields(); 42 | } 43 | 44 | public function sections(): array 45 | { 46 | return array_keys($this->object->sections()); 47 | } 48 | 49 | public function tab(string $name): ?array 50 | { 51 | if ($tab = $this->object->tab($name)) { 52 | foreach ($tab['columns'] as $columnIndex => $column) { 53 | $tab['columns'][$columnIndex]['sections'] = array_keys($column['sections']); 54 | } 55 | 56 | return $tab; 57 | } 58 | 59 | return null; 60 | } 61 | 62 | public function tabs(): array 63 | { 64 | $tabs = []; 65 | 66 | foreach ($this->object->tabs() as $tab) { 67 | $tabs[$tab['name']] = $this->tab($tab['name']); 68 | } 69 | 70 | return $tabs; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /site/plugins/kql/src/Kql/Interceptors/Cms/Collection.php: -------------------------------------------------------------------------------- 1 | object->keys(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /site/plugins/kql/src/Kql/Interceptors/Cms/Content.php: -------------------------------------------------------------------------------- 1 | isAllowedMethod($method) === true) { 14 | return $this->object->$method(...$args); 15 | } 16 | 17 | if (method_exists($this->object, $method) === false) { 18 | return $this->object->get($method); 19 | } 20 | 21 | $this->forbiddenMethod($method); 22 | } 23 | 24 | public function allowedMethods(): array 25 | { 26 | return [ 27 | 'data', 28 | 'fields', 29 | 'has', 30 | 'get', 31 | 'keys', 32 | 'not', 33 | ]; 34 | } 35 | 36 | public function toArray(): array 37 | { 38 | return $this->object->toArray(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /site/plugins/kql/src/Kql/Interceptors/Cms/Field.php: -------------------------------------------------------------------------------- 1 | isAllowedMethod($method) === true) { 14 | return $this->object->$method(...$args); 15 | } 16 | 17 | $methods = array_keys($this->object::$methods); 18 | $method = strtolower($method); 19 | 20 | if (in_array($method, $methods) === true) { 21 | return $this->object->$method(...$args); 22 | } 23 | 24 | $this->forbiddenMethod($method); 25 | } 26 | 27 | public function allowedMethods(): array 28 | { 29 | return [ 30 | 'exists', 31 | 'isEmpty', 32 | 'isNotEmpty', 33 | 'key', 34 | 'or', 35 | 'value' 36 | ]; 37 | } 38 | 39 | public function toResponse() 40 | { 41 | return $this->object->toString(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /site/plugins/kql/src/Kql/Interceptors/Cms/File.php: -------------------------------------------------------------------------------- 1 | allowedMethodsForModels(), 26 | $this->allowedMethodsForParents(), 27 | $this->allowedMethodsForSiblings(), 28 | [ 29 | 'blur', 30 | 'bw', 31 | 'crop', 32 | 'dataUri', 33 | 'dimensions', 34 | 'exif', 35 | 'extension', 36 | 'filename', 37 | 'files', 38 | 'grayscale', 39 | 'greyscale', 40 | 'height', 41 | 'html', 42 | 'isPortrait', 43 | 'isLandscape', 44 | 'isSquare', 45 | 'mime', 46 | 'name', 47 | 'niceSize', 48 | 'orientation', 49 | 'ratio', 50 | 'resize', 51 | 'size', 52 | 'srcset', 53 | 'template', 54 | 'templateSiblings', 55 | 'thumb', 56 | 'type', 57 | 'width' 58 | ] 59 | ); 60 | } 61 | 62 | public function dimensions(): array 63 | { 64 | return $this->object->dimensions()->toArray(); 65 | } 66 | 67 | public function exif(): array 68 | { 69 | return $this->object->exif()->toArray(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /site/plugins/kql/src/Kql/Interceptors/Cms/FileVersion.php: -------------------------------------------------------------------------------- 1 | allowedMethodsForSiblings(), 20 | [ 21 | 'attrs', 22 | 'columns', 23 | 'id', 24 | 'isEmpty', 25 | 'isNotEmpty', 26 | 'parent' 27 | ] 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /site/plugins/kql/src/Kql/Interceptors/Cms/LayoutColumn.php: -------------------------------------------------------------------------------- 1 | allowedMethodsForSiblings(), 20 | [ 21 | 'blocks', 22 | 'id', 23 | 'isEmpty', 24 | 'isNotEmpty', 25 | 'span', 26 | 'width' 27 | ] 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /site/plugins/kql/src/Kql/Interceptors/Cms/LayoutColumns.php: -------------------------------------------------------------------------------- 1 | object->toArray(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /site/plugins/kql/src/Kql/Interceptors/Cms/Layouts.php: -------------------------------------------------------------------------------- 1 | object->toArray(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /site/plugins/kql/src/Kql/Interceptors/Cms/Page.php: -------------------------------------------------------------------------------- 1 | allowedMethodsForChildren(), 31 | $this->allowedMethodsForFiles(), 32 | $this->allowedMethodsForModels(), 33 | $this->allowedMethodsForParents(), 34 | $this->allowedMethodsForSiblings(), 35 | [ 36 | 'blueprints', 37 | 'depth', 38 | 'hasTemplate', 39 | 'intendedTemplate', 40 | 'isDraft', 41 | 'isErrorPage', 42 | 'isHomePage', 43 | 'isHomeOrErrorPage', 44 | 'isListed', 45 | 'isReadable', 46 | 'isSortable', 47 | 'isUnlisted', 48 | 'num', 49 | 'slug', 50 | 'status', 51 | 'template', 52 | 'title', 53 | 'uid', 54 | 'uri', 55 | ] 56 | ); 57 | } 58 | 59 | public function intendedTemplate(): string 60 | { 61 | return $this->object->intendedTemplate()->name(); 62 | } 63 | 64 | public function template(): string 65 | { 66 | return $this->object->template()->name(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /site/plugins/kql/src/Kql/Interceptors/Cms/Pages.php: -------------------------------------------------------------------------------- 1 | object->permissions()->toArray(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /site/plugins/kql/src/Kql/Interceptors/Cms/Site.php: -------------------------------------------------------------------------------- 1 | allowedMethodsForChildren(), 21 | $this->allowedMethodsForFiles(), 22 | $this->allowedMethodsForModels(), 23 | [ 24 | 'blueprints', 25 | 'breadcrumb', 26 | 'errorPage', 27 | 'errorPageId', 28 | 'homePage', 29 | 'homePageId', 30 | 'page', 31 | 'pages', 32 | 'title', 33 | ] 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /site/plugins/kql/src/Kql/Interceptors/Cms/Structure.php: -------------------------------------------------------------------------------- 1 | object->toArray(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /site/plugins/kql/src/Kql/Interceptors/Cms/StructureObject.php: -------------------------------------------------------------------------------- 1 | allowedMethodsForSiblings(), 13 | [ 14 | 'content', 15 | 'id', 16 | 'parent', 17 | ] 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /site/plugins/kql/src/Kql/Interceptors/Cms/Translation.php: -------------------------------------------------------------------------------- 1 | allowedMethodsForFiles(), 20 | $this->allowedMethodsForModels(), 21 | $this->allowedMethodsForSiblings(), 22 | [ 23 | 'avatar', 24 | 'email', 25 | 'id', 26 | 'isAdmin', 27 | 'language', 28 | 'modified', 29 | 'name', 30 | 'role', 31 | 'username', 32 | ] 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /site/plugins/kql/src/Kql/Interceptors/Cms/Users.php: -------------------------------------------------------------------------------- 1 | object = $object; 19 | } 20 | 21 | public function __call($method, array $args = []) 22 | { 23 | if ($this->isAllowedMethod($method) === true) { 24 | return $this->object->$method(...$args); 25 | } 26 | 27 | $this->forbiddenMethod($method); 28 | } 29 | 30 | public function allowedMethods(): array 31 | { 32 | return []; 33 | } 34 | 35 | protected function forbiddenMethod(string $method) 36 | { 37 | $className = get_class($this->object); 38 | throw new PermissionException('The method "' . $className . '::' . $method . '()" is not allowed in the API context'); 39 | } 40 | 41 | protected function isAllowedMethod($method) 42 | { 43 | return in_array($method, $this->allowedMethods()) === true; 44 | } 45 | 46 | public function __debugInfo(): array 47 | { 48 | return [ 49 | 'type' => $this::CLASS_ALIAS, 50 | 'methods' => Help::forMethods($this->object, $this->allowedMethods()), 51 | 'value' => $this->toArray() 52 | ]; 53 | } 54 | 55 | public function toArray(): ?array 56 | { 57 | return Kql::select($this, $this->toArray); 58 | } 59 | 60 | public function toResponse() 61 | { 62 | return $this->toArray(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /site/plugins/kql/src/Kql/Interceptors/Toolkit/Obj.php: -------------------------------------------------------------------------------- 1 | object->toArray(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /site/plugins/kql/tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 35 | -------------------------------------------------------------------------------- /src/assets/fonts/IBMPlexSans-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/f-mahler/vuekit/1d23b74fc0f8a5b470dc3429cf371c464fcd3695/src/assets/fonts/IBMPlexSans-Regular.woff2 -------------------------------------------------------------------------------- /src/assets/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @font-face { 6 | font-family: "IBMPlexSans-Regular"; 7 | src: local("IBMPlexSans-Regular"), 8 | url(./fonts/IBMPlexSans-Regular.woff2) format("woff2"); 9 | } 10 | 11 | @layer base { 12 | } 13 | @layer utilities { 14 | } 15 | -------------------------------------------------------------------------------- /src/components/Navigation.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 19 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import App from "./App.vue"; 3 | import router from "./router"; 4 | import store from "./store"; 5 | import VueMeta from "vue-meta"; 6 | import VueLazyload from "vue-lazyload"; 7 | import infiniteScroll from "vue-infinite-scroll"; 8 | import "./assets/tailwind.css"; 9 | 10 | Vue.use(VueMeta, { 11 | refreshOnceOnNavigation: true, 12 | }); 13 | Vue.use(VueLazyload); 14 | Vue.use(infiniteScroll); 15 | Vue.config.productionTip = false; 16 | 17 | new Vue({ 18 | router, 19 | store, 20 | render: (h) => h(App), 21 | }).$mount("#app"); 22 | -------------------------------------------------------------------------------- /src/router.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import Router from "vue-router"; 3 | import store from "./store.js"; 4 | 5 | Vue.use(Router); 6 | 7 | export default new Router({ 8 | mode: "history", 9 | // scrollBehavior() { 10 | // return { x: 0, y: 0 }; 11 | // }, 12 | routes: [ 13 | { 14 | path: "/", 15 | name: "home", 16 | component: () => import(/* webpackChunkName: "Home" */ "./views/Home.vue") 17 | }, 18 | { 19 | path: "/about", 20 | name: "about", 21 | component: () => 22 | import(/* webpackChunkName: "About" */ "./views/About.vue"), 23 | beforeEnter: (to, from, next) => { 24 | if (store.state.about.length === 0) { 25 | store.dispatch("loadAbout").then(next); 26 | } else { 27 | next(); 28 | } 29 | } 30 | }, 31 | { 32 | path: "/projects", 33 | name: "projects", 34 | component: () => 35 | import(/* webpackChunkName: "Projects" */ "./views/Projects.vue"), 36 | beforeEnter: (to, from, next) => { 37 | if (store.state.projects.length === 0) { 38 | store.dispatch("loadProjects", 0).then(next); 39 | } else { 40 | next(); 41 | } 42 | } 43 | }, 44 | { 45 | path: "/projects/:id", 46 | name: "project", 47 | props: true, 48 | component: () => 49 | import(/* webpackChunkName: "Project" */ "./views/Project.vue"), 50 | beforeEnter: (to, from, next) => { 51 | store.dispatch("loadProject", to.params.id).then(next); 52 | } 53 | }, 54 | { 55 | path: "*", 56 | redirect: "/" 57 | } 58 | ] 59 | }); 60 | -------------------------------------------------------------------------------- /src/views/About.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 27 | -------------------------------------------------------------------------------- /src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 31 | -------------------------------------------------------------------------------- /src/views/Project.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 36 | -------------------------------------------------------------------------------- /src/views/Projects.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 54 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | purge: ["./public/**/*.html", "./src/**/*.vue", "./dist/**/*.js"], 3 | darkMode: false, // or 'media' or 'class' 4 | theme: { 5 | fontFamily: { 6 | sans: ["IBMPlexSans-Regular"], 7 | }, 8 | extend: {}, 9 | }, 10 | variants: {}, 11 | plugins: [], 12 | }; 13 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable indent */ 2 | module.exports = { 3 | publicPath: '/dist/' 4 | } 5 | --------------------------------------------------------------------------------