Pico Documentation

Pico is a flat file CMS, this means there is no administration backend or database to deal with.
You simply create .md files in the “content” folder and that becomes a page.


You can install Pico either using a pre-bundled release or with composer. Pico is also available on Packagist.org and may be included in other projects via composer require picocms/pico. Pico requires PHP 5.3+

Using a pre-bundled release

Just download the latest Pico release and upload all files to the httpdocs directory (e.g. /var/www/html) of your server.


Step 1 - for users

Download the source code of Pico’s latest release, upload all files to the httpdocs directory (e.g. /var/www/html) of your server and navigate to the upload directory using a shell.

Step 1 - for developers

Open a shell and navigate to the desired install directory of Pico within the httpdocs directory (e.g. /var/www/html) of your server. You can now clone Pico’s Git repository as follows:

$ git clone https://github.com/picocms/Pico.git .

Please note that this gives you the current development version of Pico, what is likely unstable and not ready for production use!

Step 2

Download composer and run it with the install option:

$ curl -sS https://getcomposer.org/installer | php
$ php composer.phar install

Upgrade Learn more…

Upgrading Pico is very easy: You just have to replace all of Pico’s files - that’s it! Nevertheless you should always create a backup of your Pico installation before upgrading.

Pico follows Semantic Versioning 2.0 and uses version numbers like MAJOR.MINOR.PATCH. When we update…

  • the PATCH version (e.g. 1.0.0 to 1.0.1), we made backwards-compatible bug fixes. It’s then sufficient to extract Pico’s latest release to your existing installation directory and overwriting all files. Alternatively you can either use the source code of Pico’s latest release or pull from Pico’s Git repository, but are then required to update Pico’s composer dependencies manually by running php composer.phar update.

  • the MINOR version (e.g. 1.0 to 1.1), we added functionality in a backwards-compatible manner, but anyway recommend you to “install” Pico newly. Backup all of your files, empty your installation directory and install Pico as elucidated above. You can then copy your config/config.php and content directory without any change. If applicable, you can also copy the folder of your custom theme within the themes directory. Provided that you’re using plugins, also copy all of your plugins from the plugins directory.

  • the MAJOR version (e.g. 1.0 to 2.0), we made incompatible API changes. We will then provide a appropriate upgrade tutorial.

Upgrading Pico 0.8 or 0.9 to Pico 1.0 is a special case. The new PicoDeprecated plugin ensures backwards compatibility, so you basically can follow the above upgrade instructions as if we updated the MINOR version. However, we recommend you to take some further steps to confine the necessity of PicoDeprecated as far as possible. For more information about what has changed with Pico 1.0 and a step-by-step upgrade tutorial, please refer to the upgrade page of our website.


You have nothing to consider specially, simply navigate to your Pico install using your favorite web browser. Pico’s default contents will explain how to use your brand new, stupidly simple, blazing fast, flat file CMS.

You don’t have a web server?

Starting with PHP 5.4 the easiest way to try Pico is using the built-in web server of PHP. Please note that PHPs built-in web server is for development and testing purposes only!

Step 1

Navigate to Pico’s installation directory using a shell.

Step 2

Start PHPs built-in web server:

$ php -S

Step 3

Access Pico from http://localhost:8080.

Creating Content

Pico is a flat file CMS. This means there is no administration backend or database to deal with. You simply create .md files in the content folder and those files become your pages. For example, creating a file called index.md will make it show as your main landing page.

When you install Pico, it comes with a content-sample folder. Inside this folder is a sample website that will display until you add your own content. You should create your own content folder in Pico’s root directory and place your files there. No configuration is required, Pico will automatically use the content folder if it exists.

If you create a folder within the content folder (e.g. content/sub) and put an index.md inside it, you can access that folder at the URL http://example.com/?sub. If you want another page within the sub folder, simply create a text file with the corresponding name and you will be able to access it (e.g. content/sub/page.md is accessible from the URL http://example.com/?sub/page). Below we’ve shown some examples of locations and their corresponding URLs:

