├── sample ├── site │ ├── cache │ │ └── index.html │ ├── accounts │ │ └── index.html │ ├── plugins │ │ └── index.html │ ├── blueprints │ │ ├── default.php │ │ ├── home.php │ │ ├── error.php │ │ ├── projects.php │ │ ├── project.php │ │ └── site.php │ ├── templates │ │ ├── default.php │ │ ├── projects.php │ │ ├── home.php │ │ └── project.php │ ├── snippets │ │ ├── footer.php │ │ ├── menu.php │ │ ├── projects.php │ │ └── header.php │ └── config │ │ └── config.php ├── .DS_Store ├── content │ ├── error │ │ └── error.txt │ ├── 1-about │ │ ├── about.jpg │ │ └── about.txt │ ├── 2-projects │ │ ├── 1-project-a │ │ │ ├── green.jpg │ │ │ ├── forrest.jpg │ │ │ ├── the-sea.jpg │ │ │ └── project.txt │ │ ├── 2-project-b │ │ │ ├── road.jpg │ │ │ ├── mountains.jpg │ │ │ └── project.txt │ │ ├── 3-project-c │ │ │ ├── hightide.jpg │ │ │ ├── kermit-the-fog.jpg │ │ │ └── project.txt │ │ └── projects.txt │ ├── site.txt │ ├── 3-contact │ │ └── contact.txt │ └── home │ │ └── home.txt ├── panel │ ├── app │ │ ├── views │ │ │ ├── files │ │ │ │ └── delete.php │ │ │ ├── pages │ │ │ │ ├── delete.php │ │ │ │ ├── toggle.php │ │ │ │ ├── add.php │ │ │ │ ├── url.php │ │ │ │ └── edit.php │ │ │ ├── users │ │ │ │ ├── delete.php │ │ │ │ └── index.php │ │ │ ├── avatars │ │ │ │ └── delete.php │ │ │ ├── error │ │ │ │ ├── index.php │ │ │ │ └── modal.php │ │ │ ├── auth │ │ │ │ ├── login.php │ │ │ │ └── block.php │ │ │ ├── installation │ │ │ │ └── index.php │ │ │ ├── search │ │ │ │ └── results.php │ │ │ ├── dashboard │ │ │ │ └── index.php │ │ │ └── options │ │ │ │ └── index.php │ │ ├── translations │ │ │ ├── ca │ │ │ │ └── package.json │ │ │ ├── cs │ │ │ │ └── package.json │ │ │ ├── da │ │ │ │ └── package.json │ │ │ ├── de │ │ │ │ └── package.json │ │ │ ├── en │ │ │ │ └── package.json │ │ │ ├── fa │ │ │ │ └── package.json │ │ │ ├── fi │ │ │ │ └── package.json │ │ │ ├── fr │ │ │ │ └── package.json │ │ │ ├── it │ │ │ │ └── package.json │ │ │ ├── ja │ │ │ │ └── package.json │ │ │ ├── pl │ │ │ │ └── package.json │ │ │ ├── ro │ │ │ │ └── package.json │ │ │ ├── tr │ │ │ │ └── package.json │ │ │ ├── bg │ │ │ │ └── package.json │ │ │ ├── hu │ │ │ │ └── package.json │ │ │ ├── nb │ │ │ │ └── package.json │ │ │ ├── nl │ │ │ │ └── package.json │ │ │ ├── sv_SE │ │ │ │ └── package.json │ │ │ ├── id │ │ │ │ └── package.json │ │ │ ├── zh_CN │ │ │ │ └── package.json │ │ │ ├── zh_TW │ │ │ │ └── package.json │ │ │ ├── es_ES │ │ │ │ └── package.json │ │ │ ├── pt_PT │ │ │ │ └── package.json │ │ │ ├── ru │ │ │ │ └── package.json │ │ │ ├── es_419 │ │ │ │ └── package.json │ │ │ ├── pt_BR │ │ │ │ └── package.json │ │ │ └── ar │ │ │ │ └── package.json │ │ ├── fields │ │ │ ├── structure │ │ │ │ ├── views │ │ │ │ │ ├── delete.php │ │ │ │ │ ├── add.php │ │ │ │ │ └── update.php │ │ │ │ ├── forms │ │ │ │ │ ├── add.php │ │ │ │ │ ├── update.php │ │ │ │ │ └── delete.php │ │ │ │ ├── template.php │ │ │ │ ├── styles │ │ │ │ │ ├── items.php │ │ │ │ │ └── table.php │ │ │ │ └── assets │ │ │ │ │ ├── js │ │ │ │ │ └── structure.js │ │ │ │ │ └── css │ │ │ │ │ └── structure.css │ │ │ ├── tel │ │ │ │ └── tel.php │ │ │ ├── text │ │ │ │ ├── assets │ │ │ │ │ ├── css │ │ │ │ │ │ └── counter.css │ │ │ │ │ └── js │ │ │ │ │ │ └── counter.js │ │ │ │ └── text.php │ │ │ ├── hidden │ │ │ │ └── hidden.php │ │ │ ├── line │ │ │ │ └── line.php │ │ │ ├── filename │ │ │ │ └── filename.php │ │ │ ├── url │ │ │ │ └── url.php │ │ │ ├── info │ │ │ │ └── info.php │ │ │ ├── headline │ │ │ │ ├── assets │ │ │ │ │ └── css │ │ │ │ │ │ └── headline.css │ │ │ │ └── headline.php │ │ │ ├── textarea │ │ │ │ ├── controller.php │ │ │ │ ├── forms │ │ │ │ │ ├── email.php │ │ │ │ │ └── link.php │ │ │ │ ├── views │ │ │ │ │ ├── email.php │ │ │ │ │ └── link.php │ │ │ │ ├── assets │ │ │ │ │ └── js │ │ │ │ │ │ └── editor.js │ │ │ │ └── textarea.php │ │ │ ├── page │ │ │ │ └── page.php │ │ │ ├── user │ │ │ │ └── user.php │ │ │ ├── title │ │ │ │ └── title.php │ │ │ ├── toggle │ │ │ │ └── toggle.php │ │ │ ├── email │ │ │ │ └── email.php │ │ │ ├── password │ │ │ │ └── password.php │ │ │ ├── radio │ │ │ │ └── radio.php │ │ │ ├── input │ │ │ │ └── input.php │ │ │ ├── number │ │ │ │ └── number.php │ │ │ ├── checkboxes │ │ │ │ └── checkboxes.php │ │ │ ├── date │ │ │ │ ├── assets │ │ │ │ │ └── js │ │ │ │ │ │ └── date.js │ │ │ │ └── date.php │ │ │ ├── checkbox │ │ │ │ └── checkbox.php │ │ │ ├── tags │ │ │ │ └── tags.php │ │ │ ├── time │ │ │ │ └── time.php │ │ │ ├── select │ │ │ │ └── select.php │ │ │ └── inputlist │ │ │ │ └── inputlist.php │ │ ├── topbars │ │ │ ├── error.php │ │ │ └── user.php │ │ ├── snippets │ │ │ ├── meta.php │ │ │ ├── search.php │ │ │ ├── pages │ │ │ │ ├── sidebar │ │ │ │ │ ├── file.php │ │ │ │ │ ├── subpage.php │ │ │ │ │ ├── files.php │ │ │ │ │ └── subpages.php │ │ │ │ └── sidebar.php │ │ │ ├── uploader.php │ │ │ ├── languages.php │ │ │ ├── breadcrumb.php │ │ │ ├── menu.php │ │ │ ├── pagination.php │ │ │ └── subpages │ │ │ │ └── subpage.php │ │ ├── widgets │ │ │ ├── pages │ │ │ │ ├── pages.html.php │ │ │ │ └── pages.php │ │ │ ├── site │ │ │ │ ├── site.php │ │ │ │ └── site.html.php │ │ │ ├── history │ │ │ │ ├── history.php │ │ │ │ └── history.html.php │ │ │ ├── license │ │ │ │ ├── license.html.php │ │ │ │ └── license.php │ │ │ └── account │ │ │ │ ├── account.html.php │ │ │ │ └── account.php │ │ ├── controllers │ │ │ ├── dashboard.php │ │ │ ├── search.php │ │ │ ├── assets.php │ │ │ ├── autocomplete.php │ │ │ ├── error.php │ │ │ ├── options.php │ │ │ ├── avatars.php │ │ │ ├── auth.php │ │ │ └── installation.php │ │ ├── src │ │ │ └── panel │ │ │ │ ├── layout.php │ │ │ │ ├── snippet.php │ │ │ │ ├── models │ │ │ │ ├── page │ │ │ │ │ ├── addbutton.php │ │ │ │ │ ├── blueprint │ │ │ │ │ │ ├── fields.php │ │ │ │ │ │ └── files.php │ │ │ │ │ └── sidebar.php │ │ │ │ ├── user │ │ │ │ │ ├── blueprint.php │ │ │ │ │ └── history.php │ │ │ │ └── file │ │ │ │ │ └── menu.php │ │ │ │ ├── upload.php │ │ │ │ ├── collections │ │ │ │ ├── users.php │ │ │ │ └── files.php │ │ │ │ ├── urls.php │ │ │ │ ├── view.php │ │ │ │ ├── roots.php │ │ │ │ ├── controllers │ │ │ │ └── field.php │ │ │ │ ├── installer.php │ │ │ │ ├── widgets.php │ │ │ │ ├── translation.php │ │ │ │ └── form │ │ │ │ └── plugins.php │ │ ├── forms │ │ │ ├── avatars │ │ │ │ └── delete.php │ │ │ ├── files │ │ │ │ ├── delete.php │ │ │ │ └── edit.php │ │ │ ├── pages │ │ │ │ ├── delete.php │ │ │ │ ├── url.php │ │ │ │ ├── add.php │ │ │ │ ├── toggle.php │ │ │ │ └── edit.php │ │ │ ├── users │ │ │ │ └── delete.php │ │ │ ├── editor │ │ │ │ ├── link.php │ │ │ │ └── email.php │ │ │ ├── installation │ │ │ │ ├── check.php │ │ │ │ └── signup.php │ │ │ └── auth │ │ │ │ └── login.php │ │ ├── layouts │ │ │ ├── base.php │ │ │ ├── fatal.php │ │ │ └── app.php │ │ └── helpers.php │ ├── assets │ │ ├── images │ │ │ ├── avatar.png │ │ │ ├── pattern.png │ │ │ ├── hint.arrows.png │ │ │ ├── loader.black.gif │ │ │ ├── loader.white.gif │ │ │ └── placeholder.png │ │ ├── fonts │ │ │ ├── sourcesanspro-400.woff │ │ │ ├── sourcesanspro-600.woff │ │ │ ├── fontawesome-webfont.woff │ │ │ ├── sourcesanspro-400.woff2 │ │ │ ├── sourcesanspro-600.woff2 │ │ │ ├── fontawesome-webfont.woff2 │ │ │ ├── sourcesanspro-400-italic.woff │ │ │ └── sourcesanspro-400-italic.woff2 │ │ ├── js │ │ │ └── dist │ │ │ │ ├── app.min.js │ │ │ │ └── form.min.js │ │ └── css │ │ │ └── form.min.css │ ├── readme.md │ └── index.php ├── site.php ├── assets │ ├── fonts │ │ ├── sourcesanspro-300.woff │ │ ├── sourcesanspro-400.woff │ │ ├── sourcesanspro-600.woff │ │ └── sourcesanspro-400-italic.woff │ └── images │ │ └── logo.svg ├── kirby │ ├── kirby │ │ ├── request │ │ │ ├── query.php │ │ │ ├── path.php │ │ │ └── params.php │ │ ├── request.php │ │ └── urls.php │ ├── readme.md │ ├── toolkit │ │ ├── lib │ │ │ ├── l.php │ │ │ ├── c.php │ │ │ ├── toolkit.php │ │ │ ├── error.php │ │ │ ├── timer.php │ │ │ ├── tpl.php │ │ │ ├── obj.php │ │ │ ├── silo.php │ │ │ ├── password.php │ │ │ ├── yaml.php │ │ │ ├── exif │ │ │ │ └── camera.php │ │ │ ├── cache │ │ │ │ ├── driver │ │ │ │ │ ├── mock.php │ │ │ │ │ ├── apc.php │ │ │ │ │ └── session.php │ │ │ │ └── value.php │ │ │ ├── cache.php │ │ │ ├── redirect.php │ │ │ ├── server.php │ │ │ └── bitmask.php │ │ └── readme.md │ ├── lib │ │ ├── pageextension.php │ │ └── structure.php │ ├── system.php │ ├── branches │ │ ├── default.php │ │ ├── multilang │ │ │ ├── languages.php │ │ │ ├── language.php │ │ │ └── content.php │ │ └── multilang.php │ └── core │ │ ├── users.php │ │ └── field.php ├── index.php ├── .htaccess └── readme.md ├── index.php ├── .DS_Store ├── www.conf ├── Dockerfile └── README.md /sample/site/cache/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sample/site/accounts/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sample/site/plugins/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/.DS_Store -------------------------------------------------------------------------------- /sample/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/.DS_Store -------------------------------------------------------------------------------- /sample/content/error/error.txt: -------------------------------------------------------------------------------- 1 | Title: Error 2 | 3 | ---- 4 | 5 | Text: The page has not been found. -------------------------------------------------------------------------------- /sample/panel/app/views/files/delete.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sample/panel/app/views/pages/delete.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sample/panel/app/views/pages/toggle.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sample/panel/app/views/users/delete.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sample/panel/app/translations/ca/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Catalan", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/cs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Česky", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/da/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Dansk", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/de/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Deutsch", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/en/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "English", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/fa/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "پارسی", 3 | "direction": "rtl" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/fi/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Suomi", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/fr/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Français", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/it/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Italiano", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/ja/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Japanese", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/pl/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Polski", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/ro/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Română", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/tr/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Türkçe", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/views/avatars/delete.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sample/panel/app/translations/bg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Bulgarian", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/hu/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Hungarian", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/nb/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Norsk Bokmål", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/nl/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Nederlands", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/sv_SE/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Svenska", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/site.php: -------------------------------------------------------------------------------- 1 | urls->index = "http://" . $_SERVER["HTTP_HOST"]; 4 | 5 | -------------------------------------------------------------------------------- /sample/panel/app/fields/structure/views/delete.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sample/panel/app/translations/id/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Bahasa Indonesia", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/zh_CN/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "简体中文(大陆)‎", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/zh_TW/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "繁體中文(台灣)‎", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/es_ES/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Español (España)", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/pt_PT/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Português (Portugal)", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/ru/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Русский (Russian)‎", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/content/1-about/about.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/content/1-about/about.jpg -------------------------------------------------------------------------------- /sample/panel/app/topbars/error.php: -------------------------------------------------------------------------------- 1 | append('', l('error.headline')); 5 | }; -------------------------------------------------------------------------------- /sample/panel/app/translations/es_419/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Español (América Latina)‎", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/app/translations/pt_BR/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Português (Brasileiro)‎", 3 | "direction": "ltr" 4 | } -------------------------------------------------------------------------------- /sample/panel/assets/images/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/panel/assets/images/avatar.png -------------------------------------------------------------------------------- /sample/panel/assets/images/pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/panel/assets/images/pattern.png -------------------------------------------------------------------------------- /sample/assets/fonts/sourcesanspro-300.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/assets/fonts/sourcesanspro-300.woff -------------------------------------------------------------------------------- /sample/assets/fonts/sourcesanspro-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/assets/fonts/sourcesanspro-400.woff -------------------------------------------------------------------------------- /sample/assets/fonts/sourcesanspro-600.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/assets/fonts/sourcesanspro-600.woff -------------------------------------------------------------------------------- /sample/panel/assets/images/hint.arrows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/panel/assets/images/hint.arrows.png -------------------------------------------------------------------------------- /sample/panel/assets/images/loader.black.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/panel/assets/images/loader.black.gif -------------------------------------------------------------------------------- /sample/panel/assets/images/loader.white.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/panel/assets/images/loader.white.gif -------------------------------------------------------------------------------- /sample/panel/assets/images/placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/panel/assets/images/placeholder.png -------------------------------------------------------------------------------- /sample/panel/app/fields/structure/views/add.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sample/panel/app/fields/structure/views/update.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sample/content/2-projects/1-project-a/green.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/content/2-projects/1-project-a/green.jpg -------------------------------------------------------------------------------- /sample/content/2-projects/2-project-b/road.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/content/2-projects/2-project-b/road.jpg -------------------------------------------------------------------------------- /sample/panel/assets/fonts/sourcesanspro-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/panel/assets/fonts/sourcesanspro-400.woff -------------------------------------------------------------------------------- /sample/panel/assets/fonts/sourcesanspro-600.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/panel/assets/fonts/sourcesanspro-600.woff -------------------------------------------------------------------------------- /sample/assets/fonts/sourcesanspro-400-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/assets/fonts/sourcesanspro-400-italic.woff -------------------------------------------------------------------------------- /sample/content/2-projects/1-project-a/forrest.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/content/2-projects/1-project-a/forrest.jpg -------------------------------------------------------------------------------- /sample/content/2-projects/1-project-a/the-sea.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/content/2-projects/1-project-a/the-sea.jpg -------------------------------------------------------------------------------- /sample/content/2-projects/3-project-c/hightide.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/content/2-projects/3-project-c/hightide.jpg -------------------------------------------------------------------------------- /sample/panel/assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/panel/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /sample/panel/assets/fonts/sourcesanspro-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/panel/assets/fonts/sourcesanspro-400.woff2 -------------------------------------------------------------------------------- /sample/panel/assets/fonts/sourcesanspro-600.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/panel/assets/fonts/sourcesanspro-600.woff2 -------------------------------------------------------------------------------- /sample/content/2-projects/2-project-b/mountains.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/content/2-projects/2-project-b/mountains.jpg -------------------------------------------------------------------------------- /sample/panel/app/views/error/index.php: -------------------------------------------------------------------------------- 1 |
2 |

3 |

