Create your own plugins & themes

Below is our developer documentation, you may also refer to Pico’s class documentation.

Please note: Unfortunately we didn’t have the time to finish the developer docs. We’ll finish this page as soon as possible, so please stay in touch.

If you’re searching for information about how to upgrade your plugin to Pico 1.0 (we appreciate that!), you can find basic information in the Pull Request message of #252 and its comments (especially this comment). The changes were wide-ranging, so until we finish the docs (help is appreciated!), we advise you to really read the Pull Request message and, at least, skim through all comments.

If you have a question about one of the new features of Pico 1.0, please comment on #252 (although the Pull Request is closed!). If you have a problem with upgrading your plugin, please do the same. If you experience a problem with Pico in general, please refer to the upgrade page. If this doesn’t answer your question, please notice the “Getting help” section of the docs and open a new Issue on GitHub.


Creating your own content for Pico is easy.

Inside the root Pico folder, all themes reside in the themes directory, and all plugins in the plugins directory.

Pico Core

It’s generally not a good idea to make modifications to the core of Pico. If you are looking to add or change functionality, can it be accomplished with a plugin?

If not, and you want to contribute to Pico’s core please refer to our on GitHub.


At the heart of customizing Pico is a plugin. You can ‘hook-in’ to the Pico engine at many different times during the rendering of your site and its content. You will find a full example template in plugins/DummyPlugin.php to get you started on building some great stuff. Otherwise, keep reading to learn how to create your first plugin!

Officially tested plugins can be found at, but there are many awesome third-party plugins out there! A good start point for discovery is our Wiki.

Your First Plugin

1. To get started, navigate to your plugins directory


2. Create a new folder and name it your desired name using CammelCase


Note: It’s not necessary to create the folder, if you do not have assets to include, you can simply skip this step and continue to Step 3

3. Next, you should copy DummyPlugin.php inside your newly created folder and give it the same name as you did the folder


4. You will need to name the class the same as the folder and the .php file


5. From here, you will be able to hook-in to Pico’s processing

Choose an event that makes sense for your situation. Do you need to load configuration values? onConfigLoaded. You need to modify the content of the page before it is rendered by markdown? onPageRendering. Etc… Plugin developers shouldn’t manipulate data in “wrong” events, this could lead to unexpected behavior.

Note: Don’t forget to set your plugins enabled/disabled state, either by default or through your sites config/config.php file.

Migrating from 0.X to 1.0


Initialization of Pico now works completely different: rather than defining constants (which are probably conflicting with other applications…), Pico now expects its paths to be passed as parameters to Pico’s constructor method. The constructor doesn’t start Pico’s processing anymore, you now have to call the Pico::run() method, which returns the parsed page contents instead of directly echoing them. The PicoDeprecated plugin defines the now deprecated constants ROOT_DIR, LIB_DIR etc., so old plugins can still use them. Those constants are defined before reading config.php in Pico’s root folder, so upgrading users usually aren’t bothered with e.g. a PHP Notice: Use of undefined constant ROOT_DIR - assumed 'ROOT_DIR' error when using ROOT_DIR in their config.php (so: no BC break). This change is reflected in the new index.php file.

New users don’t need the constants anymore, relative paths are now always interpreted to be relative to Pico’s root directory, so $config['content_dir'] = 'content'; is always sufficient (previously this was depending on the webserver config). All these changes are supposed to improve Pico’s interoperability with other applications and allows developers to integrate Pico in other applications, therefore there is a newly added Pico::setConfig() method to even make the use of a config.php optional.

Migrating plugins

A whole new plugin system has been implemented while maintaining full backward compatibility. See the class docs of PicoPluginInterface for details. The new event system supports plugin dependencies as well as some new events. It was necessary to reliably distinct between old and new events, so all events were renamed. The new PicoDeprecated plugin is crucial for backward compatibility, it’s enabled on demand. Refer to its class docs for details.

You will be able to set an enabled/disabled state by default as well. If you have previously created a plugin for Pico, it is HIGHLY recommended that you update your class to extend from AbstractPicoPlugin and use the new events to avoid activating the PicoDeprecated plugin.

Event … triggers the deprecated event
onPluginsLoaded plugins_loaded()
onConfigLoaded config_loaded($config)
onRequestUrl request_url($url)
onContentLoading before_load_content($file)
onContentLoaded after_load_content($file, $rawContent)
on404ContentLoading before_404_load_content($file)
on404ContentLoaded after_404_load_content($file, $rawContent)
onMetaHeaders before_read_file_meta($headers)
onMetaParsed file_meta($meta)
onContentParsing before_parse_content($rawContent)
onContentParsed after_parse_content($content)
onContentParsed content_parsed($content)
onSinglePageLoaded get_page_data($pages, $meta)
onPagesLoaded get_pages($pages, $currentPage, $previousPage, $nextPage)
onTwigRegistration before_twig_register()
onPageRendering before_render($twigVariables, $twig, $templateName)
onPageRendered after_render($output)

Plugin Wiki

Whether you have an awesome new plugin you’ve created and you’re dying to share, or if you’re a new plugin developer and you’re looking for some inspiration– our Pico Plugin Wiki is here to help!

GitHub Pages - This page was generated from 9164cea2f254e611a1de2311775f6d0ee370c838 at 2022-08-10 21:26:48 +0000

Pico was made by Gilbert Pellegrom and is maintained by The Pico Community. Released under the MIT license.