Physical Location URL
content/index.md /
content/sub.md ?sub (not accessible, see below)
content/sub/index.md ?sub (same as above)
content/sub/page.md ?sub/page
content/a/very/long/url.md ?a/very/long/url

If a file cannot be found, the file content/404.md will be shown. You can add 404.md files to any directory. So, for example, if you wanted to use a special error page for your blog, you could simply create content/blog/404.md.

As a common practice, we recommend you to separate your contents and assets (like images, downloads, etc.). We even deny access to your content directory by default. If you want to use some assets (e.g. a image) in one of your content files, you should create an assets folder in Pico’s root directory and upload your assets there. You can then access them in your markdown using %base_url%/assets/ for example: ![Image Title](%base_url%/assets/image.png)

Text File Markup

Text files are marked up using Markdown and Markdown Extra. They can also contain regular HTML.

At the top of text files you can place a block comment and specify certain meta attributes of the page using YAML (the “YAML header”). For example:

Title: Welcome
Description: This description will go in the meta description tag
Author: Joe Bloggs
Date: 2013/01/01
Robots: noindex,nofollow
Template: index

These values will be contained in the {{ meta }} variable in themes (see below).

There are also certain variables that you can use in your text files:

  • %site_title% - The title of your Pico site
  • %base_url% - The URL to your Pico site; internal links can be specified using %base_url%?sub/page
  • %theme_url% - The URL to the currently used theme
  • %meta.*% - Access any meta variable of the current page, e.g. %meta.author% is replaced with Joe Bloggs


Pico is not blogging software - but makes it very easy for you to use it as a blog. You can find many plugins out there implementing typical blogging features like authentication, tagging, pagination and social plugins. See the below Plugins section for details.

If you want to use Pico as a blogging software, you probably want to do something like the following:

  1. Put all your blog articles in a separate blog folder in your content directory. All these articles should have both a Date and Template meta header, the latter with e.g. blog-post as value (see Step 2).
  2. Create a new Twig template called blog-post.twig (this must match the Template meta header from Step 1) in your theme directory. This template probably isn't very different from your default index.twig, it specifies how your article pages will look like.
  3. Create a blog.md in your content folder and set its Template meta header to e.g. blog. Also create a blog.twig in your theme directory. This template will show a list of your articles, so you probably want to do something like this:
    {% for page in pages|sort_by("time")|reverse %}
        {% if page.id starts with "blog/" %}
            <div class="post">
                <h3><a href="{{ page.url }}">{{ page.title }}</a></h3>
                <p class="date">{{ page.date_formatted }}</p>
                <p class="excerpt">{{ page.description }}</p>
        {% endif %}
    {% endfor %}
  4. Make sure to exclude blog articles from your page navigation. You can achieve this by adding {% if not (page.id starts with "blog/") %}...{% endif %} to the navigation loop ({% for page in pages %}...{% endfor %}) in your theme's index.twig.


Pico is highly customizable in two different ways: On the one hand you can change Pico’s appearance by using themes, on the other hand you can add new functionality by using plugins. Doing the former includes changing Pico’s HTML, CSS and JavaScript, the latter mostly consists of PHP programming.

This is all Greek to you? Don’t worry, you don’t have to spend time on these techie talk - it’s very easy to use one of the great themes or plugins others developed and released to the public. Please refer to the next sections for details.


You can create themes for your Pico installation in the themes folder. Check out the default theme for an example. Pico uses Twig for template rendering. You can select your theme by setting the $config['theme'] option in config/config.php to the name of your theme folder.