4 |
-------------------------------------------------------------------------------- /sample/panel/assets/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/panel/assets/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /sample/panel/assets/fonts/sourcesanspro-400-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/panel/assets/fonts/sourcesanspro-400-italic.woff -------------------------------------------------------------------------------- /sample/content/2-projects/3-project-c/kermit-the-fog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/content/2-projects/3-project-c/kermit-the-fog.jpg -------------------------------------------------------------------------------- /sample/panel/assets/fonts/sourcesanspro-400-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhurlow/docker-kirby-nginx/HEAD/sample/panel/assets/fonts/sourcesanspro-400-italic.woff2 -------------------------------------------------------------------------------- /sample/panel/app/snippets/meta.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /sample/panel/app/translations/ar/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "العربية", 3 | "direction": "rtl", 4 | "author": "أحمد الحداد ", 5 | "version": "1.0.0" 6 | } -------------------------------------------------------------------------------- /sample/kirby/kirby/request/query.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | $c)) ?> 4 | 5 | -------------------------------------------------------------------------------- /sample/site/blueprints/default.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | title: Page 4 | pages: true 5 | files: true 6 | fields: 7 | title: 8 | label: Title 9 | type: text 10 | text: 11 | label: Text 12 | type: textarea -------------------------------------------------------------------------------- /sample/site/blueprints/home.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | title: Home 4 | pages: false 5 | fields: 6 | title: 7 | label: Title 8 | type: text 9 | text: 10 | label: Text 11 | type: textarea 12 | size: large -------------------------------------------------------------------------------- /sample/panel/app/fields/structure/forms/add.php: -------------------------------------------------------------------------------- 1 | fields()); 6 | $form->cancel($model); 7 | $form->buttons->submit->value = l('add'); 8 | 9 | return $form; 10 | 11 | }; -------------------------------------------------------------------------------- /sample/panel/app/fields/tel/tel.php: -------------------------------------------------------------------------------- 1 | type = 'tel'; 7 | $this->icon = 'phone'; 8 | $this->label = l::get('fields.tel.label', 'Phone'); 9 | } 10 | 11 | } -------------------------------------------------------------------------------- /sample/site/blueprints/error.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | title: Error 4 | pages: false 5 | files: false 6 | fields: 7 | title: 8 | label: Title 9 | type: text 10 | text: 11 | label: Text 12 | type: textarea 13 | size: large -------------------------------------------------------------------------------- /sample/site/blueprints/projects.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | title: Projects 4 | pages: 5 | template: project 6 | files: false 7 | fields: 8 | title: 9 | label: Title 10 | type: text 11 | text: 12 | label: Text 13 | type: textarea -------------------------------------------------------------------------------- /sample/panel/app/fields/text/assets/css/counter.css: -------------------------------------------------------------------------------- 1 | .field-counter { 2 | position: absolute; 3 | z-index: -1; 4 | right: 0; 5 | top: 0; 6 | text-align: right; 7 | font-size: .9em; 8 | line-height: 1.66666666666667; 9 | } 10 | .field-counter.outside-range { 11 | color: #b3000a; 12 | } -------------------------------------------------------------------------------- /sample/panel/app/fields/structure/forms/update.php: -------------------------------------------------------------------------------- 1 | fields(), $entry->toArray()); 6 | 7 | $form->cancel($model); 8 | $form->buttons->submit->value = l('ok'); 9 | 10 | return $form; 11 | 12 | }; -------------------------------------------------------------------------------- /sample/site/templates/default.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 |

title()->html() ?>

7 | text()->kirbytext() ?> 8 |
9 | 10 |
11 | 12 | -------------------------------------------------------------------------------- /sample/panel/app/fields/hidden/hidden.php: -------------------------------------------------------------------------------- 1 | 'hidden', 8 | 'name' => $this->name(), 9 | 'value' => $this->value() 10 | )); 11 | } 12 | 13 | } -------------------------------------------------------------------------------- /sample/panel/app/widgets/site/site.php: -------------------------------------------------------------------------------- 1 | array( 5 | 'text' => l('dashboard.index.site.title'), 6 | 'link' => url(), 7 | 'target' => '_blank', 8 | ), 9 | 'html' => function() { 10 | return tpl::load(__DIR__ . DS . 'site.html.php'); 11 | } 12 | ); -------------------------------------------------------------------------------- /sample/content/site.txt: -------------------------------------------------------------------------------- 1 | Title: Kirby Starterkit 2 | 3 | ---- 4 | 5 | Author: Bastian Allgeier GmbH 6 | 7 | ---- 8 | 9 | Description: This is Kirby's Starterkit. 10 | 11 | ---- 12 | 13 | Keywords: Kirby, CMS, file-based 14 | 15 | ---- 16 | 17 | Copyright: © 2009-(date: Year) (link: http://getkirby.com text: Kirby) -------------------------------------------------------------------------------- /sample/panel/app/controllers/dashboard.php: -------------------------------------------------------------------------------- 1 | screen('dashboard/index', panel()->site(), array( 8 | 'widgets' => new Kirby\Panel\Widgets() 9 | )); 10 | 11 | } 12 | 13 | } -------------------------------------------------------------------------------- /sample/panel/app/src/panel/layout.php: -------------------------------------------------------------------------------- 1 | _root = panel::instance()->roots()->layouts(); 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /sample/panel/app/src/panel/snippet.php: -------------------------------------------------------------------------------- 1 | _root = panel::instance()->roots()->snippets(); 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /sample/panel/app/topbars/user.php: -------------------------------------------------------------------------------- 1 | append(purl('users'), l('users')); 6 | 7 | if($user === 'user') { 8 | $topbar->append(purl('users/add'), l('users.index.add')); 9 | } else { 10 | $topbar->append($user->url(), $user->username()); 11 | } 12 | 13 | }; -------------------------------------------------------------------------------- /sample/panel/app/views/auth/login.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /www.conf: -------------------------------------------------------------------------------- 1 | [www] 2 | user = root 3 | group = www-data 4 | php_value[post_max_size] = 256M 5 | php_value[upload_max_filesize] = 256M 6 | listen = /var/run/php5-fpm.sock 7 | listen.owner = www-data 8 | listen.group = www-data 9 | pm = dynamic 10 | pm.max_children = 5 11 | pm.start_servers = 2 12 | pm.min_spare_servers = 1 13 | pm.max_spare_servers = 3 14 | -------------------------------------------------------------------------------- /sample/kirby/kirby/request/path.php: -------------------------------------------------------------------------------- 1 | data); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /sample/panel/app/widgets/history/history.php: -------------------------------------------------------------------------------- 1 | array( 5 | 'text' => l('dashboard.index.history.title'), 6 | 'link' => false, 7 | ), 8 | 'html' => function() { 9 | return tpl::load(__DIR__ . DS . 'history.html.php', array( 10 | 'history' => panel()->user()->history()->get() 11 | )); 12 | } 13 | ); -------------------------------------------------------------------------------- /sample/panel/readme.md: -------------------------------------------------------------------------------- 1 | # Kirby Panel 2 | 3 | This is the Kirby Panel submodule. 4 | 5 | Please refer to the [Kirby Starterkit](http://github.com/getkirby/starterkit) 6 | for a complete installation of Kirby 7 | 8 | ## Author 9 | Bastian Allgeier 10 | 11 | 12 | ## Website 13 | 14 | 15 | ## License 16 | -------------------------------------------------------------------------------- /sample/index.php: -------------------------------------------------------------------------------- 1 | launch(); -------------------------------------------------------------------------------- /sample/panel/app/fields/structure/forms/delete.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'label' => 'fields.structure.delete.label', 8 | 'type' => 'info', 9 | ) 10 | )); 11 | 12 | $form->style('delete'); 13 | $form->cancel($model); 14 | 15 | return $form; 16 | 17 | }; -------------------------------------------------------------------------------- /sample/site/blueprints/project.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | title: Project 4 | pages: false 5 | files: 6 | sortable: true 7 | fields: 8 | title: 9 | label: Title 10 | type: text 11 | year: 12 | label: Year 13 | type: text 14 | text: 15 | label: Text 16 | type: textarea 17 | tags: 18 | label: Tags 19 | type: tags -------------------------------------------------------------------------------- /sample/site/templates/projects.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 |

title()->html() ?>

7 | text()->kirbytext() ?> 8 |
9 | 10 |
11 | 12 | 13 | 14 |
15 | 16 | -------------------------------------------------------------------------------- /sample/panel/app/widgets/license/license.html.php: -------------------------------------------------------------------------------- 1 | 11 |
12 |
13 | 14 |
15 |
-------------------------------------------------------------------------------- /sample/kirby/kirby/request/params.php: -------------------------------------------------------------------------------- 1 | $value) { 14 | $params[] = $key . ':' . $value; 15 | } 16 | 17 | return implode('/', $params); 18 | 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /sample/site/snippets/footer.php: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /sample/panel/app/snippets/search.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /sample/panel/app/views/auth/block.php: -------------------------------------------------------------------------------- 1 | 9 | 10 | -------------------------------------------------------------------------------- /sample/panel/app/fields/line/line.php: -------------------------------------------------------------------------------- 1 | '; 11 | } 12 | 13 | public function element() { 14 | $element = parent::element(); 15 | $element->addClass('field-with-line'); 16 | return $element; 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /sample/panel/app/controllers/search.php: -------------------------------------------------------------------------------- 1 | view('search/results', array( 12 | 'pages' => $search->pages(), 13 | 'users' => $search->users(), 14 | )); 15 | 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /sample/panel/app/fields/filename/filename.php: -------------------------------------------------------------------------------- 1 | addClass('field-icon'); 12 | $icon->append('.' . $this->extension . ''); 13 | 14 | return $icon; 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /sample/panel/app/widgets/site/site.html.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sample/panel/app/fields/url/url.php: -------------------------------------------------------------------------------- 1 | type = 'url'; 8 | $this->icon = 'chain'; 9 | $this->label = l::get('fields.url.label', 'URL'); 10 | $this->placeholder = 'http://'; 11 | 12 | } 13 | 14 | public function validate() { 15 | return v::url($this->value()); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /sample/site/blueprints/site.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | title: Site 4 | pages: default 5 | fields: 6 | title: 7 | label: Title 8 | type: text 9 | author: 10 | label: Author 11 | type: text 12 | description: 13 | label: Description 14 | type: textarea 15 | keywords: 16 | label: Keywords 17 | type: tags 18 | copyright: 19 | label: Copyright 20 | type: textarea -------------------------------------------------------------------------------- /sample/site/templates/home.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

4 | 5 |
6 | 7 |
8 |

title()->html() ?>

