├── docs ├── panel-2 │ ├── url.md │ ├── fingerprint.md │ ├── login-automatically.md │ ├── routes.md │ ├── messages.md │ ├── blueprints.md │ ├── css.md │ └── fields.md ├── str-replace.md ├── dependencies.md ├── use-kirby-from-the-outside.md ├── site-methods.md ├── folder-setup.md ├── assets.md ├── videos.md ├── plugin │ ├── installation.md │ ├── readme.md │ └── best-practices.md ├── config.md ├── hooks.md ├── thumb.md ├── cache.md ├── extension-registry.md ├── plugin.md ├── vue.md ├── snippet.md ├── image.md ├── collection.md ├── routing.md ├── page.md └── htaccess.md ├── readme.md └── changelog.md /docs/panel-2/url.md: -------------------------------------------------------------------------------- 1 | # Panel 2 - Url 2 | 3 | ## Get panel root uri 4 | 5 | Not sure if it will work in all cases but it returns `panel` if not changed: 6 | 7 | ```php 8 | echo str_replace(kirby()->urls()->index() . '/', '', panel()->urls()->index()); 9 | ``` 10 | 11 | ## Get panel root url 12 | 13 | To get the panel root url from inside a field, do this: 14 | 15 | ```php 16 | echo panel()->urls()->index(); 17 | ``` -------------------------------------------------------------------------------- /docs/str-replace.md: -------------------------------------------------------------------------------- 1 | # strtr 2 | 3 | ## str::replace() alternative 4 | 5 | It's nice to be able to search replace with key/value pair. The toolkit does NOT provide such a function, but PHP does. 6 | 7 | **Solution:** 8 | 9 | ```php 10 | $string = strtr($string, 11 | array( 12 | 'Search for this' => 'Replace with this', 13 | 'Search something else' => 'Replace with something else' 14 | ) 15 | ); 16 | ``` -------------------------------------------------------------------------------- /docs/dependencies.md: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | 3 | Here are the known dependencies that Kirby uses. 4 | 5 | ## Kirby 6 | 7 | - [SimpleImage](https://github.com/claviska/SimpleImage) (for thumbs) 8 | - [Spyc](https://github.com/mustangostang/spyc) (for yaml operations) 9 | - [SQLight](https://www.sqlite.org/) 10 | 11 | ## Panel 2 12 | 13 | - [jQuery](https://jquery.com/) 14 | - [jQuery sortable](https://jqueryui.com/sortable/) 15 | -------------------------------------------------------------------------------- /docs/use-kirby-from-the-outside.md: -------------------------------------------------------------------------------- 1 | # Use Kirby from the outside 2 | 3 | If you use this code, you will have access to all the Kirby function from outside of Kirby: 4 | 5 | ```php 6 | define('DS', DIRECTORY_SEPARATOR); 7 | 8 | // load kirby 9 | require(DIR . DS . 'kirby' . DS . 'bootstrap.php'); 10 | 11 | $kirby = kirby(); 12 | $site = $kirby->site(); 13 | ``` 14 | 15 | **Source** 16 | 17 | https://forum.getkirby.com/t/traversing-content-outside-of-templates/968/3 18 | -------------------------------------------------------------------------------- /docs/site-methods.md: -------------------------------------------------------------------------------- 1 | # Site methods 2 | 3 | Site methods can be seen as global methods, attached to the `$site` object. 4 | 5 | **Place this code in a plugin:** 6 | 7 | ```php 8 | site::$methods['test'] = function($site, $arg1 = '', $arg2 = '') { 9 | return $site->homePage() . ' ' . $arg1 . ' ' . $arg2; 10 | }; 11 | ``` 12 | 13 | **Add this into a template or a snippet:** 14 | 15 | ```php 16 | test('testing', 12345); ?> 17 | ``` 18 | 19 | **Source** 20 | 21 | https://forum.getkirby.com/t/get-path-to-assets-images/1304/8 22 | -------------------------------------------------------------------------------- /docs/folder-setup.md: -------------------------------------------------------------------------------- 1 | # Folder setup 2 | 3 | A custom folder setup can be a perfect way to customize the urls for a plugin. Let's have a look at how it's done. 4 | 5 | **site.php** in root of your installation: 6 | 7 | ```php 8 | $kirby = kirby(); 9 | $kirby->roots->foldername = $kirby->roots()->index() . DS . 'foldername'; 10 | ``` 11 | 12 | Get it in a snippet or template like this: 13 | 14 | ```php 15 | echo kirby()->roots()->foldername(); 16 | ``` 17 | 18 | ## Sources 19 | 20 | - [Developer guide - Folders](https://getkirby.com/docs/developer-guide/configuration/folders) -------------------------------------------------------------------------------- /docs/panel-2/fingerprint.md: -------------------------------------------------------------------------------- 1 | # Fingerprint 2 | 3 | This feature is to prevent users from being logged out. Add this code in your `config.php` but change the returned string to anything you want. 4 | 5 | ```php 6 | s::$fingerprint = function() { 7 | return 'some fingerprint'; 8 | }; 9 | ``` 10 | 11 | >In scenarios, where IP or user agent based session fingerprints won't work, you can avoid problems that way. 12 | 13 | **Sources** 14 | 15 | - https://forum.getkirby.com/t/panel-keeps-logging-me-out/2747/20 16 | - https://forum.getkirby.com/t/panel-keep-login-out/6587/10 17 | - https://forum.getkirby.com/t/how-can-i-use-fingerprint/6047/4 18 | -------------------------------------------------------------------------------- /docs/assets.md: -------------------------------------------------------------------------------- 1 | # Assets 2 | 3 | ## Convert any image to object 4 | 5 | When an image is attached to a page, you can use [Thumb](https://getkirby.com/docs/cheatsheet/helpers/thumb) to resize that image. 6 | 7 | It's now also possible to resize an image that is outside the content folder. To do that, you first convert the image to an object. You will now have access to the methods of [media](https://getkirby.com/docs/toolkit/api#media). 8 | 9 | ```php 10 | $image = new Asset('assets/images/hero-default.jpg'); 11 | echo $image->resize(50)->url(); 12 | ``` 13 | 14 | - [How to use the new asset class to generate thumbnails](https://forum.getkirby.com/t/how-to-use-the-new-asset-class-to-generate-thumbnails/4245/5) -------------------------------------------------------------------------------- /docs/videos.md: -------------------------------------------------------------------------------- 1 | # Videos 2 | 3 | ## Kirby Courses 4 | 5 | Instead of listing all the upcoming videos here is the channel: 6 | 7 | https://www.youtube.com/channel/UCcsI8ZSvGDwIaSyLS0fGegg 8 | 9 | ## Patterns 10 | 11 | A great tutorial on the [Patterns](https://github.com/getkirby-plugins/patterns-plugin) plugin. 12 | 13 | https://vimeo.com/153132557 14 | 15 | ## Other videos 16 | 17 | - [Install Kirby CMS](https://www.youtube.com/watch?v=hnnBTt4ts10) 18 | - [Install CMS no database Kirby Php](https://www.youtube.com/watch?v=h_Xo9Q6wqok) 19 | - [Kirby CLI](https://www.youtube.com/watch?v=Rdn_t__Ag_Q) 20 | - [NightlyBuild 2015 - Bastian Allgeier - Homemade Pressure](https://www.youtube.com/watch?v=BV-5qIMyzD4) 21 | - [Alex Meisner Website - Kirby CMS Tutorial](https://www.youtube.com/watch?v=1CMVDKAgrtM) 22 | -------------------------------------------------------------------------------- /docs/plugin/installation.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | Use one of the alternatives below. 4 | 5 | ### 1. Kirby CLI 6 | 7 | If you are using the [Kirby CLI](https://github.com/getkirby/cli) you can install this plugin by running the following commands in your shell: 8 | 9 | ```text 10 | $ cd path/to/kirby 11 | $ kirby plugin:install username/plugin-name 12 | ``` 13 | 14 | ### 2. Clone or download 15 | 16 | 1. [Clone](https://github.com/username/plugin-name.git) or [download](https://github.com/username/plugin-name/archive/master.zip) this repository. 17 | 2. Unzip the archive if needed and rename the folder to `plugin-name`. 18 | 19 | **Make sure that the plugin folder structure looks like this:** 20 | 21 | ```text 22 | site/plugins/plugin-name/ 23 | ``` 24 | 25 | ### 3. Git Submodule 26 | 27 | If you know your way around Git, you can download this plugin as a submodule: 28 | 29 | ```text 30 | $ cd path/to/kirby 31 | $ git submodule add https://github.com/username/plugin-name site/plugins/plugin-name 32 | ``` -------------------------------------------------------------------------------- /docs/config.md: -------------------------------------------------------------------------------- 1 | # Config 2 | 3 | Sometimes you have data that should live in a global scope. You can use `$GLOBALS`, `define`, a singleton pattern, or with the [Kirby registry](https://getkirby.com/docs/developer-guide/plugins/registry). Let's have a look at how it's done. 4 | 5 | ## Set the global data 6 | 7 | The third argument can be string, array or an object which means you are not limited by it. 8 | 9 | ```php 10 | $data = array( 11 | 'key1' => 'data1', 12 | 'key2' => array( 13 | 'key' => 'value' 14 | ) 15 | ); 16 | kirby()->set('option', 'my_data', $data); 17 | ``` 18 | 19 | ## Get the global data 20 | 21 | `get` looks like `set` without the last argument. 22 | 23 | ```php 24 | $data = kirby()->get('option', 'my_data'); 25 | print_r($data); 26 | ``` 27 | 28 | The nice thing about it is that you don't need to think of what scope you are in. The first time I used it was to get a set value inside a kirbytext tag. 29 | 30 | ## Sources 31 | 32 | - [Developer guide - Extension registry](https://getkirby.com/docs/developer-guide/plugins/registry) -------------------------------------------------------------------------------- /docs/panel-2/login-automatically.md: -------------------------------------------------------------------------------- 1 | # Panel 2 - Login automatically 2 | 3 | This solution could be added to the config.php. Replace `YOURUSERNAME` and `YOURPASSWORD`. When visiting your domain and `/autologin` you will be logged in with no questions asked. 4 | 5 | ***Be aware that this could be a very dangerous feature and should not be used on a live environment*** 6 | 7 | ```php 8 | c::set('routes', array( 9 | array( 10 | 'pattern' => 'autologin', 11 | 'action' => function() { 12 | $username = 'YOURUSERNAME'; 13 | $password = 'YOURPASSWORD'; 14 | 15 | // Prevent access on the production system 16 | if(url::host() !== 'localhost') return false; 17 | 18 | $user = site()->user($username); 19 | if($user and $user->login($password)) { 20 | go('panel'); // or use go(); to redirect to the frontpage 21 | } else { 22 | echo 'invalid username or password'; 23 | return false; 24 | } 25 | } 26 | ) 27 | )); 28 | ``` 29 | 30 | **Source:** https://forum.getkirby.com/t/bypass-login-for-localhost-environment/3015 -------------------------------------------------------------------------------- /docs/panel-2/routes.md: -------------------------------------------------------------------------------- 1 | # Panel 2 - Routes 2 | 3 | If you make plugins for the Panel you can use routes, but you can also use Panel routes, routes specially for the Panel. 4 | 5 | **Visit the url below** 6 | 7 | Change domain to your domain and you need to prefix the route with `panel/`. 8 | 9 | ```text 10 | https://example.com/panel/my-panel-route/something` 11 | ``` 12 | 13 | **In your plugin** 14 | 15 | ```php 16 | panel()->routes(array( 17 | array( 18 | 'pattern' => 'my-panel-route/(:any)', 19 | 'action' => function($uid) { 20 | echo 'Hello from the panel! ' . $uid; 21 | } 22 | ) 23 | )); 24 | ``` 25 | 26 | It's often good to add some extra "protection". Below we check that the Panel exist and that a user is logged in. 27 | 28 | ```php 29 | if(class_exists('Panel') && site()->user()) { 30 | panel()->routes(array( 31 | array( 32 | 'pattern' => 'my-panel-route/(:any)', 33 | 'action' => function($uid) { 34 | echo 'Hello from the panel! ' . $uid; 35 | } 36 | ) 37 | )); 38 | } 39 | ``` 40 | 41 | **Source** 42 | 43 | https://github.com/pedroborges/kirby-autogit/blob/master/lib/routes.php -------------------------------------------------------------------------------- /docs/hooks.md: -------------------------------------------------------------------------------- 1 | # Hooks 2 | 3 | ## Custom hooks 4 | 5 | Maybe a hook is missing or you need a custom one for your plugin. Let's have a look at how it's done. 6 | 7 | **Add** a hook where you want the action to happend: 8 | 9 | ```php 10 | kirby()->hook('my_hook', function($arg1, $arg2) { 11 | echo $arg1; 12 | print_r($arg2); 13 | }); 14 | ``` 15 | 16 | **Trigger** the hook when you want the action to happend: 17 | 18 | ```php 19 | kirby()->trigger('my_hook', 20 | [ 21 | 'Argument 1', 22 | ['item' => 'Argument2'] 23 | ] 24 | ); 25 | ``` 26 | 27 | ### Reset triggered hooks 28 | 29 | When triggering a hook, it will only fire ones. If you trigger it again, it will not run. That's the behavior to prevent infinity loops. In some cases there is a need to trigger a hook more than ones. It's possible to reset the trigger array, like below. 30 | 31 | ```php 32 | kirby()::$triggered = array(); 33 | ``` 34 | 35 | - [Forum - Trigger hook does not fire oldpage](https://forum.getkirby.com/t/trigger-hook-does-not-fire-oldpage/8700/7) 36 | 37 | ## Sources 38 | 39 | - [Developer guide - Extension registry](https://getkirby.com/docs/developer-guide/plugins/registry) 40 | -------------------------------------------------------------------------------- /docs/panel-2/messages.md: -------------------------------------------------------------------------------- 1 | # Panel 2 - Messages 2 | 3 | There are `notify` which is a green message and `alert` which is a red error message. 4 | 5 | ## With hooks 6 | 7 | If you are inside the Panel and want to trigger a message, you can do that inside a hook. 8 | 9 | In both examples there is a redirect and in order for the message to work it needs to be there. In these cases it will redirect to the page it just created. 10 | 11 | ### Message 12 | 13 | ```php 14 | kirby()->hook('panel.page.create', function($page) { 15 | panel()->notify("Your page was created!"); 16 | panel()->redirect('pages/' . $page->id() . '/edit'); 17 | }); 18 | ``` 19 | 20 | ### Error message 21 | 22 | ```php 23 | kirby()->hook('panel.page.create', function($page) { 24 | panel()->alert("Error! Just kidding!"); 25 | panel()->redirect('pages/' . $page->id() . '/edit'); 26 | }); 27 | ``` 28 | 29 | ## Without hooks 30 | 31 | If you don't want to put the message into a hook you can use it for example directly into a field. 32 | 33 | ```php 34 | panel()->notify('Hello world!'); 35 | ``` 36 | 37 | or 38 | 39 | ```php 40 | panel()->error('Did not work!'); 41 | ``` 42 | 43 | **Sources** 44 | 45 | https://forum.getkirby.com/t/hooks-flash-message/6766/1 46 | https://forum.getkirby.com/t/trigger-panel-notification-message-from-field/3851/1 -------------------------------------------------------------------------------- /docs/thumb.md: -------------------------------------------------------------------------------- 1 | # Thumb 2 | 3 | ## toFile 4 | 5 | ### Old way 6 | 7 | How do you create a thumbnail with Kirby? 8 | 9 | **The most common is probably by using the `thumb` function like this:** 10 | 11 | ```php 12 | = thumb($page->image($page->my_image()), array('width' => 300)); ?> 13 | ``` 14 | 15 | https://getkirby.com/docs/cheatsheet/helpers/thumb 16 | 17 | We need to wrap everything with a `thumb` function. To use a particular filename, we also need to wrap `$page->my_image()` inside `$page->image()`, else it will pick the first image. It's not very straight forward. 18 | 19 | ### New way 20 | 21 | To use `toFile` is a "new" way of working with thumbs. It's in the [docs](https://getkirby.com/docs/cheatsheet/field-methods/toFile) but not very prominent. 22 | 23 | **It looks much simpler:** 24 | 25 | ```php 26 | = $page->my_image()->toFile()->resize(300); ?> 27 | ``` 28 | 29 | **To check if the file exists we can do this:** 30 | 31 | ```php 32 | = ($image = $page->my_image()->toFile()) ? $image->resize(300) : ''; ?> 33 | ``` 34 | 35 | In the above, we check if `$page->my_image()->toFile()` exists and if it does, put it into `$image`. Then `$image` is used to resize the thumb. If it does not match, don't write anything. It may look complicated, but this way we can get away with a oneliner. 36 | 37 | https://forum.getkirby.com/t/site-thumb-not-created/9267/2 -------------------------------------------------------------------------------- /docs/cache.md: -------------------------------------------------------------------------------- 1 | # Cache 2 | 3 | ## Partial cache 4 | 5 | ### Enable the cache 6 | 7 | In this case we want to enable the cache. The `cache.ignore` make sure no pages are cached. 8 | 9 | ```php 10 | c::set('cache', true); 11 | c::set('cache.ignore', ['*']); 12 | ``` 13 | 14 | ### `getCache` 15 | 16 | If the cache is already set, load data from the cache. If the cache is not set, return the data from the `setCache` function. 17 | 18 | ```php 19 | function getCache($key) { 20 | $cache = cache::get($key); 21 | if(!$cache) { 22 | $cache = setCache(); 23 | cache::set($key, $cache); 24 | } 25 | return $cache; 26 | } 27 | ``` 28 | 29 | ### `setCache` 30 | 31 | What is inside the `setCache` function is probably slow. That's why we need a cache for it. 32 | 33 | ```php 34 | function setCache() { 35 | return 'My data'; 36 | } 37 | ``` 38 | 39 | ### Function call 40 | 41 | The key is `my_cache`. If you change it a new cache file will be saved. 42 | 43 | ```php 44 | echo getCache('my_cache'); 45 | ``` 46 | 47 | - [Forum - Cache part of a page](https://forum.getkirby.com/t/cache-part-of-a-page/5199/1) 48 | 49 | ## Sources 50 | 51 | - [Developer guide - Caching](https://getkirby.com/docs/developer-guide/advanced/caching) 52 | - [Cheatcheet - Cache](https://getkirby.com/docs/cheatsheet/options/cache) 53 | - [Cheatcheet - Cache ignore](https://getkirby.com/docs/cheatsheet/options/cache-ignore) 54 | -------------------------------------------------------------------------------- /docs/extension-registry.md: -------------------------------------------------------------------------------- 1 | # Extension registry 2 | 3 | ## Custom registry set 4 | 5 | Maybe you need a custom registry for your plugin. 6 | 7 | **Put this code into a file that is loaded by a plugin, or autoloaded:** 8 | 9 | ```php 10 | set('type', 'name', __DIR__ . '/types/name.php'); 31 | echo $kirby->get('type', 'name'); 32 | ``` 33 | 34 | Change `type` to the name of your registry type name, but make sure everything is lowercase. Also change `name` to the name of your registry entry. 35 | 36 | - [Forum - How can I create an own registry of files or folders](https://forum.getkirby.com/t/how-can-i-create-an-own-registry-set-of-files-or-folder/6415) 37 | 38 | ## Sources 39 | 40 | - [Forum - How can I create an own registry of files or folders](https://forum.getkirby.com/t/how-can-i-create-an-own-registry-set-of-files-or-folder/6415) 41 | - [Developer guide - Extension registry](https://getkirby.com/docs/developer-guide/plugins/registry) 42 | -------------------------------------------------------------------------------- /docs/plugin.md: -------------------------------------------------------------------------------- 1 | # Plugin 2 | 3 | ## Force load plugins 4 | 5 | The `$plugin_name` is the plugin folder name: 6 | 7 | ```php 8 | kirby()->plugin($plugin_name); 9 | ``` 10 | 11 | It will only run once, not again by the core. 12 | 13 | ## Get loaded plugins 14 | 15 | ```php 16 | print_r( kirby()->plugins ); 17 | ``` 18 | 19 | ## Load plugin last 20 | 21 | Sometimes you might need to load your plugin last. It's not possible out of the box but when doing it like this it loads every plugin except your plugin first. It means your plugin will load last. Because a plugin will only be loaded once you don't need to worry about that the plugins will load mulitple times, they will only be loaded once. 22 | 23 | **Source:** https://forum.getkirby.com/t/load-your-plugin-last/5718 24 | 25 | ```php 26 | function loadOtherPluginsFirst() { 27 | $folders = glob( kirby()->roots()->plugins() . DS . '*', GLOB_ONLYDIR ); 28 | 29 | if( ! empty( $folders ) ) { 30 | foreach( $folders as $folder ) { 31 | $name = pathinfo($folder, PATHINFO_FILENAME); 32 | 33 | if( $name != 'my-plugin') { 34 | kirby()->plugin( $name ); 35 | } 36 | } 37 | } 38 | } 39 | ``` 40 | 41 | ## Plugin has loaded 42 | 43 | ```php 44 | if( kirby()->plugin('modules') ) { 45 | echo 'The Modules plugin has been loaded'; 46 | } 47 | ``` 48 | 49 | **Be aware:** If the plugin exist, but has not been loaded it will force load it and return `true` if exists. 50 | 51 | ## Plugin creation 52 | 53 | - [Boiler readme - Preview](plugin/readme.md) 54 | - [Boiler readme - Download](https://raw.githubusercontent.com/jenstornell/kirby-secrets/master/docs/plugin/readme.md) 55 | - [Plugin best practices](plugin/best-practices.md) 56 | -------------------------------------------------------------------------------- /docs/panel-2/blueprints.md: -------------------------------------------------------------------------------- 1 | # Panel 2 - Blueprints 2 | 3 | ## Special characters 4 | 5 | To allow special characters like quotes, always wrap the whole block with quotes and then escape the quotes inside it with `\`. 6 | 7 | ```text 8 | fields: 9 | my_field: 10 | title: "A field title with \"Quotes\"" 11 | type: text 12 | ``` 13 | 14 | - [Forum - Special characters breaking blueprint content in the panel](https://forum.getkirby.com/t/special-characters-breaking-blueprint-content-in-the-panel/3748/3) 15 | 16 | ## Field definition subfolders 17 | 18 | You can create global field definitions in subfolders. It's especially good if you have many global field definitions and it's starting to be messy. 19 | 20 | ```text 21 | fields: 22 | myfield: subfolder/definition 23 | ``` 24 | 25 | - [Kirby Courses - 10 Tips & Hidden Features](https://www.youtube.com/watch?v=YjbbcKWOLs8) 26 | 27 | ## Get all blueprints 28 | 29 | Especially for plugins it can sometimes be useful to be able to get all the blueprints. Let's see how that is done. 30 | 31 | ```php 32 | $blueprints = kirby()->get('blueprint'); 33 | print_r($blueprints); 34 | ``` 35 | 36 | - [Get the blueprint in a panel field from another page](https://forum.getkirby.com/t/get-the-blueprint-in-the-a-panel-field-from-another-page/4877/5) 37 | 38 | ## Sources 39 | 40 | - [Forum - Special characters breaking blueprint content in the panel](https://forum.getkirby.com/t/special-characters-breaking-blueprint-content-in-the-panel/3748/3) 41 | - [Kirby Courses - 10 Tips & Hidden Features](https://www.youtube.com/watch?v=YjbbcKWOLs8) 42 | - [Get the blueprint in a panel field from another page](https://forum.getkirby.com/t/get-the-blueprint-in-the-a-panel-field-from-another-page/4877/5) -------------------------------------------------------------------------------- /docs/vue.md: -------------------------------------------------------------------------------- 1 | # Kirby and Vue 2 | 3 | Vue is a js framework and if your site is not a js web app, you probably don't need it. 4 | 5 | ## Footer 6 | 7 | Here is a starting point placed in the `footer.php`, which uses [Vue](https://vuejs.org/) and [Vue Router](https://router.vuejs.org/en/). 8 | 9 | ```html 10 | 11 | 12 | 13 |