All themes must include an index.twig (or index.html) file to define the HTML structure of the theme. Below are the Twig variables that are available to use in your theme. Please note that paths (e.g. {{ base_dir }}) and URLs (e.g. {{ base_url }}) don’t have a trailing slash.

  • {{ config }} - Contains the values you set in config/config.php (e.g. {{ config.theme }} becomes default)
  • {{ base_dir }} - The path to your Pico root directory
  • {{ base_url }} - The URL to your Pico site; use Twigs link filter to specify internal links (e.g. {{ "sub/page"|link }}), this guarantees that your link works whether URL rewriting is enabled or not
  • {{ theme_dir }} - The path to the currently active theme
  • {{ theme_url }} - The URL to the currently active theme
  • {{ rewrite_url }} - A boolean flag indicating enabled/disabled URL rewriting
  • {{ site_title }} - Shortcut to the site title (see config/config.php)
  • {{ meta }} - Contains the meta values from the current page
    • {{ meta.title }}
    • {{ meta.description }}
    • {{ meta.author }}
    • {{ meta.date }}
    • {{ meta.date_formatted }}
    • {{ meta.time }}
    • {{ meta.robots }}
  • {{ content }} - The content of the current page after it has been processed through Markdown)
  • {{ pages }} - A collection of all the content pages in your site
    • {{ page.id }} - The relative path to the content file (unique ID)
    • {{ page.url }} - The URL to the page
    • {{ page.title }} - The title of the page (YAML header)
    • {{ page.description }} - The description of the page (YAML header)
    • {{ page.author }} - The author of the page (YAML header)
    • {{ page.time }} - The timestamp derived from the Date header
    • {{ page.date }} - The date of the page (YAML header)
    • {{ page.date_formatted }} - The formatted date of the page
    • {{ page.raw_content }} - The raw, not yet parsed contents of the page; use Twigs content filter to get the parsed contents of a page by passing its unique ID (e.g. {{ "sub/page"|content }})
    • {{ page.meta }}- The meta values of the page
  • {{ prev_page }} - The data of the previous page (relative to current_page)
  • {{ current_page }} - The data of the current page
  • {{ next_page }} - The data of the next page (relative to current_page)
  • {{ is_front_page }} - A boolean flag for the front page

Pages can be used like the following:

<ul class="nav">
    {% for page in pages %}
        <li><a href="{{ page.url }}">{{ page.title }}</a></li>
    {% endfor %}

Additional to Twigs extensive list of filters, functions and tags, Pico also provides some useful additional filters to make theming easier. You can parse any Markdown string to HTML using the markdown filter. Arrays can be sorted by one of its keys or a arbitrary deep sub-key using the sort_by filter (e.g. {% for page in pages|sort_by([ 'meta', 'nav' ]) %}...{% endfor %} iterates through all pages, ordered by the nav meta header; please note the [ 'meta', 'nav' ] part of the example, it instructs Pico to sort by page.meta.nav). You can return all values of a given key or key path of an array using the map filter (e.g. {{ pages|map("title") }} returns all page titles).

You can use different templates for different content files by specifying the Template meta header. Simply add e.g. Template: blog-post to a content file and Pico will use the blog-post.twig file in your theme folder to render the page.

You don’t have to create your own theme if Pico’s default theme isn’t sufficient for you, you can use one of the great themes third-party developers and designers created in the past. As with plugins, you can find themes in our Wiki and here on our website.


Plugins for users

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

Pico makes it very easy for you to add new features to your website. Simply upload the files of the plugin to the plugins/ directory and you’re done. Depending on the plugin you’ve installed, you may have to go through some more steps (e.g. specifying config variables), the plugin docs or README file will explain what to do.

Plugins which were written to work with Pico 1.0 can be enabled and disabled through your config/config.php. If you want to e.g. disable the PicoExcerpt plugin, add the following line to your config/config.php: $config['PicoExcerpt.enabled'] = false;. To force the plugin to be enabled replace false with true.

Plugins for developers

You’re a plugin developer? We love you guys! You can find tons of information about how to develop plugins at http://picocms.org/development/. If you’ve developed a plugin for Pico 0.9 or older, you probably want to upgrade it to the brand new plugin system introduced with Pico 1.0. Please refer to the upgrade section of the docs.