9 | text()->kirbytext() ?> 10 |
11 | 12 |
13 | 14 | 15 | 16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /sample/kirby/readme.md: -------------------------------------------------------------------------------- 1 | # Kirby Core 2 | 3 | This is the Kirby Core submodule. 4 | 5 | Please refer to the [Kirby Starterkit](http://github.com/getkirby/starterkit) 6 | for a complete installation of Kirby 7 | 8 | ![Build Status](https://travis-ci.org/getkirby/kirby.svg) 9 | 10 | ## Author 11 | Bastian Allgeier 12 | 13 | 14 | ## Website 15 | 16 | 17 | ## License 18 | -------------------------------------------------------------------------------- /sample/panel/app/forms/avatars/delete.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'type' => 'info' 8 | ) 9 | )); 10 | 11 | $form->fields->image->text = '(image: ' . $avatar->url() . ' class: avatar avatar-full avatar-centered)'; 12 | $form->centered = true; 13 | $form->style('delete'); 14 | 15 | return $form; 16 | 17 | }; 18 | 19 | 20 | -------------------------------------------------------------------------------- /sample/panel/app/widgets/account/account.html.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sample/panel/app/controllers/assets.php: -------------------------------------------------------------------------------- 1 | plugins()->js(), 'text/javascript'); 10 | } 11 | 12 | public function css() { 13 | $form = new Form(); 14 | return new Response($form->plugins()->css(), 'text/css'); 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /sample/panel/app/forms/files/delete.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'label' => 'files.delete.headline', 8 | 'type' => 'text', 9 | 'readonly' => true, 10 | 'icon' => false, 11 | 'default' => $file->filename() 12 | ) 13 | )); 14 | 15 | $form->style('delete'); 16 | $form->cancel($file); 17 | 18 | return $form; 19 | 20 | }; -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:trusty 2 | USER root 3 | RUN apt-get update 4 | RUN apt-get install -y nginx 5 | RUN apt-get install -y php5-fpm 6 | RUN apt-get install -y imagemagick 7 | ADD nginx.conf /etc/nginx/nginx.conf 8 | ADD www.conf /etc/php5/fpm/pool.d/www.conf 9 | 10 | WORKDIR /app 11 | EXPOSE 80 12 | 13 | CMD /usr/sbin/php5-fpm \ 14 | --daemonize \ 15 | --fpm-config /etc/php5/fpm/php-fpm.conf \ 16 | --allow-to-run-as-root && nginx -g 'daemon off;' 17 | 18 | -------------------------------------------------------------------------------- /sample/kirby/toolkit/lib/l.php: -------------------------------------------------------------------------------- 1 | 11 | * @link http://getkirby.com 12 | * @copyright Bastian Allgeier 13 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 14 | */ 15 | class L extends Silo { 16 | public static $data = array(); 17 | } -------------------------------------------------------------------------------- /sample/kirby/lib/pageextension.php: -------------------------------------------------------------------------------- 1 | parent(), $page->dirname()); 13 | } else { 14 | throw new Exception('The page could not be found'); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /sample/panel/app/snippets/pages/sidebar/file.php: -------------------------------------------------------------------------------- 1 |
  • 2 | canHavePreview(), ' data-url="' . $file->thumb(75, 75, true) . '"') ?> data-helper="filename()) ?>" data-text="dragText()) ?>" href="url('edit')) ?>"> 3 | icon() . __($file->filename()) ?> 4 | 5 | 6 |
  • -------------------------------------------------------------------------------- /sample/kirby/toolkit/lib/c.php: -------------------------------------------------------------------------------- 1 | 11 | * @link http://getkirby.com 12 | * @copyright Bastian Allgeier 13 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 14 | */ 15 | class C extends Silo { 16 | public static $data = array(); 17 | } -------------------------------------------------------------------------------- /sample/panel/app/controllers/autocomplete.php: -------------------------------------------------------------------------------- 1 | result(); 10 | } catch(Exception $e) { 11 | $result = array(); 12 | } 13 | 14 | return $this->json(array( 15 | 'data' => $result 16 | )); 17 | 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /sample/panel/app/fields/info/info.php: -------------------------------------------------------------------------------- 1 | addClass('field-with-icon'); 14 | return $element; 15 | } 16 | 17 | public function input() { 18 | return '
    ' . kirbytext($this->i18n($this->text())) . '
    '; 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /sample/panel/app/src/panel/models/page/addbutton.php: -------------------------------------------------------------------------------- 1 | page = $page; 12 | $this->modal = true; 13 | $this->url = $this->page->url('add'); 14 | 15 | if(!$this->page->canHaveMoreSubpages()) { 16 | throw new Exception(l('subpages.add.error.more')); 17 | } 18 | 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /sample/kirby/toolkit/lib/toolkit.php: -------------------------------------------------------------------------------- 1 | 8 | * @link http://getkirby.com 9 | * @copyright Bastian Allgeier 10 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 11 | */ 12 | class Toolkit { 13 | 14 | public static $version = '2.2.2'; 15 | 16 | public static function version() { 17 | return static::$version; 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /sample/panel/app/forms/pages/delete.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'label' => 'pages.delete.headline', 8 | 'type' => 'text', 9 | 'readonly' => true, 10 | 'icon' => false, 11 | 'default' => $page->title(), 12 | 'help' => $page->id(), 13 | ) 14 | )); 15 | 16 | $form->style('delete'); 17 | $form->cancel($page); 18 | 19 | return $form; 20 | 21 | }; -------------------------------------------------------------------------------- /sample/panel/app/layouts/base.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <?php __($title) ?> 8 | 9 | 10 | 11 | option('panel.stylesheet')): ?> 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /sample/panel/app/fields/headline/assets/css/headline.css: -------------------------------------------------------------------------------- 1 | .field-with-headline { 2 | counter-increment: count; 3 | } 4 | .field-with-headline:first-child { 5 | padding-top: 0; 6 | } 7 | .field-with-headline { 8 | padding-top: 6em; 9 | } 10 | .field-with-headline .hgroup span { 11 | padding-left: 1.5em; 12 | } 13 | .field-with-headline .hgroup:before { 14 | position: absolute; 15 | content: counter(count, decimal-leading-zero); 16 | left: 0; 17 | color: #8dae28; 18 | font-weight: 400; 19 | } 20 | -------------------------------------------------------------------------------- /sample/panel/app/forms/users/delete.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'label' => 'users.delete.headline', 8 | 'type' => 'text', 9 | 'readonly' => true, 10 | 'icon' => false, 11 | 'default' => $user->username(), 12 | 'help' => $user->email(), 13 | ) 14 | )); 15 | 16 | $form->style('delete'); 17 | $form->cancel($user, 'edit'); 18 | 19 | return $form; 20 | 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | This is a docker image for running [kirby](http://getkirby.com) cms apps 4 | 5 | to use: 6 | 7 | ### pull it 8 | 9 | ``` 10 | docker pull bhurlow/docker-kirby-nginx 11 | ``` 12 | 13 | ### run it: 14 | ``` 15 | docker run -i -t -p 3000:80 -v $PWD:/app bhurlow/docker-kirby-nginx 16 | ``` 17 | 18 | note, you'll have to update your site url for css assets to load properly: 19 | 20 | in site.php: 21 | 22 | ``` 23 | urls->index = 'http://docker:3000'; 26 | ``` 27 | 28 | -------------------------------------------------------------------------------- /sample/panel/app/views/installation/index.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /sample/kirby/system.php: -------------------------------------------------------------------------------- 1 | roots->index = $root; 17 | $kirby->roots->site = $rootSite; 18 | $kirby->roots->content = $rootContent; 19 | 20 | // render 21 | echo $kirby->launch(); -------------------------------------------------------------------------------- /sample/panel/app/snippets/pages/sidebar.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sample/content/2-projects/2-project-b/project.txt: -------------------------------------------------------------------------------- 1 | Title: Project B 2 | 3 | ---- 4 | 5 | Year: 2013 6 | 7 | ---- 8 | 9 | Tags: city 10 | 11 | ---- 12 | 13 | Text: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. -------------------------------------------------------------------------------- /sample/content/2-projects/3-project-c/project.txt: -------------------------------------------------------------------------------- 1 | Title: Project C 2 | 3 | ---- 4 | 5 | Year: 2012 6 | 7 | ---- 8 | 9 | Tags: stuff 10 | 11 | ---- 12 | 13 | Text: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. -------------------------------------------------------------------------------- /sample/panel/app/snippets/pages/sidebar/subpage.php: -------------------------------------------------------------------------------- 1 |
  • 2 | 3 | icon() ?>title()) ?> 4 | displayNum()) ?> 5 | 6 | 7 |
  • -------------------------------------------------------------------------------- /sample/panel/app/snippets/uploader.php: -------------------------------------------------------------------------------- 1 | isset($multiple) ? $multiple : true, 5 | 'accept' => isset($accept) ? $accept : false 6 | )); 7 | 8 | ?> 9 | 13 | 14 | -------------------------------------------------------------------------------- /sample/panel/app/views/pages/add.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /sample/panel/app/widgets/account/account.php: -------------------------------------------------------------------------------- 1 | user(); 4 | 5 | return array( 6 | 'title' => array( 7 | 'text' => l('dashboard.index.account.title'), 8 | 'link' => $user->url('edit'), 9 | ), 10 | 'options' => array( 11 | array( 12 | 'text' => l('dashboard.index.account.edit'), 13 | 'icon' => 'pencil', 14 | 'link' => $user->url('edit') 15 | ) 16 | ), 17 | 'html' => function() use($user) { 18 | return tpl::load(__DIR__ . DS . 'account.html.php', array( 19 | 'user' => $user 20 | )); 21 | } 22 | ); -------------------------------------------------------------------------------- /sample/content/2-projects/1-project-a/project.txt: -------------------------------------------------------------------------------- 1 | Title: Project A 2 | 3 | ---- 4 | 5 | Year: 2014 6 | 7 | ---- 8 | 9 | Tags: outdoor 10 | 11 | ---- 12 | 13 | Text: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. -------------------------------------------------------------------------------- /sample/content/3-contact/contact.txt: -------------------------------------------------------------------------------- 1 | Title: Contact 2 | 3 | ---- 4 | 5 | Text: 6 | 7 | ## Get in touch 8 | 9 | - (link: http://getkirby.com/support text: Kirby's support page) 10 | - (link: http://forum.getkirby.com text: Kirby's forum) 11 | - (link: http://github.com/getkirby text: Kirby on Github) 12 | - 13 | 14 | ## Follow us on Twitter 15 | 16 | - Follow Kirby on Twitter (twitter: @getkirby) 17 | - Follow Bastian on Twitter (twitter: @bastianallgeier) 18 | - Follow Nico on Twitter (twitter: @distantnative) 19 | - Follow Sascha on Twitter (twitter: @sashtown) -------------------------------------------------------------------------------- /sample/panel/app/fields/textarea/controller.php: -------------------------------------------------------------------------------- 1 | model(); 8 | $form = $this->form('link', array($page, $this->fieldname())); 9 | 10 | return $this->modal('link', compact('form')); 11 | 12 | } 13 | 14 | public function email($textarea = null) { 15 | 16 | $page = $this->model(); 17 | $form = $this->form('email', array($page, $this->fieldname())); 18 | 19 | return $this->modal('email', compact('form')); 20 | 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /sample/kirby/toolkit/lib/error.php: -------------------------------------------------------------------------------- 1 | 8 | * @link http://getkirby.com 9 | * @copyright Bastian Allgeier 10 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 11 | */ 12 | class Error extends Exception { 13 | 14 | public function message() { 15 | return $this->message; 16 | } 17 | 18 | public function code() { 19 | return $this->code; 20 | } 21 | 22 | public function __toString() { 23 | return $this->message; 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /sample/panel/app/fields/page/page.php: -------------------------------------------------------------------------------- 1 | icon = 'chain'; 8 | $this->label = l::get('fields.page.label', 'Page'); 9 | $this->placeholder = l::get('fields.page.placeholder', 'path/to/page'); 10 | 11 | } 12 | 13 | public function input() { 14 | 15 | $input = parent::input(); 16 | $input->data(array( 17 | 'field' => 'autocomplete', 18 | 'url' => panel()->urls()->api() . '/autocomplete/uris' 19 | )); 20 | 21 | return $input; 22 | 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /sample/panel/app/fields/user/user.php: -------------------------------------------------------------------------------- 1 | type = 'text'; 7 | $this->icon = 'user'; 8 | $this->label = l::get('fields.user.label', 'User'); 9 | $this->options = array(); 10 | 11 | foreach(kirby()->site()->users() as $user) { 12 | $this->options[$user->username()] = $user->username(); 13 | } 14 | 15 | } 16 | 17 | public function value() { 18 | $value = parent::value(); 19 | return empty($value) ? site()->user()->username() : parent::value(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /sample/content/home/home.txt: -------------------------------------------------------------------------------- 1 | Title: Home 2 | 3 | ---- 4 | 5 | Text: Yay! If you are seeing this, the installation of Kirby worked. :) 6 | 7 | ## Get started 8 | 9 | - Go to the (link: panel text: panel) to give Kirby's admin interface a try 10 | - Check out the (link: http://getkirby.com/docs text: docs) and start building your own site 11 | - Follow (twitter: @getkirby) on Twitter for updates 12 | - Visit the (link: http://forum.getkirby.com text: forum) to connect with other Kirby users 13 | - (link: http://getkirby.com/support text: Get in contact) if you need support. 14 | 15 | **Have fun with Kirby!** -------------------------------------------------------------------------------- /sample/kirby/branches/default.php: -------------------------------------------------------------------------------- 1 | site = $site; 14 | } 15 | 16 | public function find($code) { 17 | return isset($this->data[$code]) ? $this->data[$code] : null; 18 | } 19 | 20 | public function codes() { 21 | return $this->keys(); 22 | } 23 | 24 | public function findDefault() { 25 | return $this->site->defaultLanguage(); 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /sample/content/2-projects/projects.txt: -------------------------------------------------------------------------------- 1 | Title: Projects 2 | 3 | ---- 4 | 5 | Text: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. 6 | 7 | Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. -------------------------------------------------------------------------------- /sample/panel/app/snippets/languages.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |
    4 | 5 | 6 | code()) ?> 7 | 8 | 9 | 18 | 19 |
    20 | 21 | 22 | -------------------------------------------------------------------------------- /sample/panel/app/forms/editor/link.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'label' => 'editor.link.url.label', 8 | 'type' => 'text', 9 | 'placeholder' => 'http://', 10 | 'autofocus' => 'true', 11 | 'required' => 'true', 12 | ), 13 | 'text' => array( 14 | 'label' => 'editor.link.text.label', 15 | 'type' => 'text', 16 | 'help' => 'editor.link.text.help', 17 | ), 18 | )); 19 | 20 | $form->data('textarea', 'form-field-' . $textarea); 21 | $form->style('editor'); 22 | $form->cancel($page, 'show'); 23 | 24 | return $form; 25 | 26 | }; -------------------------------------------------------------------------------- /sample/panel/app/views/error/modal.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sample/panel/app/layouts/fatal.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Kirby Panel 5 | 6 | 7 | 21 | 22 | 23 | 24 |

    Panel Error:

    25 |

    26 | 27 |

    28 |

    29 | Find more info on: getkirby.com 30 |

    31 | 32 | -------------------------------------------------------------------------------- /sample/site/snippets/menu.php: -------------------------------------------------------------------------------- 1 | 23 | -------------------------------------------------------------------------------- /sample/site/snippets/projects.php: -------------------------------------------------------------------------------- 1 |

    Latest projects

    2 | 3 | 16 | -------------------------------------------------------------------------------- /sample/panel/app/fields/headline/headline.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'headline.css' 8 | ) 9 | ); 10 | 11 | public function result() { 12 | return null; 13 | } 14 | 15 | public function label() { 16 | return null; 17 | } 18 | 19 | public function content() { 20 | return '

    ' . html($this->i18n($this->label)) . '

    '; 21 | } 22 | 23 | public function element() { 24 | $element = parent::element(); 25 | $element->addClass('field-with-headline'); 26 | return $element; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /sample/panel/app/forms/editor/email.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'label' => 'editor.email.address.label', 8 | 'type' => 'email', 9 | 'placeholder' => 'editor.email.address.placeholder', 10 | 'autofocus' => 'true', 11 | 'required' => 'true', 12 | ), 13 | 'text' => array( 14 | 'label' => 'editor.email.text.label', 15 | 'type' => 'text', 16 | 'help' => 'editor.email.text.help', 17 | ) 18 | )); 19 | 20 | $form->data('textarea', 'form-field-' . $textarea); 21 | $form->style('editor'); 22 | $form->cancel($page, 'show'); 23 | 24 | return $form; 25 | 26 | }; -------------------------------------------------------------------------------- /sample/assets/images/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 9 | -------------------------------------------------------------------------------- /sample/panel/app/forms/installation/check.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'type' => 'info' 8 | ) 9 | )); 10 | 11 | $info = new Brick('ol'); 12 | 13 | foreach($problems as $problem) { 14 | $info->append('
  • ' . $problem . '
  • '); 15 | } 16 | 17 | // add the list of problems to the info field 18 | $form->fields->info->text = (string)$info; 19 | 20 | // setup the retry button 21 | $form->buttons->submit->value = l('installation.check.retry'); 22 | $form->buttons->submit->autofocus = true; 23 | 24 | $form->style('centered'); 25 | $form->alert(l('installation.check.text')); 26 | 27 | return $form; 28 | 29 | }; -------------------------------------------------------------------------------- /sample/panel/app/widgets/license/license.php: -------------------------------------------------------------------------------- 1 | license(); 4 | 5 | if($license->type() == 'trial' and !$license->local()) { 6 | 7 | return array( 8 | 'title' => array( 9 | 'text' => l('dashboard.index.license.title'), 10 | 'link' => false, 11 | 'compressed' => false 12 | ), 13 | 'html' => function() { 14 | return tpl::load(__DIR__ . DS . 'license.html.php', array( 15 | 'text' => kirbytext(str::template(l('dashboard.index.license.text'), array( 16 | 'buy' => 'http://getkirby.com/buy', 17 | 'docs' => 'http://getkirby.com/docs/installation/license-code' 18 | ))) 19 | )); 20 | } 21 | ); 22 | 23 | } else { 24 | return false; 25 | } -------------------------------------------------------------------------------- /sample/panel/app/widgets/history/history.html.php: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 5 | 17 | 18 |
    -------------------------------------------------------------------------------- /sample/kirby/toolkit/readme.md: -------------------------------------------------------------------------------- 1 | # Kirby Toolkit 2 | 3 | The Kirby 2 toolkit is a set of handy classes and helpers which make your life with PHP easier. 4 | 5 | [![Build Status](https://travis-ci.org/getkirby/toolkit.svg?branch=master)](https://travis-ci.org/getkirby/toolkit) 6 | 7 | ## Installation 8 | 9 | ```` 10 | git pull https://github.com/getkirby/toolkit.git 11 | ```` 12 | 13 | Adding the toolkit to your app… 14 | 15 | ```php 16 | 17 | ``` 18 | 19 | ## Requirements 20 | 21 | PHP 5.4+ 22 | 23 | ## License 24 | 25 | 26 | 27 | ## Author 28 | 29 | Bastian Allgeier 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /sample/panel/app/fields/textarea/forms/email.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'label' => 'editor.email.address.label', 8 | 'type' => 'email', 9 | 'placeholder' => 'editor.email.address.placeholder', 10 | 'autofocus' => 'true', 11 | 'required' => 'true', 12 | ), 13 | 'text' => array( 14 | 'label' => 'editor.email.text.label', 15 | 'type' => 'text', 16 | 'help' => 'editor.email.text.help', 17 | 'icon' => 'font' 18 | ) 19 | )); 20 | 21 | $form->data('textarea', 'form-field-' . $textarea); 22 | $form->style('editor'); 23 | $form->cancel($page); 24 | 25 | return $form; 26 | 27 | }; -------------------------------------------------------------------------------- /sample/panel/app/fields/textarea/forms/link.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'label' => 'editor.link.url.label', 8 | 'type' => 'text', 9 | 'placeholder' => 'http://', 10 | 'autofocus' => 'true', 11 | 'required' => 'true', 12 | 'icon' => 'chain' 13 | ), 14 | 'text' => array( 15 | 'label' => 'editor.link.text.label', 16 | 'type' => 'text', 17 | 'help' => 'editor.link.text.help', 18 | 'icon' => 'font' 19 | ), 20 | )); 21 | 22 | $form->data('textarea', 'form-field-' . $textarea); 23 | $form->style('editor'); 24 | $form->cancel($page); 25 | 26 | return $form; 27 | 28 | }; -------------------------------------------------------------------------------- /sample/kirby/toolkit/lib/timer.php: -------------------------------------------------------------------------------- 1 | 8 | * @link http://getkirby.com 9 | * @copyright Bastian Allgeier 10 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 11 | */ 12 | class Timer { 13 | 14 | public static $time = null; 15 | 16 | public static function start() { 17 | $time = explode(' ', microtime()); 18 | static::$time = (double)$time[1] + (double)$time[0]; 19 | } 20 | 21 | public static function stop() { 22 | $time = explode(' ', microtime()); 23 | $time = (double)$time[1] + (double)$time[0]; 24 | $timer = static::$time; 25 | return round(($time-$timer), 5); 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /sample/panel/app/layouts/app.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <?php __($title) ?> 8 | 9 | 10 | 11 | 12 | 13 | option('panel.stylesheet')): ?> 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
    26 | 27 | 28 |
    29 | 30 | 31 | -------------------------------------------------------------------------------- /sample/panel/app/forms/auth/login.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'label' => 'login.username.label', 8 | 'type' => 'text', 9 | 'icon' => 'user', 10 | 'required' => true, 11 | 'autofocus' => true, 12 | 'default' => s::get('username') 13 | ), 14 | 'password' => array( 15 | 'label' => 'login.password.label', 16 | 'type' => 'password', 17 | 'required' => true 18 | ) 19 | )); 20 | 21 | $form->attr('autocomplete', 'off'); 22 | $form->data('autosubmit', 'native'); 23 | $form->style('centered'); 24 | 25 | $form->buttons->submit->value = l('login.button'); 26 | 27 | return $form; 28 | 29 | }; 30 | 31 | -------------------------------------------------------------------------------- /sample/panel/app/snippets/breadcrumb.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sample/site/snippets/header.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <?php echo $site->title()->html() ?> | <?php echo $page->title()->html() ?> 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /sample/kirby/toolkit/lib/tpl.php: -------------------------------------------------------------------------------- 1 | 10 | * @link http://getkirby.com 11 | * @copyright Bastian Allgeier 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | class Tpl extends Silo { 15 | 16 | public static $data = array(); 17 | 18 | public static function load($_file, $_data = array(), $_return = true) { 19 | if(!file_exists($_file)) return false; 20 | ob_start(); 21 | extract(array_merge(static::$data, (array)$_data)); 22 | require($_file); 23 | $_content = ob_get_contents(); 24 | ob_end_clean(); 25 | if($_return) return $_content; 26 | echo $_content; 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /sample/panel/app/views/pages/url.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /sample/panel/app/fields/title/title.php: -------------------------------------------------------------------------------- 1 | label = l::get('fields.title.label', 'Title'); 8 | $this->icon = 'font'; 9 | $this->required = true; 10 | 11 | } 12 | 13 | public function help() { 14 | 15 | if($this->page and !$this->page->isSite()) { 16 | 17 | if(!empty($this->help)) { 18 | $this->help .= '
    '; 19 | } 20 | 21 | $this->help .= '→  ' . ltrim($this->page->parent()->slug() . '/', '/') . $this->page->slug() . ''; 22 | 23 | } 24 | 25 | return parent::help(); 26 | 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /sample/panel/app/fields/structure/template.php: -------------------------------------------------------------------------------- 1 |
    6 | 7 | headline() ?> 8 | 9 |
    10 | 11 | entries()->count()): ?> 12 |
    13 | 14 |
    15 | 16 | style() . '.php') ?> 17 | 18 |
    19 | 20 |
    -------------------------------------------------------------------------------- /sample/panel/app/controllers/error.php: -------------------------------------------------------------------------------- 1 | auth(); 8 | 9 | if(is_null($text)) { 10 | $text = l('pages.error.missing'); 11 | } 12 | 13 | if(server::get('HTTP_MODAL')) { 14 | return $this->modal('error', array( 15 | 'text' => $text, 16 | 'back' => url::last(), 17 | )); 18 | } else { 19 | return $this->screen('error/index', 'error', array( 20 | 'text' => $text, 21 | 'exception' => $exception 22 | )); 23 | } 24 | 25 | } 26 | 27 | public function auth() { 28 | try { 29 | $user = panel()->user(); 30 | } catch(Exception $e) { 31 | $this->redirect('login'); 32 | } 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /sample/kirby/branches/multilang/language.php: -------------------------------------------------------------------------------- 1 | site = $site; 13 | $this->code = $lang['code']; 14 | $this->name = $lang['name']; 15 | $this->locale = $lang['locale']; 16 | $this->default = (isset($lang['default']) and $lang['default']); 17 | $this->direction = (isset($lang['direction']) and $lang['direction'] == 'rtl') ? 'rtl' : 'ltr'; 18 | $this->url = isset($lang['url']) ? $lang['url'] : $lang['code']; 19 | 20 | } 21 | 22 | public function url() { 23 | return url::makeAbsolute($this->url, $this->site->url()); 24 | } 25 | 26 | public function __toString() { 27 | return $this->code; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /sample/panel/app/fields/structure/styles/items.php: -------------------------------------------------------------------------------- 1 | entries() as $entry): ?> 2 |
    3 |
    4 | entry($entry) ?> 5 |
    6 | readonly()): ?> 7 | 16 | 17 |
    18 | -------------------------------------------------------------------------------- /sample/site/config/config.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /sample/panel/app/snippets/pagination.php: -------------------------------------------------------------------------------- 1 | pages() > 1): ?> 2 | 14 | -------------------------------------------------------------------------------- /sample/kirby/kirby/request.php: -------------------------------------------------------------------------------- 1 | kirby = $kirby; 15 | } 16 | 17 | public function url() { 18 | return url::current(); 19 | } 20 | 21 | public function params() { 22 | return new Request\Params(url::params()); 23 | } 24 | 25 | public function query() { 26 | return new Request\Query(url::query()); 27 | } 28 | 29 | public function path() { 30 | return new Request\Path($this->kirby->path()); 31 | } 32 | 33 | public function __call($method, $arguments) { 34 | if(method_exists('r', $method)) { 35 | return call('r::' . $method, $arguments); 36 | } else { 37 | throw new Exception('Invalid method: ' . $method); 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /sample/panel/app/fields/toggle/toggle.php: -------------------------------------------------------------------------------- 1 | text())) { 10 | case 'yes/no': 11 | $true = l::get('fields.toggle.yes'); 12 | $false = l::get('fields.toggle.no'); 13 | break; 14 | case 'on/off': 15 | $true = l::get('fields.toggle.on'); 16 | $false = l::get('fields.toggle.off'); 17 | break; 18 | } 19 | 20 | return array( 21 | 'true' => $true, 22 | 'false' => $false 23 | ); 24 | 25 | } 26 | 27 | public function value() { 28 | $value = parent::value(); 29 | 30 | if(in_array($value, array('yes', 'true', true, 1, 'on'), true)) { 31 | return 'true'; 32 | } else { 33 | return 'false'; 34 | } 35 | 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /sample/panel/app/src/panel/upload.php: -------------------------------------------------------------------------------- 1 | 'The file is missing', 10 | static::ERROR_MISSING_TMP_DIR => 'The /tmp directory is missing on your server', 11 | static::ERROR_FAILED_UPLOAD => 'The upload failed', 12 | static::ERROR_PARTIAL_UPLOAD => 'The file has been only been partially uploaded', 13 | static::ERROR_UNALLOWED_OVERWRITE => 'The file exists and cannot be overwritten', 14 | static::ERROR_MAX_SIZE => 'The file is too big. The maximum size is ' . f::niceSize($this->maxSize()), 15 | static::ERROR_MOVE_FAILED => 'The file could not be moved', 16 | static::ERROR_UNACCEPTED => 'The file is not accepted by the server' 17 | ); 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /sample/panel/app/src/panel/collections/users.php: -------------------------------------------------------------------------------- 1 | map(function($user) { 15 | return new User($user->username()); 16 | }); 17 | 18 | } 19 | 20 | public function topbar($topbar) { 21 | $topbar->append(purl('users'), l('users')); 22 | } 23 | 24 | public function create($data) { 25 | 26 | if($data['password'] !== $data['passwordconfirmation']) { 27 | throw new Exception(l('users.form.error.password.confirm')); 28 | } 29 | 30 | unset($data['passwordconfirmation']); 31 | 32 | $user = parent::create($data); 33 | kirby()->trigger('panel.user.create', $user); 34 | return new User($user->username()); 35 | 36 | } 37 | 38 | 39 | } -------------------------------------------------------------------------------- /sample/panel/app/fields/email/email.php: -------------------------------------------------------------------------------- 1 | type = 'email'; 8 | $this->icon = 'envelope'; 9 | $this->label = l::get('fields.email.label', 'Email'); 10 | $this->placeholder = l::get('fields.email.placeholder', 'mail@example.com'); 11 | $this->autocomplete = true; 12 | 13 | } 14 | 15 | public function input() { 16 | 17 | $input = parent::input(); 18 | 19 | if($this->autocomplete) { 20 | $input->attr('autocomplete', 'off'); 21 | $input->data(array( 22 | 'field' => 'autocomplete', 23 | 'url' => panel()->urls()->api() . '/autocomplete/emails?_csrf=' . panel()->csrf() 24 | )); 25 | } 26 | 27 | return $input; 28 | 29 | } 30 | 31 | public function validate() { 32 | return v::email($this->result()); 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /sample/kirby/core/users.php: -------------------------------------------------------------------------------- 1 | 8 | * @link http://getkirby.com 9 | * @copyright Bastian Allgeier 10 | * @license http://getkirby.com/license 11 | */ 12 | abstract class UsersAbstract extends Collection { 13 | 14 | public function __construct() { 15 | 16 | $root = kirby::instance()->roots()->accounts(); 17 | 18 | foreach(dir::read($root) as $file) { 19 | 20 | // skip invalid account files 21 | if(f::extension($file) != 'php') continue; 22 | 23 | $user = new User(f::name($file)); 24 | $this->append($user->username(), $user); 25 | 26 | } 27 | 28 | } 29 | 30 | public function create($data) { 31 | return user::create($data); 32 | } 33 | 34 | public function find($username) { 35 | return $this->findBy('username', $username); 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /sample/panel/app/views/pages/edit.php: -------------------------------------------------------------------------------- 1 |
    2 | 3 | 4 | 5 |
    6 |
    7 | 8 | isWritable()): ?> 9 |
    10 |

    11 | 12 |

    13 |
    14 |

    15 |
    16 |
    17 | 18 | 19 | 20 |
    21 |
    22 | 23 | 24 | 25 | 26 |
    27 |
    28 | 29 |
    30 | 31 | -------------------------------------------------------------------------------- /sample/panel/app/src/panel/urls.php: -------------------------------------------------------------------------------- 1 | panel = $panel; 12 | 13 | // base url 14 | $this->index = rtrim($this->panel->kirby()->urls()->index(), '/') . '/' . basename($root); 15 | 16 | // assets 17 | $this->assets = $this->index . '/assets'; 18 | $this->css = $this->assets . '/css'; 19 | $this->js = $this->assets . '/js'; 20 | $this->images = $this->assets . '/images'; 21 | 22 | // enable urls without rewriting 23 | if(kirby()->option('rewrite') === false) { 24 | $this->index .= '/index.php'; 25 | } 26 | 27 | // shortcuts 28 | $this->api = $this->index . '/api'; 29 | $this->login = $this->index . '/login'; 30 | $this->logout = $this->index . '/logout'; 31 | $this->error = $this->index . '/error'; 32 | 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /sample/kirby/toolkit/lib/obj.php: -------------------------------------------------------------------------------- 1 | 10 | * @link http://getkirby.com 11 | * @copyright Bastian Allgeier 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | class Obj extends stdClass { 15 | 16 | public function __construct($data = array()) { 17 | foreach($data as $key => $val) { 18 | $this->{$key} = $val; 19 | } 20 | } 21 | 22 | public function __call($method, $arguments) { 23 | return isset($this->$method) ? $this->$method : null; 24 | } 25 | 26 | public function set($key, $value) { 27 | $this->$key = $value; 28 | } 29 | 30 | public function get($key, $default = null) { 31 | return isset($this->$key) ? $this->$key : $default; 32 | } 33 | 34 | public function toArray() { 35 | return (array)$this; 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /sample/panel/app/fields/text/assets/js/counter.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 3 | $.fn.counter = function() { 4 | 5 | return this.each(function() { 6 | 7 | var counter = $(this); 8 | 9 | if(counter.data('counter')) { 10 | return counter; 11 | } 12 | 13 | var field = counter.parent('.field').find('.input'); 14 | var length = $.trim(field.val()).length; 15 | var max = field.data('max'); 16 | var min = field.data('min'); 17 | 18 | field.keyup(function() { 19 | length = $.trim(field.val()).length; 20 | counter.text(length + (max ? '/' + max : '')); 21 | if((max && length > max) || (min && length < min)) { 22 | counter.addClass('outside-range'); 23 | } else { 24 | counter.removeClass('outside-range'); 25 | } 26 | }).trigger('keyup'); 27 | 28 | counter.data('counter', true); 29 | 30 | }); 31 | 32 | }; 33 | 34 | }(jQuery)); -------------------------------------------------------------------------------- /sample/panel/app/fields/password/password.php: -------------------------------------------------------------------------------- 1 | type = 'password'; 10 | $this->icon = 'key'; 11 | $this->label = l('fields.password.label', 'Password'); 12 | 13 | } 14 | 15 | public function input() { 16 | 17 | $input = parent::input(); 18 | 19 | if($this->suggestion) { 20 | $input->data(array( 21 | 'field' => 'passwordSuggestion' 22 | )); 23 | } 24 | 25 | return $input; 26 | 27 | } 28 | 29 | public function help() { 30 | if($this->suggestion and !$this->readonly) { 31 | $this->help = $this->suggestion(); 32 | } 33 | return parent::help(); 34 | } 35 | 36 | public function suggestion() { 37 | return ''; 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /sample/panel/app/widgets/pages/pages.php: -------------------------------------------------------------------------------- 1 | site(); 4 | $options = array(); 5 | 6 | if($site->canHaveSubpages()) { 7 | $options[] = array( 8 | 'text' => l('dashboard.index.pages.edit'), 9 | 'icon' => 'pencil', 10 | 'link' => $site->url('subpages') 11 | ); 12 | } 13 | 14 | if($addbutton = $site->addButton()) { 15 | $options[] = array( 16 | 'text' => l('dashboard.index.pages.add'), 17 | 'icon' => 'plus-circle', 18 | 'link' => $addbutton->url(), 19 | 'modal' => $addbutton->modal(), 20 | 'key' => '+', 21 | ); 22 | } 23 | 24 | return array( 25 | 'title' => array( 26 | 'text' => l('dashboard.index.pages.title'), 27 | 'link' => $site->url('subpages'), 28 | 'compressed' => true 29 | ), 30 | 'options' => $options, 31 | 'html' => function() use($site) { 32 | return tpl::load(__DIR__ . DS . 'pages.html.php', array( 33 | 'pages' => $site->children() 34 | )); 35 | } 36 | ); -------------------------------------------------------------------------------- /sample/panel/app/src/panel/view.php: -------------------------------------------------------------------------------- 1 | _root = panel::instance()->roots()->views(); 18 | $this->_file = $file; 19 | $this->_data = $data; 20 | } 21 | 22 | public function __set($key, $value) { 23 | $this->_data[$key] = $value; 24 | } 25 | 26 | public function render() { 27 | $file = $this->_root . DS . str_replace('.', DS, $this->_file) . '.php'; 28 | if(!file_exists($file)) throw new Exception(l('view.error.invalid') . $file); 29 | return tpl::load($file, $this->_data); 30 | } 31 | 32 | public function __toString() { 33 | try { 34 | return (string)$this->render(); 35 | } catch(Exception $e) { 36 | return $e->getMessage(); 37 | } 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /sample/kirby/lib/structure.php: -------------------------------------------------------------------------------- 1 | data[$key])) { 10 | return $this->data[$key]; 11 | } else { 12 | $lowerkeys = array_change_key_case($this->data, CASE_LOWER); 13 | if(isset($lowerkeys[strtolower($key)])) { 14 | return $lowerkeys[$key]; 15 | } 16 | } 17 | 18 | return new Field($this->page, $key, null); 19 | 20 | } 21 | 22 | /** 23 | * Get formatted date fields 24 | * 25 | * @param string $format 26 | * @param string $field 27 | * @return string 28 | */ 29 | public function date($format = null, $field = 'date') { 30 | 31 | if($timestamp = strtotime($this->get($field))) { 32 | if(is_null($format)) { 33 | return $timestamp; 34 | } else { 35 | return kirby()->options['date.handler']($format, $timestamp); 36 | } 37 | } 38 | 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /sample/kirby/branches/multilang.php: -------------------------------------------------------------------------------- 1 | __DIR__ . DS . 'multilang' . DS . 'content.php', 22 | 'file' => __DIR__ . DS . 'multilang' . DS . 'file.php', 23 | 'language' => __DIR__ . DS . 'multilang' . DS . 'language.php', 24 | 'languages' => __DIR__ . DS . 'multilang' . DS . 'languages.php', 25 | 'page' => __DIR__ . DS . 'multilang' . DS . 'page.php', 26 | 'site' => __DIR__ . DS . 'multilang' . DS . 'site.php', 27 | )); -------------------------------------------------------------------------------- /sample/panel/app/fields/radio/radio.php: -------------------------------------------------------------------------------- 1 | options(); 10 | if(is_array($options)) { 11 | reset($options); 12 | $value = key($options); 13 | } 14 | } 15 | return $value; 16 | } 17 | 18 | public function input() { 19 | 20 | $val = func_get_arg(0); 21 | $input = parent::input(); 22 | $input->addClass('radio'); 23 | $input->attr('type', 'radio'); 24 | $input->val($val); 25 | 26 | if($this->readonly) { 27 | $input->attr('disabled', true); 28 | } 29 | 30 | $input->attr('checked', $val == $this->value()); 31 | return $input; 32 | 33 | } 34 | 35 | public function item($value, $text) { 36 | $item = parent::item($value, $text); 37 | $item->addClass('input-with-radio'); 38 | return $item; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /sample/panel/app/forms/pages/url.php: -------------------------------------------------------------------------------- 1 | 'btn btn-icon label-option', 8 | 'href' => '#', 9 | 'data-title' => str::slug($page->title()) 10 | )); 11 | 12 | // url preview 13 | $preview = new Brick('div', '', array('class' => 'uid-preview')); 14 | $preview->append(ltrim($page->parent()->uri() . '/', '/')); 15 | $preview->append('' . $page->slug() . ''); 16 | 17 | // create the form 18 | $form = new Kirby\Panel\Form(array( 19 | 'uid' => array( 20 | 'label' => l('pages.url.uid.label') . $option, 21 | 'type' => 'text', 22 | 'icon' => 'chain', 23 | 'autofocus' => true, 24 | 'help' => $preview, 25 | 'default' => $page->slug() 26 | ) 27 | )); 28 | 29 | $form->buttons->submit->val(l('change')); 30 | $form->cancel($page); 31 | 32 | return $form; 33 | 34 | }; -------------------------------------------------------------------------------- /sample/kirby/branches/multilang/content.php: -------------------------------------------------------------------------------- 1 | site()->languages->codes()) . '))$!'; 20 | $this->name = preg_replace($expression, '', $this->name); 21 | */ 22 | 23 | $this->name = f::name($this->name); 24 | 25 | } 26 | 27 | public function language() { 28 | 29 | if(!is_null($this->language)) return $this->language; 30 | 31 | $codes = $this->page->site()->languages()->codes(); 32 | $code = f::extension(f::name($this->root)); 33 | 34 | return $this->language = in_array($code, $codes) ? $this->page->site()->languages()->find($code) : false; 35 | 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /sample/panel/app/fields/input/input.php: -------------------------------------------------------------------------------- 1 | addClass('input'); 11 | $input->attr(array( 12 | 'type' => $this->type(), 13 | 'value' => '', 14 | 'required' => $this->required(), 15 | 'name' => $this->name(), 16 | 'autocomplete' => $this->autocomplete() === false ? 'off' : 'on', 17 | 'autofocus' => $this->autofocus(), 18 | 'placeholder' => $this->i18n($this->placeholder()), 19 | 'readonly' => $this->readonly(), 20 | 'disabled' => $this->disabled(), 21 | 'id' => $this->id() 22 | )); 23 | 24 | if(!is_array($this->value())) { 25 | $input->val(html($this->value(), false)); 26 | } 27 | 28 | if($this->readonly()) { 29 | $input->attr('tabindex', '-1'); 30 | $input->addClass('input-is-readonly'); 31 | } 32 | 33 | return $input; 34 | 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /sample/panel/app/fields/structure/styles/table.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | fields() as $f): ?> 5 | 8 | 9 | 12 | 13 | 14 | 15 | entries() as $entry): ?> 16 | 17 | fields() as $f): ?> 18 | 23 | 24 | 29 | 30 | 31 | 32 |
    6 | 7 | 10 |   11 |
    19 | 20 | {$f['name']}, false) ?> 21 | 22 | 25 | 26 | 27 | 28 |
    -------------------------------------------------------------------------------- /sample/panel/app/fields/number/number.php: -------------------------------------------------------------------------------- 1 | type = 'number'; 8 | $this->label = l::get('fields.number.label', 'Number'); 9 | $this->placeholder = l::get('fields.number.placeholder', '#'); 10 | $this->step = 1; 11 | $this->min = 0; 12 | $this->max = false; 13 | 14 | } 15 | 16 | public function input() { 17 | $input = parent::input(); 18 | $input->attr('step', $this->step); 19 | $input->attr('min', $this->min); 20 | $input->attr('max', $this->max); 21 | return $input; 22 | } 23 | 24 | public function validate() { 25 | 26 | if(!v::num($this->result())) return false; 27 | 28 | if($this->validate and is_array($this->validate)) { 29 | return parent::validate(); 30 | } else { 31 | if($this->min and !v::min($this->result(), $this->min)) return false; 32 | if($this->max and !v::max($this->result(), $this->max)) return false; 33 | } 34 | 35 | return true; 36 | 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /sample/panel/app/views/search/results.php: -------------------------------------------------------------------------------- 1 | count()): ?> 2 |
    3 | 16 |
    17 | 18 | 19 | count()): ?> 20 |
    21 | 34 |
    35 | -------------------------------------------------------------------------------- /sample/panel/app/controllers/options.php: -------------------------------------------------------------------------------- 1 | site(); 9 | $sidebar = $site->sidebar(); 10 | $form = $site->form('edit', function($form) use($site, $self) { 11 | 12 | // validate all fields 13 | $form->validate(); 14 | 15 | // stop at invalid fields 16 | if(!$form->isValid()) { 17 | return $self->alert(l('pages.show.error.form')); 18 | } 19 | 20 | try { 21 | $site->update($form->serialize()); 22 | $self->notify(':)'); 23 | return $self->redirect('options'); 24 | } catch(Exception $e) { 25 | return $self->alert($e->getMessage()); 26 | } 27 | 28 | }); 29 | 30 | return $this->screen('options/index', $site, array( 31 | 'site' => $site, 32 | 'form' => $form, 33 | 'files' => $sidebar->files(), 34 | 'license' => panel()->license(), 35 | 'uploader' => $this->snippet('uploader', array('url' => $site->url('upload'))) 36 | )); 37 | 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /sample/site/templates/project.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |
    4 | 5 |

    title()->html() ?>

    6 | 7 |
      8 |
    • Year:
    • 9 |
    • Tags: tags() ?>
    • 10 |
    11 | 12 |
    13 | text()->kirbytext() ?> 14 | 15 | images()->sortBy('sort', 'asc') as $image): ?> 16 |
    17 | <?php echo $page->title()->html() ?> 18 |
    19 | 20 |
    21 | 22 | 30 | 31 |
    32 | 33 | -------------------------------------------------------------------------------- /sample/panel/app/src/panel/roots.php: -------------------------------------------------------------------------------- 1 | panel = $panel; 14 | $this->index = $root; 15 | $this->app = $root . DS . 'app'; 16 | $this->assets = $root . DS . 'assets'; 17 | 18 | $this->config = $this->app . DS . 'config'; 19 | $this->controllers = $this->app . DS . 'controllers'; 20 | $this->collections = $this->app . DS . 'collections'; 21 | $this->models = $this->app . DS . 'models'; 22 | $this->fields = $this->app . DS . 'fields'; 23 | $this->forms = $this->app . DS . 'forms'; 24 | $this->translations = $this->app . DS . 'translations'; 25 | $this->widgets = $this->app . DS . 'widgets'; 26 | $this->layouts = $this->app . DS . 'layouts'; 27 | $this->lib = $this->app . DS . 'lib'; 28 | $this->topbars = $this->app . DS . 'topbars'; 29 | $this->snippets = $this->app . DS . 'snippets'; 30 | $this->views = $this->app . DS . 'views'; 31 | 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /sample/panel/app/fields/checkboxes/checkboxes.php: -------------------------------------------------------------------------------- 1 | replaceClass('radio', 'checkbox'); 10 | $input->attr(array( 11 | 'name' => $this->name() . '[]', 12 | 'type' => 'checkbox', 13 | 'value' => $value, 14 | 'checked' => ($this->value === 'all') ? true : in_array($value, (array)$this->value()), 15 | 'required' => false, 16 | )); 17 | 18 | return $input; 19 | 20 | } 21 | 22 | public function value() { 23 | 24 | $value = InputListField::value(); 25 | 26 | if(is_array($value)) { 27 | return $value; 28 | } else { 29 | return str::split($value, ','); 30 | } 31 | 32 | } 33 | 34 | public function result() { 35 | $result = parent::result(); 36 | return is_array($result) ? implode(', ', $result) : null; 37 | } 38 | 39 | public function item($value, $text) { 40 | $item = parent::item($value, $text); 41 | $item->replaceClass('input-with-radio', 'input-with-checkbox'); 42 | return $item; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /sample/panel/app/snippets/subpages/subpage.php: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 | title()) ?> 5 |
    6 |
    7 | 29 |
    -------------------------------------------------------------------------------- /sample/panel/app/src/panel/controllers/field.php: -------------------------------------------------------------------------------- 1 | model = $model; 12 | $this->field = $field; 13 | $this->fieldname = $field->name(); 14 | } 15 | 16 | public function form($id, $data = array(), $submit = null) { 17 | $file = $this->field->root() . DS . 'forms' . DS . $id . '.php'; 18 | return panel()->form($file, $data, $submit); 19 | } 20 | 21 | public function view($file, $data = array()) { 22 | 23 | $view = new View($file, $data); 24 | $root = $this->field->root() . DS . 'views'; 25 | 26 | if(file_exists($root . DS . $file . '.php')) { 27 | $view->_root = $root; 28 | } 29 | 30 | return $view; 31 | 32 | } 33 | 34 | public function snippet($file, $data = array()) { 35 | 36 | $snippet = new Snippet($file, $data); 37 | $root = $this->field->root() . DS . 'snippets'; 38 | 39 | if(file_exists($root . DS . $file . '.php')) { 40 | $snippet->_root = $root; 41 | } 42 | 43 | return $snippet; 44 | 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /sample/panel/app/src/panel/models/page/blueprint/fields.php: -------------------------------------------------------------------------------- 1 | $field) { 15 | 16 | // sanitize the name 17 | $name = str_replace('-','_', str::lower($name)); 18 | 19 | // import a field by name 20 | if(is_string($field)) { 21 | $field = array( 22 | 'name' => $name, 23 | 'extends' => $field 24 | ); 25 | } 26 | 27 | // add the name to the field 28 | $field['name'] = $name; 29 | 30 | // create the field object 31 | $field = new Field($field, $model); 32 | 33 | // append it to the collection 34 | $this->append($name, $field); 35 | 36 | } 37 | 38 | } 39 | 40 | public function toArray($callback = null) { 41 | $result = array(); 42 | foreach($this->data as $field) { 43 | $result[$field->name()] = $field->toArray(); 44 | } 45 | return $result; 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /sample/panel/app/controllers/avatars.php: -------------------------------------------------------------------------------- 1 | user($username); 8 | 9 | try { 10 | $user->avatar()->upload(); 11 | $this->notify(':)'); 12 | } catch(Exception $e) { 13 | $this->alert($e->getMessage()); 14 | } 15 | 16 | $this->redirect($user); 17 | 18 | } 19 | 20 | public function delete($username) { 21 | 22 | $self = $this; 23 | $user = $this->user($username); 24 | $avatar = $user->avatar(); 25 | 26 | if(!$avatar->exists()) { 27 | return $this->modal('error', array( 28 | 'text' => l('users.avatar.missing'), 29 | 'back' => $user->url() 30 | )); 31 | } 32 | 33 | $form = $avatar->form('delete', function($form) use($user, $avatar, $self) { 34 | 35 | try { 36 | $avatar->delete(); 37 | $self->notify(':)'); 38 | $self->redirect($user); 39 | } catch(Exception $e) { 40 | $form->alert($e->getMessage()); 41 | } 42 | 43 | }); 44 | 45 | return $this->modal('avatars/delete', compact('form')); 46 | 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /sample/panel/app/snippets/pages/sidebar/files.php: -------------------------------------------------------------------------------- 1 |

    2 | 3 | isSite(), l('metatags.files'), l('pages.show.files.title')) ?> 4 | 5 | 6 | 7 | 8 | 9 | 10 | canHaveMoreFiles()) : ?> 11 | 12 | 13 | 14 | 15 | 16 | 17 |

    18 | 19 | count()): ?> 20 | 25 | 26 |

    27 | -------------------------------------------------------------------------------- /sample/kirby/toolkit/lib/silo.php: -------------------------------------------------------------------------------- 1 | 12 | * @link http://getkirby.com 13 | * @copyright Bastian Allgeier 14 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 15 | */ 16 | class Silo { 17 | 18 | public static $data = array(); 19 | 20 | public static function set($key, $value = null) { 21 | if(is_array($key)) { 22 | return static::$data = array_merge(static::$data, $key); 23 | } else { 24 | return static::$data[$key] = $value; 25 | } 26 | } 27 | 28 | public static function get($key = null, $default = null) { 29 | if(empty($key)) return static::$data; 30 | return isset(static::$data[$key]) ? static::$data[$key] : $default; 31 | } 32 | 33 | public static function remove($key = null) { 34 | // reset the entire array 35 | if(is_null($key)) return static::$data = array(); 36 | // unset a single key 37 | unset(static::$data[$key]); 38 | // return the array without the removed key 39 | return static::$data; 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /sample/panel/app/fields/textarea/views/email.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /sample/panel/app/src/panel/collections/files.php: -------------------------------------------------------------------------------- 1 | kirby = $page->kirby; 12 | $this->site = $page->site; 13 | $this->page = $page; 14 | 15 | // make sure the inventory is always fresh 16 | $this->page->reset(); 17 | 18 | $inventory = $page->inventory(); 19 | 20 | foreach($inventory['files'] as $filename) { 21 | $file = new File($this, $filename); 22 | $this->data[strtolower($file->filename())] = $file; 23 | } 24 | 25 | if($this->page->canSortFiles()) { 26 | $sorted = $this->sortBy('sort', 'asc'); 27 | $this->data = $sorted->data; 28 | } 29 | 30 | if($this->page->blueprint()->files()->sort() == 'flip') { 31 | $flipped = $this->flip(); 32 | $this->data = $flipped->data; 33 | } 34 | 35 | } 36 | 37 | public function topbar($topbar) { 38 | 39 | $page = $this->page(); 40 | 41 | if($page->isSite()) { 42 | $topbar->append(purl('options'), l('metatags')); 43 | } 44 | 45 | $page->topbar($topbar); 46 | 47 | $topbar->append($page->url('files'), l('files')); 48 | 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /sample/panel/app/forms/files/edit.php: -------------------------------------------------------------------------------- 1 | type(); 9 | $info[] = $file->niceSize(); 10 | 11 | if((string)$file->dimensions() != '0 x 0') { 12 | $info[] = $file->dimensions(); 13 | } 14 | 15 | // setup the default fields 16 | $fields = array( 17 | '_name' => array( 18 | 'label' => 'files.show.name.label', 19 | 'type' => 'filename', 20 | 'extension' => $file->extension(), 21 | 'required' => true, 22 | 'default' => $file->name(), 23 | ), 24 | '_info' => array( 25 | 'label' => 'files.show.info.label', 26 | 'type' => 'text', 27 | 'readonly' => true, 28 | 'icon' => 'info', 29 | 'default' => implode(' / ', $info), 30 | ), 31 | '_link' => array( 32 | 'label' => 'files.show.link.label', 33 | 'type' => 'text', 34 | 'readonly' => true, 35 | 'icon' => 'chain', 36 | 'default' => $file->url() 37 | ) 38 | ); 39 | 40 | $form = new Kirby\Panel\Form(array_merge($fields, $file->getFormFields()), $file->getFormData()); 41 | 42 | $form->centered = true; 43 | $form->buttons->cancel = ''; 44 | 45 | return $form; 46 | 47 | }; -------------------------------------------------------------------------------- /sample/kirby/kirby/urls.php: -------------------------------------------------------------------------------- 1 | index)) return $this->index; 14 | 15 | if(r::cli()) { 16 | return $this->index = '/'; 17 | } else { 18 | return $this->index = url::base() . preg_replace('!\/index\.php$!i', '', server::get('SCRIPT_NAME')); 19 | } 20 | 21 | } 22 | 23 | public function content() { 24 | return isset($this->content) ? $this->content : url::makeAbsolute('content', $this->index); 25 | } 26 | 27 | public function thumbs() { 28 | return isset($this->thumbs) ? $this->thumbs : url::makeAbsolute('thumbs', $this->index); 29 | } 30 | 31 | public function assets() { 32 | return isset($this->assets) ? $this->assets : url::makeAbsolute('assets', $this->index); 33 | } 34 | 35 | public function autocss() { 36 | return isset($this->autocss) ? $this->autocss : $this->assets() . '/css/templates'; 37 | } 38 | 39 | public function autojs() { 40 | return isset($this->autojs) ? $this->autojs : $this->assets() . '/js/templates'; 41 | } 42 | 43 | public function avatars() { 44 | return isset($this->avatars) ? $this->avatars : $this->assets() . '/avatars'; 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /sample/kirby/toolkit/lib/password.php: -------------------------------------------------------------------------------- 1 | 10 | * @link http://getkirby.com 11 | * @copyright Bastian Allgeier 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | class Password { 15 | 16 | /** 17 | * Generates a salted hash for a plaintext password 18 | * 19 | * @param string $plaintext 20 | * @return string 21 | */ 22 | public static function hash($plaintext) { 23 | $salt = substr(str_replace('+', '.', base64_encode(sha1(str::random(), true))), 0, 22); 24 | return crypt($plaintext, '$2a$10$' . $salt); 25 | } 26 | 27 | /** 28 | * Checks if a given string is already a hash 29 | * 30 | * @param string 31 | * @return boolean 32 | */ 33 | public static function isHash($hash) { 34 | return preg_match('!^\$2a\$10\$!', $hash); 35 | } 36 | 37 | /** 38 | * Checks if a password matches the encrypted hash 39 | * 40 | * @param string $plaintext 41 | * @param string $hash 42 | * @return boolean 43 | */ 44 | public static function match($plaintext, $hash) { 45 | return crypt($plaintext, $hash) === $hash; 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /sample/panel/app/controllers/auth.php: -------------------------------------------------------------------------------- 1 | isAuthenticated()) { 12 | $this->redirect(); 13 | } 14 | 15 | if($login->isBlocked()) { 16 | return $this->layout('base', array( 17 | 'content' => $this->view('auth/block') 18 | )); 19 | } 20 | 21 | $self = $this; 22 | $form = $this->form('auth/login', null, function($form) use($self, $login) { 23 | 24 | $data = $form->serialize(); 25 | 26 | try { 27 | $login->attempt($data['username'], $data['password']); 28 | $self->redirect(); 29 | } catch(Exception $e) { 30 | $form->alert(l('login.error')); 31 | $form->fields->username->error = true; 32 | $form->fields->password->error = true; 33 | } 34 | 35 | }); 36 | 37 | return $this->layout('base', array( 38 | 'bodyclass' => 'login', 39 | 'content' => $this->view('auth/login', compact('form')) 40 | )); 41 | 42 | } 43 | 44 | public function logout() { 45 | 46 | if($user = panel()->user()) { 47 | $user->logout(); 48 | } 49 | 50 | $this->redirect('login'); 51 | 52 | } 53 | 54 | } -------------------------------------------------------------------------------- /sample/panel/app/forms/pages/add.php: -------------------------------------------------------------------------------- 1 | blueprint()->pages()->template() as $template) { 8 | $options[$template->name()] = $template->title(); 9 | } 10 | 11 | $form = new Kirby\Panel\Form(array( 12 | 'title' => array( 13 | 'label' => 'pages.add.title.label', 14 | 'type' => 'title', 15 | 'placeholder' => 'pages.add.title.placeholder', 16 | 'autocomplete' => false, 17 | 'autofocus' => true, 18 | 'required' => true 19 | ), 20 | 'uid' => array( 21 | 'label' => 'pages.add.url.label', 22 | 'type' => 'text', 23 | 'icon' => 'chain', 24 | 'autocomplete' => false, 25 | 'required' => true, 26 | ), 27 | 'template' => array( 28 | 'label' => 'pages.add.template.label', 29 | 'type' => 'select', 30 | 'options' => $options, 31 | 'default' => key($options), 32 | 'required' => true, 33 | 'readonly' => count($options) == 1 ? true : false, 34 | 'icon' => count($options) == 1 ? 'file-o' : 'chevron-down', 35 | ) 36 | )); 37 | 38 | $form->cancel($page->isSite() ? '/' : $page); 39 | 40 | $form->buttons->submit->val(l('add')); 41 | 42 | return $form; 43 | 44 | }; -------------------------------------------------------------------------------- /sample/.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 | # block text files in the content folder from being accessed directly 20 | RewriteRule ^content/(.*)\.(txt|md|mdown)$ index.php [L] 21 | 22 | # block all files in the site folder from being accessed directly 23 | RewriteRule ^site/(.*) index.php [L] 24 | 25 | # block all files in the kirby folder from being accessed directly 26 | RewriteRule ^kirby/(.*) index.php [L] 27 | 28 | # make panel links work 29 | RewriteCond %{REQUEST_FILENAME} !-f 30 | RewriteCond %{REQUEST_FILENAME} !-d 31 | RewriteRule ^panel/(.*) panel/index.php [L] 32 | 33 | # make site links work 34 | RewriteCond %{REQUEST_FILENAME} !-f 35 | RewriteCond %{REQUEST_FILENAME} !-d 36 | RewriteRule ^(.*) index.php [L] 37 | 38 | 39 | 40 | # Additional recommended values 41 | # Remove comments for those you want to use. 42 | # 43 | # AddDefaultCharset UTF-8 44 | # 45 | # php_flag short_open_tag on -------------------------------------------------------------------------------- /sample/kirby/core/field.php: -------------------------------------------------------------------------------- 1 | 8 | * @link http://getkirby.com 9 | * @copyright Bastian Allgeier 10 | * @license http://getkirby.com/license 11 | */ 12 | abstract class FieldAbstract { 13 | 14 | static public $methods = array(); 15 | 16 | public $page; 17 | public $key; 18 | public $value; 19 | 20 | public function __construct($page, $key, $value = '') { 21 | $this->page = $page; 22 | $this->key = $key; 23 | $this->value = $value; 24 | } 25 | 26 | public function page() { 27 | return $this->page; 28 | } 29 | public function exists() { 30 | return $this->page->content()->has($this->key); 31 | } 32 | public function key() { 33 | return $this->key; 34 | } 35 | public function value() { 36 | return $this->value; 37 | } 38 | public function __toString() { 39 | return (string)$this->value; 40 | } 41 | public function toString() { 42 | return $this->value; 43 | } 44 | public function __call($method, $arguments = array()) { 45 | if(isset(static::$methods[$method])) { 46 | array_unshift($arguments, clone $this); 47 | return call(static::$methods[$method], $arguments); 48 | } else { 49 | return $this; 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /sample/panel/app/fields/date/assets/js/date.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 3 | $.fn.date = function() { 4 | 5 | return this.each(function() { 6 | 7 | if($(this).data('pikaday')) { 8 | return $(this); 9 | } 10 | 11 | var input = $(this).attr('type', 'text'); 12 | var hidden = input.next(); 13 | var format = input.data('format'); 14 | var val = input.val(); 15 | var date = val ? moment(val).format(format) : null; 16 | 17 | input.attr('placeholder', format); 18 | input.val(date); 19 | 20 | // don't initialize the datepicker on readonly fields 21 | if(input.is('[readonly]')) { 22 | return false; 23 | } 24 | 25 | input.on('change', function() { 26 | var val = input.val(); 27 | if(val) { 28 | hidden.val(moment(val, format).format('YYYY-MM-DD')); 29 | } else { 30 | hidden.val(''); 31 | } 32 | }); 33 | 34 | var pikaday = new Pikaday({ 35 | field : this, 36 | firstDay : 1, 37 | format : format, 38 | i18n : input.data('i18n'), 39 | onSelect : function(date) { 40 | hidden.val(moment(date).format('YYYY-MM-DD')); 41 | } 42 | }); 43 | 44 | $(this).data('pikaday', pikaday); 45 | 46 | }); 47 | 48 | }; 49 | 50 | })(jQuery); -------------------------------------------------------------------------------- /sample/panel/app/fields/checkbox/checkbox.php: -------------------------------------------------------------------------------- 1 | addClass('checkbox'); 9 | $input->attr(array( 10 | 'id' => $this->id(), 11 | 'name' => $this->name(), 12 | 'required' => $this->required(), 13 | 'autofocus' => $this->autofocus(), 14 | 'autocomplete' => $this->autocomplete(), 15 | 'readonly' => $this->readonly(), 16 | 'type' => 'checkbox', 17 | 'checked' => v::accepted($this->value()), 18 | )); 19 | 20 | $wrapper = parent::input(); 21 | $wrapper->tag('label'); 22 | $wrapper->text($this->i18n($this->text())); 23 | $wrapper->attr('for', $this->id()); 24 | $wrapper->removeAttr('id'); 25 | $wrapper->addClass('input-with-checkbox'); 26 | $wrapper->prepend($input); 27 | 28 | return $wrapper; 29 | 30 | } 31 | 32 | public function value() { 33 | $value = parent::value(); 34 | return empty($value) ? '0' : $value; 35 | } 36 | 37 | public function result() { 38 | $result = parent::result(); 39 | return v::accepted($result) ? '1' : '0'; 40 | } 41 | 42 | public function validate() { 43 | return v::accepted($this->value()) or v::denied($this->value()); 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /sample/panel/app/forms/pages/toggle.php: -------------------------------------------------------------------------------- 1 | parent(); 6 | $blueprint = $parent->blueprint(); 7 | $siblings = $parent->children()->visible(); 8 | 9 | // sorting needed 10 | if($blueprint->pages()->num()->mode() == 'default' and $siblings->count() > 0) { 11 | 12 | $options = array('' => l('pages.toggle.invisible'), '-' => '-'); 13 | $n = 1; 14 | 15 | foreach($siblings as $sibling) { 16 | $options[$n] = $n; 17 | $n++; 18 | } 19 | 20 | if($page->isInvisible()) { 21 | $options[$n] = $n; 22 | } 23 | 24 | $form = new Kirby\Panel\Form(array( 25 | 'position' => array( 26 | 'label' => l('pages.toggle.position'), 27 | 'type' => 'select', 28 | 'required' => true, 29 | 'default' => $page->num(), 30 | 'options' => $options 31 | ) 32 | )); 33 | 34 | } else { 35 | 36 | $form = new Kirby\Panel\Form(array( 37 | 'confirmation' => array( 38 | 'type' => 'info', 39 | 'text' => $page->isVisible() ? l('pages.toggle.hide') : l('pages.toggle.publish') 40 | ) 41 | )); 42 | 43 | } 44 | 45 | $form->buttons->submit->value = l('change'); 46 | $form->buttons->submit->autofocus = true; 47 | 48 | $form->cancel($page); 49 | 50 | return $form; 51 | 52 | }; -------------------------------------------------------------------------------- /sample/panel/app/fields/tags/tags.php: -------------------------------------------------------------------------------- 1 | icon = 'tag'; 8 | $this->label = l::get('fields.tags.label', 'Tags'); 9 | $this->index = 'siblings'; 10 | $this->separator = ','; 11 | $this->lower = false; 12 | 13 | } 14 | 15 | public function input() { 16 | 17 | $input = parent::input(); 18 | $input->addClass('input-with-tags'); 19 | $input->data(array( 20 | 'field' => 'tags', 21 | 'lowercase' => $this->lower ? 'true' : false, 22 | 'separator' => $this->separator, 23 | )); 24 | 25 | if(isset($this->data)) { 26 | 27 | $input->data('url', html(json_encode($this->data), false)); 28 | 29 | } else if($page = $this->page()) { 30 | 31 | empty($this->field) ? $field = $this->name() : $field = $this->field; 32 | 33 | $query = array( 34 | 'uri' => $page->id(), 35 | 'index' => $this->index(), 36 | 'field' => $field, 37 | 'yaml' => $this->parentField, 38 | 'separator' => $this->separator(), 39 | '_csrf' => panel()->csrf(), 40 | ); 41 | 42 | $input->data('url', panel()->urls()->api() . '/autocomplete/field?' . http_build_query($query)); 43 | 44 | } 45 | 46 | return $input; 47 | 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /sample/panel/app/src/panel/models/user/blueprint.php: -------------------------------------------------------------------------------- 1 | user = $user; 25 | 26 | // load from yaml file 27 | $this->load(); 28 | 29 | } 30 | 31 | public function load() { 32 | 33 | // get the user role and load the 34 | // correspondant blueprint if available 35 | $this->name = basename(strtolower($this->user->role())); 36 | 37 | // try to find a user blueprint 38 | $file = f::resolve(static::$root . DS . $this->name, array('yml', 'php', 'yaml')); 39 | 40 | if($file) { 41 | $this->file = $file; 42 | $this->yaml = data::read($this->file, 'yaml'); 43 | 44 | // remove the broken first line 45 | unset($this->yaml[0]); 46 | } 47 | 48 | } 49 | 50 | public function fields() { 51 | $fields = (array)a::get($this->yaml, 'fields', array()); 52 | return new Fields($fields, $this->user); 53 | } 54 | 55 | public function __toString() { 56 | return $this->name; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /sample/kirby/toolkit/lib/yaml.php: -------------------------------------------------------------------------------- 1 | 10 | * @link http://getkirby.com 11 | * @copyright Bastian Allgeier 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | class Yaml { 15 | 16 | /** 17 | * Creates a new yaml string from an array 18 | * 19 | * @param array $array 20 | * @return string 21 | */ 22 | public static function encode($array) { 23 | return preg_replace('!^---\n!', '', spyc::yamldump($array)); 24 | } 25 | 26 | /** 27 | * Creates a new yaml file from an array 28 | * 29 | * @param string $file 30 | * @param array $array 31 | * @return boolean 32 | */ 33 | public static function write($file, $array) { 34 | return f::write($file, static::encode($array)); 35 | } 36 | 37 | /** 38 | * Parses a yaml string and returns the array 39 | * 40 | * @param string $yaml 41 | * @return array 42 | */ 43 | public static function decode($yaml) { 44 | return spyc::yamlload($yaml); 45 | } 46 | 47 | /** 48 | * Reads and parses a yaml file and returns the array 49 | * 50 | * @param string $file 51 | * @return array 52 | */ 53 | public static function read($file) { 54 | return spyc::yamlload($file); 55 | } 56 | 57 | } -------------------------------------------------------------------------------- /sample/panel/app/fields/textarea/views/link.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /sample/panel/index.php: -------------------------------------------------------------------------------- 1 | urls->index)) { 27 | $kirby->urls->index = dirname($kirby->url()); 28 | } 29 | 30 | // the default index directory 31 | if(!isset($kirby->roots->index)) { 32 | $kirby->roots->index = $index; 33 | } 34 | 35 | // the default avatar directory 36 | if(!isset($kirby->roots->avatars)) { 37 | $kirby->roots->avatars = $index . DS . 'assets' . DS . 'avatars'; 38 | } 39 | 40 | // the default thumbs directory 41 | if(!isset($kirby->roots->thumbs)) { 42 | $kirby->roots->thumbs = $index . DS . 'thumbs'; 43 | } 44 | 45 | try { 46 | 47 | // create the panel object 48 | $panel = new Panel($kirby, __DIR__); 49 | 50 | // launch the panel 51 | echo $panel->launch(); 52 | 53 | } catch(Exception $e) { 54 | echo Panel::fatal($e, __DIR__); 55 | } -------------------------------------------------------------------------------- /sample/panel/app/fields/structure/assets/js/structure.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 3 | var Structure = function(el) { 4 | 5 | var element = $(el); 6 | var style = element.data('style'); 7 | var api = element.data('api'); 8 | var sortable = element.data('sortable'); 9 | var entries = style == 'table' ? element.find('.structure-table tbody') : element.find('.structure-entries'); 10 | 11 | if(sortable === false) return false; 12 | 13 | entries.sortable({ 14 | helper: function(e, ui) { 15 | ui.children().each(function() { 16 | $(this).width($(this).width()); 17 | }); 18 | return ui.addClass('structure-sortable-helper'); 19 | }, 20 | update: function() { 21 | 22 | var ids = []; 23 | 24 | $.each($(this).sortable('toArray'), function(i, id) { 25 | ids.push(id.replace('structure-entry-', '')); 26 | }); 27 | 28 | $.post(api, {ids: ids}, function() { 29 | app.content.reload(); 30 | }); 31 | 32 | } 33 | }); 34 | 35 | }; 36 | 37 | $.fn.structure = function() { 38 | 39 | return this.each(function() { 40 | 41 | if($(this).data('structure')) { 42 | return $(this); 43 | } else { 44 | var structure = new Structure(this); 45 | $(this).data('structure', structure); 46 | return $(this); 47 | } 48 | 49 | }); 50 | 51 | }; 52 | 53 | })(jQuery); -------------------------------------------------------------------------------- /sample/kirby/toolkit/lib/exif/camera.php: -------------------------------------------------------------------------------- 1 | 10 | * @link http://getkirby.com 11 | * @copyright Bastian Allgeier 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | class Camera { 15 | 16 | protected $make; 17 | protected $model; 18 | 19 | /** 20 | * Constructor 21 | * 22 | * @param array $exif 23 | */ 24 | public function __construct($exif) { 25 | $this->make = @$exif['Make']; 26 | $this->model = @$exif['Model']; 27 | } 28 | 29 | /** 30 | * Returns the make of the camera 31 | * 32 | * @return string 33 | */ 34 | public function make() { 35 | return $this->make; 36 | } 37 | 38 | /** 39 | * Returns the camera model 40 | * 41 | * @return string 42 | */ 43 | public function model() { 44 | return $this->model; 45 | } 46 | 47 | /** 48 | * Converts the object into a nicely readable array 49 | * 50 | * @return array 51 | */ 52 | public function toArray() { 53 | return array( 54 | 'make' => $this->make, 55 | 'model' => $this->model 56 | ); 57 | } 58 | 59 | /** 60 | * Returns the full make + model name 61 | * 62 | * @return string 63 | */ 64 | public function __toString() { 65 | return trim($this->make . ' ' . $this->model); 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /sample/panel/assets/js/dist/app.min.js: -------------------------------------------------------------------------------- 1 | var app={setup:function(){NProgress.configure({showSpinner:!1}),app.delay=Delay(),app.content=Content(app),app.content.setup(),app.modal=Modal(app),app.modal.setup(),new Context,new Search,$.ajaxPrefilter(function(t,a,e){a.type&&"post"==a.type.toLowerCase()&&(t.data=$.param($.extend(a.data,{csrf:$("body").attr("data-csrf")})))}),$(document).on("click","a",function(t){var a=$(this),e=a.attr("href")||"";return a.is("[data-dropdown]")||e.match(/^#/)?!0:a.is("[data-modal]")?(app.modal.open(a.attr("href")),!1):a.is("[target]")?!0:(app.content.open(e),!1)}),$(document).on("keydown",function(t){switch(t.keyCode){case 83:case 13:return t.metaKey||t.ctrlKey?(app.hasModal()||app.content.form().trigger("submit"),!1):!0;case 27:return app.modal.close(),!1}}),$(document).dropdown()},hasModal:function(){return $(".modal-content").length>0},load:function(t,a,e){if(app.isLoading(!0),"modal"==a)var o={modal:!0};else var o=!1;$.ajax({url:t,method:"GET",headers:o}).success(function(a,o,n){if(app.isLoading(!1),"object"!==$.type(a)||!a.user||!a.direction)return window.location.href=t;document.title=a.title;var r=$("body");r.hasClass(a.direction)||("ltr"==a.direction?r.removeClass("rtl").addClass("ltr"):r.removeClass("ltr").addClass("rtl"));try{e(a)}catch(d){window.location.href=t}}).error(function(){window.location.href=t})},csrf:function(){return $("body").attr("data-csrf")},isLoading:function(t){t?app.delay.start("loader",function(){NProgress.start()},250):(app.delay.stop("loader"),NProgress.done())}};$(function(){app.setup()}); -------------------------------------------------------------------------------- /sample/content/1-about/about.txt: -------------------------------------------------------------------------------- 1 | Title: About 2 | 3 | ---- 4 | 5 | Text: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. 6 | 7 | ## Lorem Ipsum 8 | In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a. 9 | 10 | (image: about.jpg) 11 | 12 | ### Lorem Ipsum 13 | In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. 14 | 15 | #### Lorem Ipsum 16 | In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. -------------------------------------------------------------------------------- /sample/panel/app/fields/time/time.php: -------------------------------------------------------------------------------- 1 | icon = 'clock-o'; 11 | $this->interval = 60; 12 | $this->format = 24; 13 | } 14 | 15 | public function interval() { 16 | if($this->interval <= 0) { 17 | $this->interval = 60; 18 | } 19 | return $this->interval; 20 | } 21 | 22 | public function value() { 23 | 24 | if($this->override()) { 25 | $value = $this->default(); 26 | } else { 27 | $value = parent::value(); 28 | } 29 | 30 | if(!empty($value)) { 31 | 32 | if($value == 'now') { 33 | $value = date($this->format(), time()); 34 | } 35 | 36 | $time = round((strtotime($value) - strtotime('00:00')) / ($this->interval() * 60)) * ($this->interval() * 60) + strtotime('00:00'); 37 | $value = date($this->format(), $time); 38 | 39 | } 40 | 41 | return $value; 42 | 43 | } 44 | 45 | public function format() { 46 | return $this->format == 12 ? 'h:i A' : 'H:i'; 47 | } 48 | 49 | public function options() { 50 | 51 | $time = strtotime('00:00'); 52 | $end = strtotime('23:59'); 53 | $options = array(); 54 | $format = $this->format(); 55 | 56 | while($time < $end) { 57 | 58 | $now = date($format, $time); 59 | $time += 60 * $this->interval(); 60 | 61 | $options[$now] = $now; 62 | 63 | } 64 | 65 | return $options; 66 | 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /sample/panel/app/snippets/pages/sidebar/subpages.php: -------------------------------------------------------------------------------- 1 |

    2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | modal(), ' data-modal') ?> href="url()) ?>"> 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |

    20 | 21 | count()): ?> 22 | 27 | 28 | 29 | 30 | 31 |

    32 | 33 | 34 | modal(), ' data-modal') ?> href="url()) ?>"> 35 | 36 | 37 | 38 | 39 | 40 | 41 |

    42 | -------------------------------------------------------------------------------- /sample/panel/app/helpers.php: -------------------------------------------------------------------------------- 1 | '; 9 | } 10 | 11 | function i($icon, $position = null) { 12 | echo icon($icon, $position); 13 | } 14 | 15 | function __($var) { 16 | echo htmlspecialchars($var); 17 | } 18 | 19 | function _l($key, $default = null) { 20 | echo htmlspecialchars(l($key, $default)); 21 | } 22 | 23 | function _u($obj = '', $action = false) { 24 | echo purl($obj, $action); 25 | } 26 | 27 | function purl($obj = '/', $action = false) { 28 | 29 | if(empty($obj) or is_string($obj)) { 30 | $base = panel()->urls()->index(); 31 | return ($obj == '/' or empty($obj)) ? $base . '/' : rtrim($base . '/' . $obj, '/'); 32 | } else if(is_a($obj, 'Kirby\\Panel\\Models\\Site')) { 33 | return $obj->url(!$action ? 'edit' : $action); 34 | } else if(is_a($obj, 'Kirby\\Panel\\Models\\Page')) { 35 | return $obj->url(!$action ? 'edit' : $action); 36 | } else if(is_a($obj, 'Kirby\\Panel\\Models\\File')) { 37 | return $obj->url(!$action ? 'edit' : $action); 38 | } else if(is_a($obj, 'Kirby\\Panel\\Models\\User')) { 39 | return $obj->url(!$action ? 'edit' : $action); 40 | } 41 | 42 | } 43 | 44 | function slugTable() { 45 | $table = array(); 46 | foreach(str::$ascii as $key => $value) { 47 | $key = trim($key, '/'); 48 | foreach(str::split($key, '|') as $needle) { 49 | $table[$needle] = $value; 50 | } 51 | } 52 | 53 | return json_encode($table, JSON_UNESCAPED_UNICODE); 54 | } -------------------------------------------------------------------------------- /sample/panel/app/forms/pages/edit.php: -------------------------------------------------------------------------------- 1 | getFormFields(), $page->getFormData()); 9 | 10 | // add the blueprint name as css class 11 | $form->addClass('form-blueprint-' . $page->blueprint()->name()); 12 | 13 | // center the submit button 14 | $form->centered = true; 15 | 16 | // set the keep api 17 | $form->data('keep', $page->url('keep')); 18 | 19 | // set the autofocus on the title field 20 | $form->fields->title->autofocus = true; 21 | 22 | // add the changes alert 23 | if($page->changes()->differ()) { 24 | 25 | // display unsaved changes 26 | $alert = new Brick('div'); 27 | $alert->addClass('text'); 28 | $alert->append('' . l('pages.show.changes.text') . ''); 29 | 30 | $form->buttons->prepend('changes', $alert); 31 | $form->buttons->cancel->attr('href', $page->url('discard')); 32 | $form->buttons->cancel->html(l('pages.show.changes.button')); 33 | 34 | // add wide buttons 35 | $form->buttons->cancel->addClass('btn-wide'); 36 | $form->buttons->submit->addClass('btn-wide'); 37 | 38 | } else { 39 | // remove the cancel button 40 | $form->buttons->cancel = ''; 41 | } 42 | 43 | // check for untranslatable fields 44 | if(panel()->site()->language() != panel()->site()->defaultLanguage()) { 45 | 46 | foreach($form->fields() as $field) { 47 | if($field->translate() == false) { 48 | $field->readonly = true; 49 | $field->disabled = true; 50 | } 51 | } 52 | 53 | } 54 | 55 | return $form; 56 | 57 | }; -------------------------------------------------------------------------------- /sample/kirby/toolkit/lib/cache/driver/mock.php: -------------------------------------------------------------------------------- 1 | 12 | * @link http://getkirby.com 13 | * @copyright Bastian Allgeier 14 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 15 | */ 16 | class Mock extends Driver { 17 | 18 | /** 19 | * Write an item to the cache for a given number of minutes. 20 | * 21 | * 22 | * // Put an item in the cache for 15 minutes 23 | * Cache::set('value', 'my value', 15); 24 | * 25 | * 26 | * @param string $key 27 | * @param mixed $value 28 | * @param int $minutes 29 | * @return void 30 | */ 31 | public function set($key, $value, $minutes = null) { 32 | return true; 33 | } 34 | 35 | /** 36 | * Retrieve an item from the cache. 37 | * 38 | * @param string $key 39 | * @return mixed 40 | */ 41 | public function retrieve($key) { 42 | return null; 43 | } 44 | 45 | /** 46 | * Checks if the current key exists in cache 47 | * 48 | * @param string $key 49 | * @return boolean 50 | */ 51 | public function exists($key) { 52 | return null; 53 | } 54 | 55 | /** 56 | * Remove an item from the cache 57 | * 58 | * @param string $key 59 | * @return boolean 60 | */ 61 | public function remove($key) { 62 | return true; 63 | } 64 | 65 | /** 66 | * Flush the entire cache directory 67 | * 68 | * @return boolean 69 | */ 70 | public function flush() { 71 | return true; 72 | } 73 | 74 | } -------------------------------------------------------------------------------- /sample/panel/app/fields/textarea/assets/js/editor.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 3 | $.fn.editor = function() { 4 | 5 | return this.each(function() { 6 | 7 | if($(this).data('editor')) { 8 | return $(this); 9 | } 10 | 11 | var textarea = $(this); 12 | var buttons = textarea.parent().find('.field-buttons'); 13 | 14 | // start autosizing 15 | textarea.autosize(); 16 | 17 | buttons.find('.btn').on('click.editorButton', function(e) { 18 | 19 | textarea.focus(); 20 | var button = $(this); 21 | 22 | if(button.data('action')) { 23 | app.modal.open(button.data('action'), window.location.href); 24 | } else { 25 | 26 | var sel = textarea.getSelection(); 27 | var tpl = button.data('tpl'); 28 | var text = button.data('text'); 29 | 30 | if(sel.length > 0) text = sel; 31 | 32 | var tag = tpl.replace('{text}', text); 33 | 34 | textarea.insertAtCursor(tag); 35 | textarea.trigger('autosize.resize'); 36 | 37 | } 38 | 39 | return false; 40 | 41 | }); 42 | 43 | buttons.find('[data-editor-shortcut]').each(function(i, el) { 44 | var key = $(this).data('editor-shortcut'); 45 | var action = function(e) { 46 | $(el).trigger('click'); 47 | return false; 48 | }; 49 | 50 | textarea.bind('keydown', key, action); 51 | 52 | if(key.match(/meta\+/)) { 53 | textarea.bind('keydown', key.replace('meta+', 'ctrl+'), action); 54 | } 55 | 56 | }); 57 | 58 | textarea.data('editor', true); 59 | 60 | }); 61 | 62 | }; 63 | 64 | })(jQuery); -------------------------------------------------------------------------------- /sample/panel/app/src/panel/installer.php: -------------------------------------------------------------------------------- 1 | users()->count() > 0 && is_writable(kirby()->roots()->accounts())); 12 | } 13 | 14 | public function problems() { 15 | 16 | $checks = array('accounts', 'thumbs', 'blueprints', 'content', 'avatars'); 17 | $problems = array(); 18 | 19 | foreach($checks as $c) { 20 | $method = 'check' . $c; 21 | 22 | if(!$this->$method()) { 23 | $problems[] = l('installation.check.error.' . $c); 24 | } 25 | 26 | } 27 | 28 | return empty($problems) ? false : $problems; 29 | 30 | } 31 | 32 | protected function checkAccounts() { 33 | 34 | $root = kirby()->roots()->accounts(); 35 | 36 | // try to create the accounts folder 37 | dir::make($root); 38 | 39 | return is_writable($root); 40 | 41 | } 42 | 43 | protected function checkThumbs() { 44 | 45 | $root = kirby()->roots()->thumbs(); 46 | 47 | // try to create the thumbs folder 48 | dir::make($root); 49 | 50 | return is_writable($root); 51 | 52 | } 53 | 54 | protected function checkBlueprints() { 55 | return is_dir(kirby()->roots()->blueprints()); 56 | } 57 | 58 | protected function checkContent() { 59 | $folder = new Folder(kirby()->roots()->content()); 60 | return $folder->isWritable(true); 61 | } 62 | 63 | protected function checkAvatars() { 64 | 65 | $root = kirby()->roots()->avatars(); 66 | 67 | // try to create the avatars folder 68 | dir::make($root); 69 | 70 | return is_writable($root); 71 | 72 | } 73 | 74 | } -------------------------------------------------------------------------------- /sample/panel/app/fields/date/date.php: -------------------------------------------------------------------------------- 1 | array( 9 | 'date.js' 10 | ) 11 | ); 12 | 13 | public function __construct() { 14 | 15 | $this->type = 'date'; 16 | $this->icon = 'calendar'; 17 | $this->label = l::get('fields.date.label', 'Date'); 18 | $this->format = 'YYYY-MM-DD'; 19 | 20 | } 21 | 22 | public function format() { 23 | $format = str::upper($this->format); 24 | return empty($format) ? 'YYYY-MM-DD' : $format; 25 | } 26 | 27 | public function validate() { 28 | return v::date($this->result()); 29 | } 30 | 31 | public function value() { 32 | if($this->override()) { 33 | $this->value = $this->default(); 34 | } 35 | return !empty($this->value) ? date('Y-m-d', strtotime($this->value)) : null; 36 | } 37 | 38 | public function input() { 39 | 40 | $input = parent::input(); 41 | $input->removeAttr('name'); 42 | $input->data(array( 43 | 'field' => 'date', 44 | 'format' => $this->format(), 45 | 'i18n' => html(json_encode(array( 46 | 'previousMonth' => '‹', 47 | 'nextMonth' => '›', 48 | 'months' => l::get('fields.date.months'), 49 | 'weekdays' => l::get('fields.date.weekdays'), 50 | 'weekdaysShort' => l::get('fields.date.weekdays.short') 51 | )), false) 52 | )); 53 | 54 | $hidden = new Brick('input', null); 55 | $hidden->type = 'hidden'; 56 | $hidden->name = $this->name(); 57 | $hidden->value = $this->value(); 58 | 59 | return $input . $hidden; 60 | 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /sample/panel/app/src/panel/models/file/menu.php: -------------------------------------------------------------------------------- 1 | page = $file->page(); 15 | $this->file = $file; 16 | } 17 | 18 | public function item($icon, $label, $attr = array()) { 19 | 20 | $a = new Brick('a', '', $attr); 21 | $a->append(icon($icon, 'left')); 22 | $a->append(l($label)); 23 | 24 | $li = new Brick('li'); 25 | $li->append($a); 26 | 27 | return $li; 28 | 29 | } 30 | 31 | public function previewOption() { 32 | return $this->item('play-circle-o', 'files.show.open', array( 33 | 'href' => $this->file->url('preview'), 34 | 'target' => '_blank' 35 | )); 36 | } 37 | 38 | public function editOption() { 39 | return $this->item('pencil', 'files.index.edit', array( 40 | 'href' => $this->file->url('edit'), 41 | )); 42 | } 43 | 44 | public function deleteOption() { 45 | return $this->item('trash-o', 'files.show.delete', array( 46 | 'href' => $this->file->url('delete'), 47 | 'data-modal' => true, 48 | )); 49 | } 50 | 51 | public function html() { 52 | 53 | $list = new Brick('ul'); 54 | $list->addClass('nav nav-list'); 55 | $list->addClass('dropdown-list'); 56 | 57 | $list->append($this->previewOption()); 58 | $list->append($this->editOption()); 59 | $list->append($this->deleteOption()); 60 | 61 | return ''; 62 | 63 | } 64 | 65 | public function __toString() { 66 | return (string)$this->html(); 67 | } 68 | 69 | } -------------------------------------------------------------------------------- /sample/panel/app/forms/installation/signup.php: -------------------------------------------------------------------------------- 1 | translations() as $translation) { 8 | $translations[$translation->code()] = $translation->title(); 9 | } 10 | 11 | $form = new Kirby\Panel\Form(array( 12 | 13 | 'username' => array( 14 | 'label' => 'installation.signup.username.label', 15 | 'type' => 'text', 16 | 'icon' => 'user', 17 | 'placeholder' => 'installation.signup.username.placeholder', 18 | 'required' => true, 19 | 'autocomplete' => false, 20 | 'autofocus' => true, 21 | ), 22 | 23 | 'email' => array( 24 | 'label' => 'installation.signup.email.label', 25 | 'placeholder' => 'installation.signup.email.placeholder', 26 | 'type' => 'email', 27 | 'required' => true, 28 | 'autocomplete' => false, 29 | ), 30 | 31 | 'password' => array( 32 | 'label' => 'installation.signup.password.label', 33 | 'type' => 'password', 34 | 'required' => true, 35 | 'autocomplete' => false, 36 | 'suggestion' => true, 37 | ), 38 | 39 | 'language' => array( 40 | 'label' => 'installation.signup.language.label', 41 | 'type' => 'select', 42 | 'required' => true, 43 | 'autocomplete' => false, 44 | 'default' => kirby()->option('panel.language', 'en'), 45 | 'options' => $translations 46 | ) 47 | 48 | )); 49 | 50 | $form->attr('autocomplete', 'off'); 51 | $form->data('autosubmit', 'native'); 52 | $form->style('centered'); 53 | 54 | $form->buttons->submit->value = l('installation.signup.button'); 55 | 56 | return $form; 57 | 58 | }; -------------------------------------------------------------------------------- /sample/kirby/toolkit/lib/cache/value.php: -------------------------------------------------------------------------------- 1 | 13 | * @link http://getkirby.com 14 | * @copyright Bastian Allgeier 15 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 16 | */ 17 | class Value { 18 | 19 | // the cached value 20 | protected $value; 21 | 22 | // the expiration timestamp 23 | protected $expires; 24 | 25 | // the creation timestamp 26 | protected $created; 27 | 28 | /** 29 | * Constructor 30 | * 31 | * @param mixed $value 32 | * @param int $minutes the number of minutes until the value expires 33 | */ 34 | public function __construct($value, $minutes = null) { 35 | 36 | // keep forever if minutes are not defined 37 | if(is_null($minutes)) $minutes = 2628000; 38 | 39 | // take the current time 40 | $time = time(); 41 | 42 | $this->value = $value; 43 | $this->expires = $time + ($minutes * 60); 44 | $this->created = $time; 45 | 46 | } 47 | 48 | /** 49 | * Returns the value 50 | * 51 | * @return mixed 52 | */ 53 | public function value() { 54 | return $this->value; 55 | } 56 | 57 | /** 58 | * Returns the expiration date as UNIX timestamp 59 | * 60 | * @return int 61 | */ 62 | public function expires() { 63 | return $this->expires; 64 | } 65 | 66 | /** 67 | * Returns the creation date as UNIX timestamp 68 | * 69 | * @return int 70 | */ 71 | public function created() { 72 | return $this->created; 73 | } 74 | 75 | } -------------------------------------------------------------------------------- /sample/kirby/toolkit/lib/cache.php: -------------------------------------------------------------------------------- 1 | 11 | * @link http://getkirby.com 12 | * @copyright Bastian Allgeier 13 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 14 | */ 15 | class Cache { 16 | 17 | const ERROR_INVALID_DRIVER = 0; 18 | const ERROR_INVALID_DRIVER_INSTANCE = 1; 19 | const ERROR_UNKNOWN_METHOD = 2; 20 | 21 | public static $driver = null; 22 | 23 | /** 24 | * Setup simplifier for the current driver 25 | * 26 | * @param string $driver 27 | * @param mixed $args 28 | * @return Cache\Driver 29 | */ 30 | public static function setup($driver, $args = null) { 31 | $ref = new ReflectionClass('Cache\\Driver\\' . $driver); 32 | return static::$driver = $ref->newInstanceArgs(array($args)); 33 | } 34 | 35 | /** 36 | * Accessor for all static driver methods 37 | * 38 | * @param string $method 39 | * @param mixed $args 40 | * @return mixed 41 | */ 42 | public static function __callStatic($method, $args) { 43 | 44 | if(is_null(static::$driver)) { 45 | throw new Error('Please define a cache driver', static::ERROR_INVALID_DRIVER); 46 | } 47 | 48 | if(!is_a(static::$driver, 'Cache\\Driver')) { 49 | throw new Error('The cache driver must be an instance of the Cache\\Driver class', static::ERROR_INVALID_DRIVER_INSTANCE); 50 | } 51 | 52 | if(method_exists(static::$driver, $method)) { 53 | return call(array(static::$driver, $method), $args); 54 | } else { 55 | throw new Error('Invalid cache method: ' . $method, static::ERROR_UNKNOWN_METHOD); 56 | } 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /sample/kirby/toolkit/lib/cache/driver/apc.php: -------------------------------------------------------------------------------- 1 | 12 | * @link http://getkirby.com 13 | * @copyright Bastian Allgeier 14 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 15 | */ 16 | class Apc extends Driver { 17 | 18 | /** 19 | * Write an item to the cache for a given number of minutes. 20 | * 21 | * 22 | * // Put an item in the cache for 15 minutes 23 | * Cache::set('value', 'my value', 15); 24 | * 25 | * 26 | * @param string $key 27 | * @param mixed $value 28 | * @param int $minutes 29 | * @return void 30 | */ 31 | public function set($key, $value, $minutes = null) { 32 | return apc_store($key, $this->value($value, $minutes), $this->expiration($minutes)); 33 | } 34 | 35 | /** 36 | * Retrieve an item from the cache. 37 | * 38 | * @param string $key 39 | * @return mixed 40 | */ 41 | public function retrieve($key) { 42 | return apc_fetch($key); 43 | } 44 | 45 | /** 46 | * Checks if the current key exists in cache 47 | * 48 | * @param string $key 49 | * @return boolean 50 | */ 51 | public function exists($key) { 52 | return apc_exists($key); 53 | } 54 | 55 | /** 56 | * Remove an item from the cache 57 | * 58 | * @param string $key 59 | * @return boolean 60 | */ 61 | public function remove($key) { 62 | return apc_delete($key); 63 | } 64 | 65 | /** 66 | * Flush the entire cache directory 67 | * 68 | * @return boolean 69 | */ 70 | public function flush() { 71 | return apc_clear_cache('user'); 72 | } 73 | 74 | } -------------------------------------------------------------------------------- /sample/kirby/toolkit/lib/redirect.php: -------------------------------------------------------------------------------- 1 | 11 | * @link http://getkirby.com 12 | * @copyright Bastian Allgeier 13 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 14 | */ 15 | class Redirect { 16 | 17 | /** 18 | * Redirects the user to a new URL 19 | * 20 | * @param string $url The URL to redirect to 21 | * @param boolean $code The HTTP status code, which should be sent (301, 302 or 303) 22 | * @param boolean $send If true, headers will be sent and redirection will take effect 23 | */ 24 | public static function send($url = false, $code = false, $send = true) { 25 | return header::redirect($url, $code, $send); 26 | } 27 | 28 | /** 29 | * Redirects to a specific URL. You can pass either a normal URI 30 | * a controller path or simply nothing (which redirects home) 31 | */ 32 | public static function to() { 33 | static::send(call_user_func_array(array('url', 'to'), func_get_args())); 34 | } 35 | 36 | /** 37 | * Redirects to the home page of the app 38 | */ 39 | public static function home() { 40 | static::send(url::home()); 41 | } 42 | 43 | /** 44 | * Redirects to the last location of the user 45 | * 46 | * @param string $fallback 47 | */ 48 | public static function back($fallback = null) { 49 | // get the last url 50 | $last = url::last(); 51 | // make sure there's a proper fallback 52 | if(empty($last)) $last = $fallback ? $fallback : url::home(); 53 | static::send($last); 54 | } 55 | 56 | } -------------------------------------------------------------------------------- /sample/kirby/toolkit/lib/server.php: -------------------------------------------------------------------------------- 1 | 12 | * @link http://getkirby.com 13 | * @copyright Bastian Allgeier 14 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 15 | */ 16 | class Server { 17 | 18 | /** 19 | * Gets a value from the _SERVER array 20 | * 21 | * 22 | * 23 | * server::get('document_root'); 24 | * // sample output: /var/www/kirby 25 | * 26 | * server::get(); 27 | * // returns the whole server array 28 | * 29 | * 30 | * 31 | * @param mixed $key The key to look for. Pass false or null to return the entire server array. 32 | * @param mixed $default Optional default value, which should be returned if no element has been found 33 | * @return mixed 34 | */ 35 | public static function get($key = false, $default = null) { 36 | if(empty($key)) return $_SERVER; 37 | $key = str::upper($key); 38 | $value = a::get($_SERVER, $key, $default); 39 | return static::sanitize($key, $value); 40 | } 41 | 42 | public static function sanitize($key, $value) { 43 | 44 | switch($key) { 45 | case 'SERVER_ADDR': 46 | case 'SERVER_NAME': 47 | case 'HTTP_HOST': 48 | $value = strip_tags($value); 49 | $value = preg_replace('![^\w.:-]+!iu', '', $value); 50 | $value = trim($value, '-'); 51 | $value = htmlspecialchars($value); 52 | break; 53 | case 'SERVER_PORT': 54 | $value = preg_replace('![^0-9]+!', '', $value); 55 | break; 56 | } 57 | 58 | return $value; 59 | 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /sample/panel/app/fields/text/text.php: -------------------------------------------------------------------------------- 1 | 0, 8 | 'max' => null 9 | ); 10 | 11 | static public $assets = array( 12 | 'js' => array( 13 | 'counter.js' 14 | ) 15 | ); 16 | 17 | public function min() { 18 | return isset($this->validate['min']) ? $this->validate['min'] : false; 19 | } 20 | 21 | public function max() { 22 | return isset($this->validate['max']) ? $this->validate['max'] : false; 23 | } 24 | 25 | public function input() { 26 | 27 | $input = parent::input(); 28 | 29 | if(!$this->readonly() && ($this->min() || $this->max())) { 30 | $input->data('max', $this->max())->data('min', $this->min()); 31 | } 32 | 33 | return $input; 34 | 35 | } 36 | 37 | public function outsideRange($length) { 38 | 39 | if($this->min() && $length < $this->min()) return true; 40 | if($this->max() && $length > $this->max()) return true; 41 | 42 | return false; 43 | 44 | } 45 | 46 | public function counter() { 47 | 48 | if(!$this->min() && !$this->max() || $this->readonly()) return null; 49 | 50 | $counter = new Brick('div'); 51 | $counter->addClass('field-counter marginalia text'); 52 | 53 | $length = str::length($this->value()); 54 | 55 | if($this->outsideRange($length)) { 56 | $counter->addClass('outside-range'); 57 | } 58 | 59 | $counter->data('field', 'counter'); 60 | $counter->html($length . ($this->max() ? '/' . $this->max() : '')); 61 | 62 | return $counter; 63 | 64 | } 65 | 66 | public function template() { 67 | 68 | return $this->element() 69 | ->append($this->label()) 70 | ->append($this->content()) 71 | ->append($this->counter()) 72 | ->append($this->help()); 73 | 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /sample/panel/app/src/panel/models/user/history.php: -------------------------------------------------------------------------------- 1 | user = $user; 13 | } 14 | 15 | public function add($id) { 16 | 17 | if(is_a('Kirby\\Panel\\Models\\Page', $id)) { 18 | $page = $id; 19 | } else { 20 | if(empty($id)) return false; 21 | 22 | try { 23 | $page = panel()->page($id); 24 | } catch(Exception $e) { 25 | return false; 26 | } 27 | } 28 | 29 | $history = $this->get(); 30 | 31 | // remove existing entries 32 | foreach($history as $key => $val) { 33 | if($val->id() == $page->id()) unset($history[$key]); 34 | } 35 | 36 | array_unshift($history, $page->id()); 37 | $history = array_slice($history, 0, 5); 38 | 39 | try { 40 | $this->user->update(array( 41 | 'history' => $history 42 | )); 43 | } catch(Exception $e) { 44 | 45 | } 46 | 47 | } 48 | 49 | public function get() { 50 | 51 | $history = $this->user->__get('history'); 52 | 53 | if(empty($history) or !is_array($history)) { 54 | return array(); 55 | } 56 | 57 | $update = false; 58 | $result = array(); 59 | 60 | foreach($history as $item) { 61 | 62 | try { 63 | $result[] = panel()->page($item); 64 | } catch(Exception $e) { 65 | $update = true; 66 | } 67 | 68 | } 69 | 70 | if($update) { 71 | 72 | $history = array_map(function($item) { 73 | return $item->id(); 74 | }, $result); 75 | 76 | try { 77 | $this->user->update(array( 78 | 'history' => $history 79 | )); 80 | } catch(Exception $e) { 81 | 82 | } 83 | 84 | } 85 | 86 | return $result; 87 | 88 | } 89 | 90 | } -------------------------------------------------------------------------------- /sample/panel/app/src/panel/widgets.php: -------------------------------------------------------------------------------- 1 | order = kirby()->option('panel.widgets'); 16 | 17 | $this->defaults(); 18 | $this->custom(); 19 | $this->sort(); 20 | 21 | } 22 | 23 | public function load($name, $file) { 24 | 25 | if(!file_exists($file)) { 26 | return false; 27 | } 28 | 29 | $widget = require($file); 30 | 31 | if(!is_array($widget)) { 32 | return false; 33 | } 34 | 35 | $this->unsorted[$name] = $widget; 36 | 37 | } 38 | 39 | public function defaults() { 40 | 41 | $root = panel()->roots()->widgets(); 42 | 43 | foreach(dir::read($root) as $dir) { 44 | 45 | // add missing widgets to the order array 46 | if(!array_key_exists($dir, $this->order)) { 47 | $this->order[$dir] = true; 48 | } 49 | 50 | $this->load($dir, $root . DS . $dir . DS . $dir . '.php'); 51 | 52 | } 53 | 54 | } 55 | 56 | public function custom() { 57 | 58 | $root = kirby()->roots()->widgets(); 59 | 60 | foreach(dir::read($root) as $dir) { 61 | 62 | // add missing widgets to the order array 63 | if(!array_key_exists($dir, $this->order)) { 64 | $this->order[$dir] = true; 65 | } 66 | 67 | $this->load($dir, $root . DS . $dir . DS . $dir . '.php'); 68 | } 69 | 70 | } 71 | 72 | public function sort() { 73 | 74 | // the license warning must always be included 75 | $this->order['license'] = true; 76 | 77 | foreach($this->order as $name => $add) { 78 | if($add and isset($this->unsorted[$name])) { 79 | $this->append($name, $this->unsorted[$name]); 80 | } 81 | } 82 | 83 | } 84 | 85 | } -------------------------------------------------------------------------------- /sample/kirby/toolkit/lib/cache/driver/session.php: -------------------------------------------------------------------------------- 1 | 15 | * @link http://getkirby.com 16 | * @copyright Bastian Allgeier 17 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 18 | */ 19 | class Session extends Driver { 20 | 21 | /** 22 | * Make sure the session is started within the constructor 23 | */ 24 | public function __construct() { 25 | s::start(); 26 | if(!isset($_SESSION['_cache'])) { 27 | $_SESSION['_cache'] = array(); 28 | } 29 | } 30 | 31 | /** 32 | * Write an item to the cache for a given number of minutes. 33 | * 34 | * 35 | * // Put an item in the cache for 15 minutes 36 | * Cache::set('value', 'my value', 15); 37 | * 38 | * 39 | * @param string $key 40 | * @param mixed $value 41 | * @param int $minutes 42 | * @return void 43 | */ 44 | public function set($key, $value, $minutes = null) { 45 | return $_SESSION['_cache'][$key] = $this->value($value, $minutes); 46 | } 47 | 48 | /** 49 | * Retrieve an item from the cache. 50 | * 51 | * @param string $key 52 | * @return object CacheValue 53 | */ 54 | public function retrieve($key) { 55 | return a::get($_SESSION['_cache'], $key); 56 | } 57 | 58 | /** 59 | * Remove an item from the cache 60 | * 61 | * @param string $key 62 | * @return boolean 63 | */ 64 | public function remove($key) { 65 | unset($_SESSION['_cache'][$key]); 66 | } 67 | 68 | /** 69 | * Flush the entire cache directory 70 | * 71 | * @return boolean 72 | */ 73 | public function flush() { 74 | $_SESSION['_cache'] = array(); 75 | return true; 76 | } 77 | 78 | } -------------------------------------------------------------------------------- /sample/panel/app/src/panel/models/page/blueprint/files.php: -------------------------------------------------------------------------------- 1 | params = $params; 25 | 26 | if($params === false) { 27 | $this->fields = array(); 28 | $this->type = array(); 29 | $this->size = false; 30 | $this->width = false; 31 | $this->height = false; 32 | $this->max = 0; 33 | $this->hide = true; 34 | $this->sortable = false; 35 | 36 | } else if(is_array($params)) { 37 | $this->fields = a::get($params, 'fields', $this->fields); 38 | $this->type = a::get($params, 'type', $this->type); 39 | if (!is_array($this->type)) 40 | $this->type = array($this->type); 41 | $this->size = a::get($params, 'size', $this->size); 42 | $this->width = a::get($params, 'width', $this->width); 43 | $this->height = a::get($params, 'height', $this->height); 44 | $this->max = a::get($params, 'max', $this->max); 45 | $this->hide = a::get($params, 'hide', $this->hide); 46 | $this->sort = a::get($params, 'sort', $this->sort); 47 | $this->sortable = a::get($params, 'sortable', $this->sortable); 48 | $this->sanitize = a::get($params, 'sanitize', true); 49 | } 50 | 51 | } 52 | 53 | public function fields($file) { 54 | return new Fields($this->fields, $file); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /sample/panel/assets/css/form.min.css: -------------------------------------------------------------------------------- 1 | .field-with-headline:first-child{padding-top:0}.field-with-headline{counter-increment:count;padding-top:6em}.field-with-headline .hgroup span{padding-left:1.5em}.field-with-headline .hgroup:before{position:absolute;content:counter(count,decimal-leading-zero);left:0;color:#8dae28;font-weight:400}.structure{padding-bottom:.5em}.structure-entry{background:#fff;border:2px solid #ddd;margin-bottom:.5em}.structure-readonly .structure-entry{background:#efefef;color:#777}.structure-entry:last-child{margin-bottom:0}.structure-entry-content{padding:1em 1.5em;border-bottom:1px solid #efefef}.structure[data-sortable=true] .structure-entry-content{cursor:move}.structure-entry-options .btn{padding:.75em 1.5em;width:50%;float:left;border-right:1px solid #efefef}.structure-empty{padding:1.5em;background:#ddd}.fileview-sidebar .structure-empty{background:0 0;border-radius:5px;border:1px dashed #ddd;padding:1rem 1.5rem 1.25rem}.structure-empty a{border-bottom:2px solid #aaa;margin-left:.5em}.fileview-sidebar .structure-empty a{display:inline-block;margin-left:0}.structure-empty a:hover{border-color:#000}.structure-add-button{cursor:pointer}.structure-table{width:100%;border-spacing:0;border:2px solid #ddd;border-bottom:1px solid #ddd;border-right:1px solid #ddd;table-layout:fixed}.structure-table td,.structure-table th{background:#fff;border-bottom:1px solid #ddd;border-right:1px solid #ddd;text-align:left;vertical-align:top}.structure-table th{padding:.5em;font-weight:400;color:#777;font-style:italic}.structure-table td a{display:block;padding:.5em;overflow:hidden;width:100%;text-overflow:ellipsis;cursor:move}.structure-table-options{width:3rem;text-align:center}.structure-table .structure-table-options a{text-align:center;cursor:pointer}.structure-sortable-helper{border-top:1px solid #ddd;border-left:1px solid #ddd}.field-counter{position:absolute;z-index:-1;right:0;top:0;text-align:right;font-size:.9em;line-height:1.66666666666667}.field-counter.outside-range{color:#b3000a} -------------------------------------------------------------------------------- /sample/panel/app/controllers/installation.php: -------------------------------------------------------------------------------- 1 | isCompleted()) { 12 | $this->redirect(); 13 | } else if($problems = $installer->problems()) { 14 | return $this->problems($problems); 15 | } else { 16 | return $this->signup(); 17 | } 18 | 19 | } 20 | 21 | protected function problems($problems) { 22 | $form = $this->form('installation/check', array($problems)); 23 | return $this->modal('index', compact('form')); 24 | } 25 | 26 | protected function signup() { 27 | 28 | $self = $this; 29 | $form = $this->form('installation/signup', array(), function($form) use($self) { 30 | 31 | $form->validate(); 32 | 33 | if(!$form->isValid()) { 34 | return false; 35 | } 36 | 37 | try { 38 | 39 | // fetch all the form data 40 | $data = $form->serialize(); 41 | 42 | // make sure that the first user is an admin 43 | $data['role'] = 'admin'; 44 | 45 | // try to create the new user 46 | $user = site()->users()->create($data); 47 | 48 | // store the new username for the login screen 49 | s::set('username', $user->username()); 50 | 51 | // try to login the user automatically 52 | if($user->hasPanelAccess()) { 53 | $user->login($data['password']); 54 | } 55 | 56 | // redirect to the login 57 | $self->redirect('login'); 58 | 59 | } catch(Exception $e) { 60 | $form->alert($e->getMessage()); 61 | } 62 | 63 | }); 64 | 65 | return $this->modal('index', compact('form')); 66 | 67 | } 68 | 69 | public function modal($view, $data = array()) { 70 | return $this->layout('base', array( 71 | 'bodyclass' => 'installation', 72 | 'content' => $this->view('installation/' . $view, $data) 73 | )); 74 | } 75 | 76 | } -------------------------------------------------------------------------------- /sample/panel/app/fields/select/select.php: -------------------------------------------------------------------------------- 1 | type = 'select'; 8 | $this->options = array(); 9 | $this->icon = 'chevron-down'; 10 | 11 | } 12 | 13 | public function options() { 14 | return FieldOptions::build($this); 15 | } 16 | 17 | public function option($value, $text, $selected = false) { 18 | return new Brick('option', $this->i18n($text), array( 19 | 'value' => $value, 20 | 'selected' => $selected 21 | )); 22 | } 23 | 24 | public function input() { 25 | 26 | $select = new Brick('select'); 27 | $select->addClass('selectbox'); 28 | $select->attr(array( 29 | 'name' => $this->name(), 30 | 'id' => $this->id(), 31 | 'required' => $this->required(), 32 | 'autocomplete' => $this->autocomplete(), 33 | 'autofocus' => $this->autofocus(), 34 | 'readonly' => $this->readonly(), 35 | 'disabled' => $this->disabled(), 36 | )); 37 | 38 | $default = $this->default(); 39 | 40 | if(!$this->required()) { 41 | $select->append($this->option('', '', $this->value() == '')); 42 | } 43 | 44 | if($this->readonly()) { 45 | $select->attr('tabindex', '-1'); 46 | } 47 | 48 | foreach($this->options() as $value => $text) { 49 | $select->append($this->option($value, $text, $this->value() == $value)); 50 | } 51 | 52 | $inner = new Brick('div'); 53 | $inner->addClass('selectbox-wrapper'); 54 | $inner->append($select); 55 | 56 | $wrapper = new Brick('div'); 57 | $wrapper->addClass('input input-with-selectbox'); 58 | $wrapper->append($inner); 59 | 60 | if($this->readonly()) { 61 | $wrapper->addClass('input-is-readonly'); 62 | } else { 63 | $wrapper->attr('data-focus', 'true'); 64 | } 65 | 66 | return $wrapper; 67 | 68 | } 69 | 70 | public function validate() { 71 | return array_key_exists($this->value(), $this->options()); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /sample/panel/app/fields/inputlist/inputlist.php: -------------------------------------------------------------------------------- 1 | removeClass('input'); 10 | return $input; 11 | } 12 | 13 | public function options() { 14 | return fieldoptions::build($this); 15 | } 16 | 17 | public function item($value, $text) { 18 | 19 | $input = $this->input($value); 20 | 21 | $label = new Brick('label', $this->i18n($text)); 22 | $label->addClass('input'); 23 | $label->attr('data-focus', 'true'); 24 | $label->prepend($input); 25 | 26 | if($this->readonly) { 27 | $label->addClass('input-is-readonly'); 28 | } 29 | 30 | return $label; 31 | 32 | } 33 | 34 | public function content() { 35 | 36 | $html = '
      '; 37 | 38 | switch($this->columns()) { 39 | case 2: 40 | $width = ' field-grid-item-1-2'; 41 | break; 42 | case 3: 43 | $width = ' field-grid-item-1-3'; 44 | break; 45 | case 4: 46 | $width = ' field-grid-item-1-4'; 47 | break; 48 | case 5: 49 | $width = ' field-grid-item-1-5'; 50 | break; 51 | default: 52 | $width = ''; 53 | break; 54 | } 55 | 56 | foreach($this->options() as $key => $value) { 57 | $html .= '
    • '; 58 | $html .= $this->item($key, $value); 59 | $html .= '
    • '; 60 | } 61 | 62 | $html .= '
    '; 63 | 64 | $content = new Brick('div'); 65 | $content->addClass('field-content'); 66 | $content->append($html); 67 | 68 | return $content; 69 | 70 | } 71 | 72 | public function validate() { 73 | if(is_array($this->value())) { 74 | foreach($this->value() as $v) { 75 | if(!array_key_exists($v, $this->options())) return false; 76 | } 77 | return true; 78 | } else { 79 | return array_key_exists($this->value(), $this->options()); 80 | } 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /sample/panel/app/src/panel/translation.php: -------------------------------------------------------------------------------- 1 | 'es_419', 19 | 'no_nb' => 'nb', 20 | 'cz' => 'cs' 21 | ); 22 | 23 | public function __construct($panel, $code) { 24 | 25 | $this->panel = $panel; 26 | $this->code = basename($code); 27 | 28 | // convert old codes 29 | if(isset($this->map[$this->code])) { 30 | $this->code = $this->map[$this->code]; 31 | } 32 | 33 | // set the root for the translation directory 34 | $this->root = $this->panel->roots()->translations() . DS . $this->code; 35 | 36 | if(!is_dir($this->root)) { 37 | throw new Exception('The translation does not exist: ' . $this->code); 38 | } 39 | 40 | if(!is_file($this->root . DS . 'package.json')) { 41 | throw new Exception('The package.json is missing for the translation with code: ' . $this->code); 42 | } 43 | 44 | if(!is_file($this->root . DS . 'core.json')) { 45 | throw new Exception('The core.json is missing for the translation with code: ' . $this->code); 46 | } 47 | 48 | } 49 | 50 | public function code() { 51 | return $this->code; 52 | } 53 | 54 | public function root() { 55 | return $this->root; 56 | } 57 | 58 | public function load() { 59 | return l::$data = data::read($this->root . DS . 'core.json'); 60 | } 61 | 62 | public function info() { 63 | if(!is_null($this->info)) return $this->info; 64 | return $this->info = new Obj(data::read($this->root . DS . 'package.json')); 65 | } 66 | 67 | public function direction() { 68 | $direction = $this->info()->direction(); 69 | return $direction ? $direction : 'ltr'; 70 | } 71 | 72 | public function __call($method, $args) { 73 | return $this->info()->{$method}(); 74 | } 75 | 76 | public function __toString() { 77 | return $this->code; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /sample/panel/app/src/panel/form/plugins.php: -------------------------------------------------------------------------------- 1 | find('custom'); 19 | $this->find('default'); 20 | $this->load(); 21 | } 22 | 23 | public function find($type) { 24 | 25 | $root = form::$root[$type]; 26 | $dirs = dir::read($root); 27 | 28 | foreach($dirs as $dir) { 29 | 30 | $name = strtolower($dir); 31 | $file = $root . DS . $name . DS . $name . '.php'; 32 | 33 | if(file_exists($file)) { 34 | $this->{$type}[$name . 'field'] = $file; 35 | } 36 | 37 | } 38 | 39 | } 40 | 41 | public function load() { 42 | 43 | $this->classes = array_merge($this->default, $this->custom); 44 | 45 | load($this->classes); 46 | 47 | foreach($this->classes as $classname => $root) { 48 | 49 | if(method_exists($classname, 'setup')) { 50 | call(array($classname, 'setup')); 51 | } 52 | 53 | } 54 | 55 | foreach($this->custom as $classname => $root) { 56 | 57 | if(!isset($classname::$assets)) continue; 58 | 59 | if(isset($classname::$assets['css'])) { 60 | $this->assets('css', $root, $classname::$assets['css']); 61 | } 62 | 63 | if(isset($classname::$assets['js'])) { 64 | $this->assets('js', $root, $classname::$assets['js']); 65 | } 66 | 67 | } 68 | 69 | } 70 | 71 | public function assets($type, $root, $files) { 72 | 73 | $output = array(); 74 | 75 | foreach($files as $filename) { 76 | $output[] = f::read(dirname($root) . DS . 'assets' . DS . $type . DS . $filename); 77 | } 78 | 79 | $this->{$type} .= implode(PHP_EOL . PHP_EOL, $output); 80 | 81 | } 82 | 83 | public function css() { 84 | return $this->css; 85 | } 86 | 87 | public function js() { 88 | return $this->js; 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /sample/panel/app/src/panel/models/page/sidebar.php: -------------------------------------------------------------------------------- 1 | page = $page; 15 | $this->blueprint = $page->blueprint(); 16 | } 17 | 18 | public function subpages() { 19 | 20 | if(!$this->page->canShowSubpages()) { 21 | return null; 22 | } 23 | 24 | // fetch all subpages in the right order 25 | $children = $this->page->children()->paginated('sidebar'); 26 | 27 | // create the pagination snippet 28 | $pagination = new Snippet('pagination', array( 29 | 'pagination' => $children->pagination(), 30 | 'nextUrl' => $children->pagination()->nextPageUrl(), 31 | 'prevUrl' => $children->pagination()->prevPageUrl(), 32 | )); 33 | 34 | // create the snippet and fill it with all data 35 | return new Snippet('pages/sidebar/subpages', array( 36 | 'title' => l('pages.show.subpages.title'), 37 | 'page' => $this->page, 38 | 'subpages' => $children, 39 | 'addbutton' => $this->page->addButton(), 40 | 'pagination' => $pagination, 41 | )); 42 | 43 | } 44 | 45 | public function files() { 46 | 47 | if(!$this->page->canShowFiles()) { 48 | return null; 49 | } 50 | 51 | return new Snippet('pages/sidebar/files', array( 52 | 'page' => $this->page, 53 | 'files' => $this->page->files(), 54 | )); 55 | 56 | } 57 | 58 | public function render() { 59 | 60 | // create the monster sidebar 61 | return new Snippet('pages/sidebar', array( 62 | 'page' => $this->page, 63 | 'menu' => $this->page->menu('sidebar'), 64 | 'subpages' => $this->subpages(), 65 | 'files' => $this->files(), 66 | )); 67 | 68 | } 69 | 70 | public function __toString() { 71 | try { 72 | return (string)$this->render(); 73 | } catch(Exception $e) { 74 | return $e->getMessage(); 75 | } 76 | } 77 | 78 | } -------------------------------------------------------------------------------- /sample/panel/app/views/dashboard/index.php: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 5 | $widget): ?> 6 | 7 |
    8 | 9 |

    10 | 11 | 12 | 13 | href=""> 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | data-shortcut="" href=""> 30 | 31 | href=""> 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |

    41 | 42 | 43 | 44 |
    45 | 46 | 47 |
    48 | 49 |
    -------------------------------------------------------------------------------- /sample/panel/app/views/options/index.php: -------------------------------------------------------------------------------- 1 |
    2 | 3 | 53 | 54 |
    55 |
    56 | 57 |
    58 |
    59 | 60 |
    61 | 62 | -------------------------------------------------------------------------------- /sample/readme.md: -------------------------------------------------------------------------------- 1 | # Kirby 2 | 3 | Kirby is a file-based CMS. 4 | Easy to setup. Easy to use. Flexible as hell. 5 | 6 | ## Trial 7 | 8 | You can try Kirby on your local machine or on a test 9 | server as long as you need to make sure it is the right 10 | tool for your next project. 11 | 12 | ## Buy a license 13 | 14 | You can purchase your Kirby license at 15 | 16 | 17 | A Kirby license is valid for a single domain. You can find 18 | Kirby's license agreement here: 19 | 20 | ## The Starterkit 21 | 22 | Kirby's Starterkit comes with a small demo website and a fully 23 | configured panel. Feel free to modify it and play with it as 24 | much as you like. 25 | 26 | ## The Panel 27 | 28 | You can find the login for Kirby's admin interface at 29 | http://yourdomain.com/panel. You will be guided through the signup 30 | process for your first user, when you visit the panel 31 | for the first time. 32 | 33 | ## Installation 34 | 35 | Kirby does not require a database, which makes it very easy to 36 | install. Just copy Kirby's files to your server and visit the 37 | URL for your website in the browser. 38 | 39 | **Please check if the invisible .htaccess file has been 40 | copied to your server correctly** 41 | 42 | ### Requirements 43 | 44 | Kirby runs on PHP 5.4+, Apache or Nginx. 45 | 46 | ### Download 47 | 48 | You can download the latest version of the Starterkit 49 | from http://download.getkirby.com 50 | 51 | ### With Git 52 | 53 | If you are familiar with Git, you can clone Kirby's 54 | Starterkit repository from Github. 55 | 56 | git clone --recursive https://github.com/getkirby/starterkit.git 57 | 58 | ## Documentation 59 | 60 | 61 | ## Issues and feedback 62 | 63 | If you have a Github account, please report issues 64 | directly on Github: 65 | 66 | - 67 | - 68 | - 69 | 70 | Otherwise you can use Kirby's forum: http://getkirby.com/forum 71 | or send us an email: 72 | 73 | ## Support 74 | 75 | 76 | ## Copyright 77 | 78 | © 2009-2014 Bastian Allgeier (Bastian Allgeier GmbH) 79 | -------------------------------------------------------------------------------- /sample/kirby/toolkit/lib/bitmask.php: -------------------------------------------------------------------------------- 1 | 10 | * @link http://getkirby.com 11 | * @copyright Lukas Bestle 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | class Bitmask { 15 | 16 | /** 17 | * Checks if a value can be used as bitmask value (checks for a power of two) 18 | * 19 | * @param mixed $value The value to check for 20 | * @return boolean 21 | */ 22 | public static function validValue($value) { 23 | return is_int($value) && ($value & ($value - 1)) == 0; 24 | } 25 | 26 | /** 27 | * Checks if a bitmask includes a value 28 | * 29 | * @param int $value The value to check for 30 | * @param int $bitmask The bitmask to check in 31 | * @return boolean 32 | */ 33 | public static function includes($value, $bitmask) { 34 | if(!static::validValue($value)) return false; 35 | 36 | return ($bitmask & $value) !== 0; 37 | } 38 | 39 | /** 40 | * Adds a value to a bitmask 41 | * 42 | * @param int $value The value to add 43 | * @param int $bitmask The bitmask to add the value to 44 | * @return int 45 | */ 46 | public static function add($value, $bitmask) { 47 | if(!static::validValue($value)) { 48 | throw new Exception('The value "' . $value . '" is not appropriate for usage in bitmasks.'); 49 | } 50 | 51 | // check if the bitmask already includes the value 52 | if(static::includes($value, $bitmask)) return $bitmask; 53 | 54 | return $bitmask | $value; 55 | } 56 | 57 | /** 58 | * Removes a value from a bitmask 59 | * 60 | * @param int $value The value to remove 61 | * @param int $bitmask The bitmask to remove the value from 62 | * @return int 63 | */ 64 | public static function remove($value, $bitmask) { 65 | if(!static::validValue($value)) { 66 | throw new Exception('The value "' . $value . '" is not appropriate for usage in bitmasks.'); 67 | } 68 | 69 | // check if the bitmask even includes the value 70 | if(!static::includes($value, $bitmask)) return $bitmask; 71 | 72 | return $bitmask ^ $value; 73 | } 74 | 75 | } -------------------------------------------------------------------------------- /sample/panel/app/views/users/index.php: -------------------------------------------------------------------------------- 1 |
    2 | 3 |

    4 | 5 | 6 | ( pagination()->items() ?> ) 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |

    16 | 17 |
    18 | 19 |
    20 | 36 | isCurrent()): ?> 37 | 53 | 54 |
    55 | 56 |
    57 | 58 | 59 | 60 |
    -------------------------------------------------------------------------------- /sample/panel/app/fields/structure/assets/css/structure.css: -------------------------------------------------------------------------------- 1 | .structure { 2 | padding-bottom: .5em; 3 | } 4 | .structure-entry { 5 | background: #fff; 6 | border: 2px solid #ddd; 7 | margin-bottom: .5em; 8 | } 9 | .structure-readonly .structure-entry { 10 | background: #efefef; 11 | color: #777; 12 | } 13 | .structure-entry:last-child { 14 | margin-bottom: 0; 15 | } 16 | .structure-entry-content { 17 | padding: 1em 1.5em; 18 | border-bottom: 1px solid #efefef; 19 | } 20 | .structure[data-sortable=true] .structure-entry-content { 21 | cursor: move; 22 | } 23 | .structure-entry-options .btn { 24 | padding: .75em 1.5em; 25 | width: 50%; 26 | float: left; 27 | border-right: 1px solid #efefef; 28 | } 29 | .structure-empty { 30 | padding: 1.5em; 31 | background: #ddd; 32 | } 33 | .fileview-sidebar .structure-empty { 34 | background: none; 35 | border-radius: 5px; 36 | border: 1px dashed #ddd; 37 | padding: 1rem 1.5rem 1.25rem; 38 | } 39 | .structure-empty a { 40 | border-bottom: 2px solid #aaa; 41 | margin-left: .5em; 42 | } 43 | .fileview-sidebar .structure-empty a { 44 | display: inline-block; 45 | margin-left: 0; 46 | } 47 | .structure-empty a:hover { 48 | border-color: #000; 49 | } 50 | .structure-add-button { 51 | cursor: pointer; 52 | } 53 | 54 | 55 | /* Table */ 56 | .structure-table { 57 | width: 100%; 58 | border-spacing: 0; 59 | border: 2px solid #ddd; 60 | border-bottom: 1px solid #ddd; 61 | border-right: 1px solid #ddd; 62 | table-layout: fixed; 63 | } 64 | .structure-table td, .structure-table th { 65 | background: #fff; 66 | border-bottom: 1px solid #ddd; 67 | border-right: 1px solid #ddd; 68 | text-align: left; 69 | vertical-align: top; 70 | } 71 | .structure-table th { 72 | padding: .5em; 73 | font-weight: 400; 74 | color: #777; 75 | font-style: italic; 76 | } 77 | .structure-table td a { 78 | display: block; 79 | padding: .5em; 80 | overflow: hidden; 81 | width: 100%; 82 | text-overflow: ellipsis; 83 | cursor: move; 84 | } 85 | .structure-table-options { 86 | width: 3rem; 87 | text-align: center; 88 | } 89 | .structure-table .structure-table-options a { 90 | text-align: center; 91 | cursor: pointer; 92 | } 93 | 94 | .structure-sortable-helper { 95 | border-top: 1px solid #ddd; 96 | border-left: 1px solid #ddd; 97 | } 98 | -------------------------------------------------------------------------------- /sample/panel/app/fields/textarea/textarea.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'editor.js' 8 | ) 9 | ); 10 | 11 | public function __construct() { 12 | $this->label = l::get('fields.textarea.label', 'Text'); 13 | $this->buttons = true; 14 | $this->min = 0; 15 | $this->max = false; 16 | } 17 | 18 | public function routes() { 19 | return array( 20 | array( 21 | 'pattern' => 'link', 22 | 'action' => 'link', 23 | 'method' => 'get|post' 24 | ), 25 | array( 26 | 'pattern' => 'email', 27 | 'action' => 'email', 28 | 'method' => 'get|post' 29 | ), 30 | ); 31 | } 32 | 33 | public function input() { 34 | 35 | $input = parent::input(); 36 | $input->tag('textarea'); 37 | $input->removeAttr('type'); 38 | $input->removeAttr('value'); 39 | $input->html($this->value() ?: false); 40 | $input->data('field', 'editor'); 41 | 42 | return $input; 43 | 44 | } 45 | 46 | public function result() { 47 | // Convert all line-endings to UNIX format 48 | return str_replace(array("\r\n", "\r"), "\n", parent::result()); 49 | } 50 | 51 | public function element() { 52 | 53 | $element = parent::element(); 54 | $element->addClass('field-with-textarea'); 55 | 56 | if($this->buttons and !$this->readonly) { 57 | $element->addClass('field-with-buttons'); 58 | } 59 | 60 | return $element; 61 | 62 | } 63 | 64 | public function content() { 65 | 66 | $content = parent::content(); 67 | 68 | if($this->buttons and !$this->readonly) { 69 | $content->append($this->buttons()); 70 | } 71 | 72 | return $content; 73 | 74 | } 75 | 76 | public function buttons() { 77 | require_once(__DIR__ . DS . 'buttons.php'); 78 | return new Buttons($this, $this->buttons); 79 | } 80 | 81 | public function validate() { 82 | 83 | if($this->validate and is_array($this->validate)) { 84 | return parent::validate(); 85 | } else { 86 | if($this->min and !v::min($this->result(), $this->min)) return false; 87 | if($this->max and !v::max($this->result(), $this->max)) return false; 88 | } 89 | 90 | return true; 91 | 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /sample/panel/assets/js/dist/form.min.js: -------------------------------------------------------------------------------- 1 | !function(t){t.fn.date=function(){return this.each(function(){if(t(this).data("pikaday"))return t(this);var a=t(this).attr("type","text"),e=a.next(),n=a.data("format"),r=a.val(),i=r?moment(r).format(n):null;if(a.attr("placeholder",n),a.val(i),a.is("[readonly]"))return!1;a.on("change",function(){var t=a.val();t?e.val(moment(t,n).format("YYYY-MM-DD")):e.val("")});var o=new Pikaday({field:this,firstDay:1,format:n,i18n:a.data("i18n"),onSelect:function(t){e.val(moment(t).format("YYYY-MM-DD"))}});t(this).data("pikaday",o)})}}(jQuery),function(t){var a=function(a){var e=t(a),n=e.data("style"),r=e.data("api"),i=e.data("sortable"),o="table"==n?e.find(".structure-table tbody"):e.find(".structure-entries");return i===!1?!1:void o.sortable({helper:function(a,e){return e.children().each(function(){t(this).width(t(this).width())}),e.addClass("structure-sortable-helper")},update:function(){var a=[];t.each(t(this).sortable("toArray"),function(t,e){a.push(e.replace("structure-entry-",""))}),t.post(r,{ids:a},function(){app.content.reload()})}})};t.fn.structure=function(){return this.each(function(){if(t(this).data("structure"))return t(this);var e=new a(this);return t(this).data("structure",e),t(this)})}}(jQuery),function(t){t.fn.counter=function(){return this.each(function(){var a=t(this);if(a.data("counter"))return a;var e=a.parent(".field").find(".input"),n=t.trim(e.val()).length,r=e.data("max"),i=e.data("min");e.keyup(function(){n=t.trim(e.val()).length,a.text(n+(r?"/"+r:"")),r&&n>r||i&&i>n?a.addClass("outside-range"):a.removeClass("outside-range")}).trigger("keyup"),a.data("counter",!0)})}}(jQuery),function(t){t.fn.editor=function(){return this.each(function(){if(t(this).data("editor"))return t(this);var a=t(this),e=a.parent().find(".field-buttons");a.autosize(),e.find(".btn").on("click.editorButton",function(e){a.focus();var n=t(this);if(n.data("action"))app.modal.open(n.data("action"),window.location.href);else{var r=a.getSelection(),i=n.data("tpl"),o=n.data("text");r.length>0&&(o=r);var u=i.replace("{text}",o);a.insertAtCursor(u),a.trigger("autosize.resize")}return!1}),e.find("[data-editor-shortcut]").each(function(e,n){var r=t(this).data("editor-shortcut"),i=function(a){return t(n).trigger("click"),!1};a.bind("keydown",r,i),r.match(/meta\+/)&&a.bind("keydown",r.replace("meta+","ctrl+"),i)}),a.data("editor",!0)})}}(jQuery); --------------------------------------------------------------------------------