You can override the default Pico settings (and add your own custom settings) by editing config/config.php in the Pico directory. For a brief overview of the available settings and their defaults see config/config.php.template. To override a setting, copy config/config.php.template to config/config.php, uncomment the setting and set your custom value.

URL Rewriting

Pico’s default URLs (e.g. http://example.com/pico/?sub/page) already are very user-friendly. Additionally, Pico offers you a URL rewrite feature to make URLs even more user-friendly (e.g. http://example.com/pico/sub/page).


If you’re using the Apache web server, URL rewriting should be enabled automatically. If you get an error message from your web server, please make sure to enable the mod_rewrite module. Assuming rewritten URLs work, but Pico still shows no rewritten URLs, force URL rewriting by setting $config['rewrite_url'] = true; in your config/config.php.

Nginx Learn more…

If you’re using Nginx, you can use the following configuration to enable URL rewriting (lines 5 to 8) and denying access to Pico’s internal files (lines 1 to 3). You’ll need to adjust the path (/pico on lines 1, 5 and 7) to match your installation directory. Additionally, you’ll need to enable URL rewriting by setting $config['rewrite_url'] = true; in your config/config.php.

location ~ /pico/(\.htaccess|\.git|config|content|content-sample|lib|vendor|CHANGELOG\.md|composer\.(json|lock)) {
	return 404;

location ~ ^/pico(.*) {
	index index.php;
	try_files $uri $uri/ /pico/index.php?$1&$args;

This configuration should provide the bare minimum you need for Pico. Nginx is a very extensive subject. If you have any trouble, please read through our page on Nginx Configuration. For additional assistance, please refer to the “Getting Help” section below.

Getting Help

Getting Help as a user

If you want to get started using Pico, please refer to the user docs (you’re reading them right now!). Please read the upgrade notes if you want to upgrade from Pico 0.8 or 0.9 to Pico 1.0. You can find officially supported plugins and themes here on our website. A greater choice of third-party plugins and themes can be found in our Wiki on the plugins or themes pages respectively. If you want to create your own plugin or theme, please refer to the “Getting Help as a developer” section below.

Getting Help as a developer

If you’re a developer, please refer to the “Contribute” section below and our contribution guidelines. To get you started with creating a plugin or theme, please read the dev docs on our website.

You still need help or experience a problem with Pico?

When the docs can’t answer your question, you can get help by joining us on #picocms on Freenode IRC. When you’re experiencing problems with Pico, please don’t hesitate to create a new Issue on GitHub. Concerning problems with plugins or themes, please refer to the website of the developer of this plugin or theme.

Before creating a new Issue, please make sure the problem wasn’t reported yet using GitHubs search engine. Please describe your issue as clear as possible and always include the Pico version you’re using. Provided that you’re using plugins, include a list of them too. We need information about the actual and expected behavior, the steps to reproduce the problem, and what steps you have taken to resolve the problem by yourself (i.e. your own troubleshooting).


You want to contribute to Pico? We really appreciate that! You can help make Pico better by contributing code or reporting issues, but please take note of our contribution guidelines. In general you can contribute in three different areas:

  1. Plugins & Themes: You’re a plugin developer or theme designer? We love you guys! You can find tons of information about how to develop plugins and themes at http://picocms.org/development/. If you have created a plugin or theme, please add it to our Wiki, either on the plugins or themes page. You may also Submit it to our website, where it’ll be displayed on the official plugin or theme pages!

  2. Documentation: We always appreciate people improving our documentation. You can either improve the inline user docs or the more extensive user docs on our website. You can also improve the docs for plugin and theme developers. Simply fork Pico from GitHub, change the Markdown files and open a pull request.

  3. Pico’s Core: The supreme discipline is to work on Pico’s Core. Your contribution should help every Pico user to have a better experience with Pico. If this is the case, fork Pico from GitHub and open a pull request. We look forward to your contribution!

GitHub Pages - This page was generated from 7b7131dfe9ba7b4f781b7bab551332c4e9ee8338 at 2018-05-02 09:04:50 +0000

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