diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..a7d81736 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +# Linux +*~ +*.swp + +# Windows +Thumbs.db +desktop.ini + +# Mac OS X +.DS_Store +._* diff --git a/_docs/config.md b/_docs/config.md index 522695c6..51c29673 100644 --- a/_docs/config.md +++ b/_docs/config.md @@ -14,11 +14,11 @@ nav: 5 Configuring Pico really is stupidly simple: Just create a `config/config.yml` to override the default Pico settings (and add your own custom settings). Take a look at the [`config/config.yml.template`][ConfigTemplate] for a brief overview of the available settings and their defaults. To override a setting, simply copy the line from `config/config.yml.template` to `config/config.yml` and set your custom value. -But we didn't stop there. Rather than having just a single config file, you can use a arbitrary number of config files. Simply create a `.yml` file in Pico's `config` dir and you're good to go. This allows you to add some structure to your config, like a separate config file for your theme (`config/my_theme.yml`). +But we didn't stop there. Rather than having just a single config file, you can use an arbitrary number of config files. Simply create a `.yml` file in Pico's `config` dir, and you're good to go. This allows you to add some structure to your config, like a separate config file for your theme (`config/my_theme.yml`). -Please note that Pico loads config files in a special way you should be aware of. First of all it loads the main config file `config/config.yml`, and then any other `*.yml` file in Pico's `config` dir in alphabetical order. The file order is crucial: Config values which have been set already, cannot be overwritten by a succeeding file. For example, if you set `site_title: Pico` in `config/a.yml` and `site_title: My awesome site!` in `config/b.yml`, your site title will be "Pico". +Please note that Pico loads config files in a special way you should be aware of. It loads the main config file `config/config.yml`, and then any other `*.yml` file in Pico's `config` dir in alphabetical order. The file order is crucial: Config values which have been set already, cannot be overwritten by a succeeding file. For example, if you set `site_title: Pico` in `config/a.yml` and `site_title: My awesome site!` in `config/b.yml`, your site title will be "Pico". -Since YAML files are plain text files, users might read your Pico config by navigating to `https://example.com/pico/config/config.yml`. This is no problem in the first place, but might get a problem if you use plugins that require you to store security-relevant data in the config (like credentials). Thus you should *always* make sure to configure your webserver to deny access to Pico's `config` dir. Just refer to the ["URL Rewriting" section below][UrlRewriting]. By following the instructions, you will not just enable URL rewriting, but also deny access to Pico's `config` dir. +Since YAML files are plain text files, users might read your Pico config by navigating to `https://example.com/pico/config/config.yml`. This is no problem in the first place, but might get a problem if you use plugins that require you to store security-relevant data in the config (like credentials). Thus, you should *always* make sure to configure your webserver to deny access to Pico's `config` dir. Just refer to the ["URL Rewriting" section below][UrlRewriting]. By following the instructions, you will not just enable URL rewriting, but also deny access to Pico's `config` dir. ### URL Rewriting diff --git a/_docs/contributing.md b/_docs/contributing.md index 0f55b0ee..392e2791 100644 --- a/_docs/contributing.md +++ b/_docs/contributing.md @@ -8,7 +8,7 @@ nav: 7 You want to contribute to Pico? We really appreciate that! You can help make Pico better by [contributing code][PullRequests] or [reporting issues][Issues], but please take note of our [contribution guidelines][ContributionGuidelines]. 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 [{{ site.github.url }}/development/][PluginDocs]. If you have created a plugin, feel free to add it to our [plugins][WikiPlugins] wiki page. You may also [Submit][] plugins and themes to our website, where they'll be displayed on the official [plugin][OfficialPlugins] or [theme][OfficialThemes] pages! +1. Plugins & Themes: You're a plugin developer or theme designer? We love you folks! To get you started with creating a plugin or theme, check out Pico's [`DummyPlugin`][PicoDummyPlugin], and [Pico's default theme][PicoThemeGit]. If you have created a plugin or theme, please add it to our [Wiki][] and [Submit][] it to our website, where it'll be displayed on the official [plugin][OfficialPlugins] or [theme][OfficialThemes] pages! 2. Documentation: We always appreciate people improving our documentation. You can either improve the [inline user docs][EditInlineDocs] or the more extensive [user docs on our website][EditUserDocs]. You can also improve the [docs for plugin and theme developers][EditDevDocs]. Simply fork our website's Git repository from [{{ site.gh_pages_url }}][GitHubWebsite], change the Markdown files and open a [pull request][PullRequestsWebsite]. @@ -29,6 +29,8 @@ You don't have time to contribute code to Pico, but still want to "stand a coffe [Submit]: {{ site.github.url }}/in-depth/submission_guidelines [OfficialPlugins]: {{ site.github.url }}/plugins/ [OfficialThemes]: {{ site.github.url }}/themes/ +[PicoThemeGit]: https://github.com/picocms/pico-theme +[PicoDummyPlugin]: https://github.com/picocms/Pico/blob/master/plugins/DummyPlugin.php [EditInlineDocs]: {{ site.gh_project_url }}/edit/{{ site.gh_project_branch }}/content-sample/index.md [EditUserDocs]: {{ site.gh_pages_url }}/tree/{{ site.gh_pages_branch }}/_docs [EditDevDocs]: {{ site.gh_pages_url }}/tree/{{ site.gh_pages_branch }}/_development diff --git a/_docs/creating-content.md b/_docs/creating-content.md index eb1b7045..bb8d29c7 100644 --- a/_docs/creating-content.md +++ b/_docs/creating-content.md @@ -45,7 +45,7 @@ If you create a folder within the content directory (e.g. `content/sub`) and put content/a/very/long/url.md - ?a/very/long/url + ?a/very/long/url (doesn't exist) @@ -54,13 +54,13 @@ If a file cannot be found, the file `content/404.md` will be shown. You can add Pico strictly separates contents of your website (the Markdown files in your `content` directory) and how these contents should be displayed (the Twig templates in your `themes` directory). However, not every file in your `content` directory might actually be a distinct page. For example, some themes (including Pico's default theme) use some special "hidden" file to manage meta data (like `_meta.md` in Pico's sample contents). Some other themes use a `_footer.md` to represent the contents of the website's footer. The common point is the `_`: all files and directories prefixed by a `_` in your `content` directory are hidden. These pages can't be accessed from a web browser, Pico will show a 404 error page instead. -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, files, use Pico's `assets` folder. You can then access them in your Markdown using the `%assets_url%` placeholder, for example: `![Image Title](%assets_url%/image.png)` +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. an image) in one of your content files, use Pico's `assets` folder. You can then access them in your Markdown using the `%assets_url%` placeholder, for example: `![Image Title](%assets_url%/image.png)` ### Text File Markup Text files are marked up using [Markdown][] and [Markdown Extra][MarkdownExtra]. 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: +At the top of text files you can place a block comment and specify certain meta attributes of the page using [YAML][] (the "YAML Front Matter", or "YAML header"). For example:
---
 Title: Welcome
@@ -71,12 +71,12 @@ Robots: noindex,nofollow
 Template: index
 ---
-These values will be contained in the `{% raw %}{{ meta }}{% endraw %}` variable in themes (see below). Meta headers can sometimes have special functions. For example: +These values will be contained in the `{% raw %}{{ meta }}{% endraw %}` variable in themes (see below). Meta headers can sometimes have special functions. For example: -- `Date` tells Pico when the page was created, letting you sort your pages not just alphabetically, but by date. -- `Template` controls what Twig template Pico uses to display the page. For example, if you add `Template: blog`, Pico uses `blog.twig`. +- `Date` tells Pico when the page was created, letting you sort your pages not just alphabetically, but by date. Pico furthermore not only passes through the `Date` meta header, but rather evaluates it to really "understand" when this page was created. +- `Template` controls what Twig template Pico uses to display the page. For example, if you add `Template: blog`, Pico uses `blog.twig` to render this page instead of the default `index.twig`. -You can create your own meta attributes and use them in your content or when modifying a theme. For example, if you create an `Order` attribute, you can set `pages_order_by_meta: Order` and `pages_order_by: meta ` in `config.yml` to sort pages in the navigation menu in a custom order. +You can even create your own meta attributes and use them in your content or when modifying a theme. For example, if you create an `Order` attribute, you can set `pages_order_by_meta: Order` and `pages_order_by: meta ` in `config.yml` to sort pages in the navigation menu in a custom order. In an attempt to separate contents and styling, we recommend you to not use inline CSS in your Markdown files. You should rather add appropriate CSS classes to your theme. For example, you might want to add some CSS classes to your theme to rule how much of the available space a image should use (e.g. `img.small { width: 80%; }`). You can then use these CSS classes in your Markdown files, for example: `![Image Title](%assets_url%/image.png) {.small}` @@ -89,12 +89,13 @@ There are also certain variables that you can use in your text files: * `%themes_url%` - The URL to Pico's `themes` directory; don't confuse this with `%theme_url%` * `%plugins_url%` - The URL to Pico's `plugins` directory * `%version%` - Pico's current version string (e.g. `2.0.0`) +* `%page_id%`, `%page_url%`, and `%page_path%` - The current page's ID (e.g. `sub/index` for `content/sub/index.md`, `sub/page` for `content/sub/page.md`, …), its URL (`sub` resp. `sub/page` in our examples), or its directory path (`sub` in both examples) respectively * `%meta.*%` - Access any meta variable of the current page, e.g. `%meta.author%` is replaced with `Joe Bloggs` -* `%config.*%` - Access any scalar config variable, e.g. `%config.theme%` is replaced with `default` +* `%config.*%` - Access any scalar config variable, e.g. `%config.theme%` is replaced by `default` ### Blogging -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. +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 "Plugins" section below for details. If you want to use Pico as a blogging software, you probably want to do something like the following: @@ -103,17 +104,19 @@ If you want to use Pico as a blogging software, you probably want to do somethin Put all your blog articles in a separate blog folder in your content directory. All these articles should have a Date meta header.
  • - Create a blog.md or blog/index.md in your content directory. Add Template: blog-index to the YAML header of this page. It will later show a list of all your blog articles (see step 3). + Create a blog.md or blog/index.md in your content directory. Add Template: blog to the YAML header of this page. It will later show a list of all your blog articles (see step 3).
  • - Create the new Twig template blog-index.twig (the file name must match the Template meta header from Step 2) in your theme directory. This template probably isn't very different from your default index.twig (i.e. copy index.twig), it will create a list of all your blog articles. Add the following Twig snippet to blog-index.twig near {% raw %}{{ content }}{% endraw %}: - -{% raw %}
    {% for page in pages("blog")|sort_by("time")|reverse if not page.hidden %}
    -    <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>
    -    </div>
    +        Create the new Twig template blog.twig (the file name must match the Template meta header from Step 2) in your theme directory. This template probably isn't very different from your default index.twig (i.e. copy index.twig), it will create a list of all your blog articles. Add the following Twig snippet to blog.twig near {% raw %}{{ content }}{% endraw %}:
    +
    +{% raw %}
    {% for page in pages("blog")|sort_by("time")|reverse %}
    +    {% if not page.hidden %}
    +        <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>
    +        </div>
    +    {% endif %}
     {% endfor %}
    {% endraw %}
  • diff --git a/_docs/customization.md b/_docs/customization.md index 1545c980..53f99cec 100644 --- a/_docs/customization.md +++ b/_docs/customization.md @@ -73,28 +73,29 @@ There are several ways to access Pico's pages list. You can access the current p Pico's `pages()` function is the best way to access all of your site's pages. It uses Pico's page tree to easily traverse a subset of Pico's pages list. It allows you to filter pages and to build recursive menus (like dropdowns). By default, `pages()` returns a list of all main pages (e.g. `content/page.md` and `content/sub/index.md`, but not `content/sub/page.md` or `content/index.md`). If you want to return all pages below a specific folder (e.g. `content/blog/`), pass the folder name as first parameter to the function (e.g. `pages("blog")`). Naturally you can also pass variables to the function. For example, to return a list of all child pages of the current page, use `pages(current_page.id)`. Check out the following code snippet: {% raw %}
    <section class="articles">
    -    {% for page in pages(current_page.id) if not page.hidden %}
    -        <article>
    -            <h2><a href="{{ page.url }}">{{ page.title }}</a></h2>
    -            {{ page.id|content }}
    -        </article>
    +    {% for page in pages(current_page.id) %}
    +        {% if not page.hidden %}
    +            <article>
    +                <h2><a href="{{ page.url }}">{{ page.title }}</a></h2>
    +                {{ page.id|content }}
    +            </article>
    +        {% endif %}
         {% endfor %}
     </section>
    {% endraw %} The `pages()` function is very powerful and also allows you to return not just a page's child pages by passing the `depth` and `depthOffset` params. For example, if you pass `pages(depthOffset=-1)`, the list will also include Pico's main index page (i.e. `content/index.md`). This one is commonly used to create a theme's main navigation. If you want to learn more, head over to Pico's complete [`pages()` function documentation][FeaturesPagesFunction]. -If you want to access the data of a particular page, use Pico's `pages` variable. Just take `content/_meta.md` in Pico's sample contents for an example: `content/_meta.md` contains some meta data you might want to use in your theme. If you want to output the page's `tagline` meta value, use `{% raw %}{{ pages["_meta"].meta.logo }}{% endraw %}`. Don't ever try to use Pico's `pages` variable as an replacement for Pico's `pages()` function. Its usage looks very similar, it will kinda work and you might even see it being used in old themes, but be warned: It slows down Pico. Always use Pico's `pages()` function when iterating Pico's page list instead (e.g. `{% raw %}{% for page in pages() %}…{% endfor %}{% endraw %}`). +If you want to access the data of a particular page, use Pico's `pages` variable. Just take `content/_meta.md` in Pico's sample contents for an example: `content/_meta.md` contains some meta data you might want to use in your theme. If you want to output the page's `tagline` meta value, use `{% raw %}{{ pages["_meta"].meta.logo }}{% endraw %}`. Don't ever try to use Pico's `pages` variable as an replacement for Pico's `pages()` function. Its usage looks very similar, it will kinda work and you might even see it being used in old themes, but be warned: It slows down Pico. Always use Pico's `pages()` function when iterating Pico's page list (e.g. `{% raw %}{% for page in pages() %}…{% endfor %}{% endraw %}`). #### Twig filters and functions Additional to [Twig][]'s extensive list of filters, functions and tags, Pico also provides some useful additional filters and functions to make theming even easier. * Pass the unique ID of a page to the `link` filter to return the page's URL (e.g. `{% raw %}{{ "sub/page"|link }}{% endraw %}` gets `https://example.com/pico/?sub/page`). -* You can replace URL placeholders (like `%base_url%`) in arbitrary strings using the `url` filter. This is helpful together with meta variables, e.g. if you add `image: %assets_url%/stock.jpg` to the YAML header of a page, `{% raw %}{{ meta.image|url }}{% endraw %}` will return `https://example.com/pico/assets/stock.jpg`. +* You can replace URL placeholders (like `%base_url%`) in arbitrary strings using the `url` filter. This is helpful together with meta variables, e.g. if you add `image: "%assets_url%/stock.jpg"` to the YAML header of a page, `{% raw %}{{ meta.image|url }}{% endraw %}` will return `https://example.com/pico/assets/stock.jpg`. * To get the parsed contents of a page, pass its unique ID to the `content` filter (e.g. `{% raw %}{{ "sub/page"|content }}{% endraw %}`). * You can parse any Markdown string using the `markdown` filter. For example, you might use Markdown in the `description` meta variable and later parse it in your theme using `{% raw %}{{ meta.description|markdown }}{% endraw %}`. You can also pass meta data as parameter to replace `%meta.*%` placeholders (e.g. `{% raw %}{{ "Written by *%meta.author%*"|markdown(meta) }}{% endraw %}` yields "Written by *John Doe*"). However, please note that all contents will be wrapped inside HTML paragraph elements (i.e. `

    `). If you want to parse just a single line of Markdown markup, pass the `singleLine` param to the `markdown` filter (e.g. `{% raw %}{{ "This really is a *single* line"|markdown(singleLine=true) }}{% endraw %}`). * Arrays can be sorted by one of its keys using the `sort_by` filter (e.g. `{% raw %}{% for page in pages|sort_by([ 'meta', 'nav' ]) %}...{% endfor %}{% endraw %}` 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`). Items which couldn't be sorted are moved to the bottom of the array; you can specify `bottom` (move items to bottom; default), `top` (move items to top), `keep` (keep original order) or `remove` (remove items) as second parameter to change this behavior. -* You can return all values of a given array key using the `map` filter (e.g. `{% raw %}{{ pages|map("title") }}{% endraw %}` returns all page titles). * Use the `url_param` and `form_param` Twig functions to access HTTP GET (i.e. a URL's query string like `?some-variable=my-value`) and HTTP POST (i.e. data of a submitted form) parameters. This allows you to implement things like pagination, tags and categories, dynamic pages, and even more - with pure Twig! Simply head over to our [introductory page for accessing HTTP parameters][FeaturesHttpParams] for details. ### Plugins @@ -109,7 +110,7 @@ Plugins which were written to work with Pico 1.0 and later can be enabled and di #### Plugins for developers -You're a plugin developer? We love you guys! You can find tons of information about how to develop plugins at [{{ site.github.url }}/development/][PluginDocs]. If you've developed a plugin before and want to upgrade it to Pico 2.0, refer to the [upgrade section of the docs][PluginUpgrade]. +You're a plugin developer? We love you people! Check out Pico's `DummyPlugin` for the complete list of events Pico provides. If you've developed a plugin before and want to upgrade it to Pico's latest version, refer to the upgrade docs. [Twig]: https://twig.symfony.com/doc/1.x/ [UnixTimestamp]: https://en.wikipedia.org/wiki/Unix_timestamp diff --git a/_docs/getting-help.md b/_docs/getting-help.md index 7e545da6..4005861a 100644 --- a/_docs/getting-help.md +++ b/_docs/getting-help.md @@ -12,11 +12,11 @@ nav: 6 ### Getting Help as a user -If you want to get started using Pico, please refer to the [user docs][HelpUserDocs] (you're reading them right now!). Please read the [upgrade notes][HelpUpgrade] if you want to upgrade from Pico 1.0 to Pico 2.0. +If you want to get started using Pico, please refer to the [user docs][HelpUserDocs] (you're reading them right now!). Please read the [upgrade notes][HelpUpgrade] if you want to upgrade to a new Pico version. You can find officially supported [plugins][OfficialPlugins] and [themes][OfficialThemes] here on our website. A greater choice of third-party plugins can be found in our [Wiki][WikiPlugins]. 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 ["Contributing" section][HelpDevContribute] below and our [contribution guidelines][ContributionGuidelines]. To get you started with creating a plugin or theme, please read the [developer docs on our website][HelpDevDocs]. +If you're a developer, please refer to the ["Contributing" section][HelpDevContribute] below and our [contribution guidelines][ContributionGuidelines]. To get you started with creating a plugin or theme, check out Pico's [`DummyPlugin`][PicoDummyPlugin], and [Pico's default theme][PicoThemeGit]. ### You still need help or experience a problem with Pico? @@ -26,8 +26,12 @@ When the docs can't answer your question, you can get help by joining us on [#pi [HelpUpgrade]: {{ site.github.url }}/in-depth/upgrade/ [HelpUserDocs]: {{ site.github.url }}/docs/ -[HelpDevDocs]: {{ site.github.url }}/development/ [HelpDevContribute]: {{ site.github.url }}/docs/#contributing +[OfficialPlugins]: {{ site.github.url }}/plugins/ +[OfficialThemes]: {{ site.github.url }}/themes/ +[WikiPlugins]: https://github.com/picocms/Pico/wiki/Pico-Plugins +[PicoThemeGit]: https://github.com/picocms/pico-theme +[PicoDummyPlugin]: https://github.com/picocms/Pico/blob/master/plugins/DummyPlugin.php [Issues]: {{ site.gh_project_url }}/issues [IssuesSearch]: {{ site.gh_project_url }}/search?type=Issues [ContributionGuidelines]: {{ site.gh_project_url }}/blob/{{ site.gh_project_branch }}/CONTRIBUTING.md diff --git a/_docs/install.md b/_docs/install.md index e2dbfe73..339aa900 100644 --- a/_docs/install.md +++ b/_docs/install.md @@ -72,7 +72,7 @@ Git is a very powerful distributed version-control system - and it can be used t ### I'm a developer -So, you're one of these amazing folks making all of this possible? We love you guys! As a developer we recommend you to clone [Pico's Git repository][PicoGit] as well as the Git repositories of [Pico's default theme][PicoThemeGit] and the [`PicoDeprecated` plugin][PicoDeprecatedGit]. You can set up your workspace using [Pico's Composer starter project][PicoComposerGit] and include all of Pico's components using local packages. +So, you're one of these amazing people making all of this possible? We love you folks! As a developer we recommend you to clone [Pico's Git repository][PicoGit] as well as the Git repositories of [Pico's default theme][PicoThemeGit] and the [`PicoDeprecated` plugin][PicoDeprecatedGit]. You can set up your workspace using [Pico's Composer starter project][PicoComposerGit] and include all of Pico's components using local packages. Using Pico's Git repositories is different from using one of the installation methods elucidated above. It gives you the current development version of Pico, what is likely *unstable* and *not ready for production use*! diff --git a/_docs/upgrade.md b/_docs/upgrade.md index 2640a3b7..966410b4 100644 --- a/_docs/upgrade.md +++ b/_docs/upgrade.md @@ -32,7 +32,7 @@ That's it! Composer will automatically update Pico and all plugins and themes yo ### I've used a pre-bundled release to install Pico -Okay, installing Pico was easy, but upgrading Pico is going to be hard, isn't it? I'm affraid I have to disappoint you... It's just as simple as installing Pico! +Okay, installing Pico was easy, but upgrading Pico is going to be hard, isn't it? I'm afraid I have to disappoint you. It's just as simple as installing Pico! First you'll have to delete the `vendor` directory of your Pico installation (e.g. if you've installed Pico to `/var/www/html/pico`, delete `/var/www/html/pico/vendor`). Then [download the latest Pico release][LatestRelease] and upload all files to your existing Pico installation directory. You will be prompted whether you want to overwrite files like `index.php`, `.htaccess`, ... - simply hit "Yes". diff --git a/in-depth/upgrade-pico-21.md b/in-depth/upgrade-pico-21.md index 73f090e9..83620041 100644 --- a/in-depth/upgrade-pico-21.md +++ b/in-depth/upgrade-pico-21.md @@ -61,10 +61,6 @@ galleries: nav-url: /docs/ gh_release: v2.1.0 -redirect_from: - - /in-depth/upgrade/index.html - - /upgrade/index.html - - /upgrade.html --- {% include gallery.html gallery='logo' %} diff --git a/in-depth/upgrade-pico-30.md b/in-depth/upgrade-pico-30.md new file mode 100644 index 00000000..e0de57e8 --- /dev/null +++ b/in-depth/upgrade-pico-30.md @@ -0,0 +1,218 @@ +--- +layout: docs +title: Upgrade to Pico 3.0 +headline: Upgrade Pico 2.1 to Pico 3.0 +description: A small update with a lot of external changes. +toc: + how-to-upgrade: How to upgrade + upgrade-to-twig-33: Upgrade to Twig 3.3 + upgrade-to-symfony-yaml-54: Upgrade to Symfony YAML 5.4 + downgrade-to-parsedown-17: Downgrade to Parsedown 1.7 + everything-else-that-was-happening: Everything else that was happening… +more: + /in-depth/upgrade-pico-10: Upgrade to Pico 1.0 + /in-depth/upgrade-pico-20: Upgrade to Pico 2.0 + /in-depth/upgrade-pico-21: Upgrade to Pico 2.1 +nav-url: /docs/ +gh_release: v3.0.0 +redirect_from: + - /in-depth/upgrade/index.html + - /upgrade/index.html + - /upgrade.html +--- + +You want to learn more about Pico's latest major installment, Pico 3.0? Pico 3.0 is a major release, but brings relatively small changes to Pico's core. What it does bring might be the biggest "minor change" Pico had in a while: majorly updated dependencies. These updates include switching to [Twig 3.3][Twig] (from Twig 1.44) and [Symfony YAML 5.4][Yaml] (from YAML 2.8), but also a slight step back from [Parsedown][] 1.8-beta to the stable Parsedown 1.7 line. The main reason for these updates is to better support PHP 8.0. This should be great news to the majority of Pico users, however, it does also mean that Pico now requires PHP 7.2.5 or later, and that Pico no longer supports (ancient) PHP 5 based environments. + +We're also pleased to announce [Pico CMS for Nextcloud 2.0][NextcloudApp]. You didn't hear about Pico CMS for Nextcloud yet? Pico CMS for Nextcloud fully integrates Pico into [Nextcloud][], a free and open-source collaboration platform for creating and using file hosting services. Pico CMS for Nextcloud allows one to create simple, secure, shareable and amazingly powerful websites with just a few clicks. It gives you everything you would expect from a extremely powerful admin interface for Pico. + +Anyway, what holds true for Pico 3.0, also holds true for Pico CMS for Nextcloud 2.0: It's a major release, but brings relatively small changes besides updated dependencies. Pico CMS for Nextcloud 2.0 is powered by Pico 3.0, thus all changes to Pico 3.0 are also part of the Nextcloud app. The biggest addition is that users can now share their websites with other Nextcloud groups more easily. Besides, Pico CMS for Nextcloud now fully supports forms, allows users to rename their websites and includes Pico's `DummyPlugin` as plugin template. Furthermore there were a whole lot of improvements "under the hood". + +If you have any questions about Pico 3.0, the upgrade process, or if you experience compatibility issues with the upgrade, please check out the ["Getting Help" section][GettingHelp] of the docs, and don't be afraid to open a new [Issue][Issues] on GitHub. + +## How to upgrade + +Pico 3.0 is a major release, thus **it will likely break your website** at first. Check out the following sections below to learn what to change to fix the expected issues. This documentation assumes that you've upgraded to Pico 2.1 before; if you're running an older version, check out the upgrade docs to their respective successor first (to [Pico 1.0][UpgradePico10], to [Pico 2.0][UpgradePico20], and to [Pico 2.1][UpgradePico21]). No matter what, make sure to **create a backup of your Pico installation before upgrading**. After that you can follow the regular [upgrade instructions][Upgrade]. For convenience, these instructions are also provided below: + +1. **Create a backup of your Pico installation.** + +2. Think about how you've installed Pico in the past. Did you use [Composer][] or one of Pico's pre-bundled releases? + + - If you've used Composer to install Pico, upgrading Pico itself is no more than running a single command. Open a shell and navigate to Pico's install directory within the `httpdocs` directory (e.g. `/var/www/html/pico`) of your server. You can now upgrade Pico using the following command: + + ```shell + $ php composer.phar update + ``` + + That's it! Composer will automatically update Pico and all plugins and themes you've installed using Composer. + + - If you've used one of Pico's pre-bundled releases, the upgrade steps are dead simple, too. First you'll have to delete the `vendor` directory of your Pico installation (e.g. if you've installed Pico to `/var/www/html/pico`, delete `/var/www/html/pico/vendor`). Also delete the `plugins/PicoDeprecated` directory. Then [download the latest Pico release][LatestRelease] and upload all files to your existing Pico installation directory. You will be prompted whether you want to overwrite files like `index.php`, `.htaccess`, … - simply hit "Yes". That's it! + +3. Check all your custom plugins and themes whether there are updates available and follow the provided upgrade instructions to upgrade them. Pico 3.0 introduces the new API version 4 for both plugins and themes. However, Pico 3.0 is mostly backwards-compatible to Pico 2.1 (using API version 3) and earlier. This is achieved by Pico's official [`PicoDeprecated` plugin][PicoDeprecated]. The `PicoDeprecated` plugin is installed by default, so usually you don't have to do anything. However, if you've removed `PicoDeprecated` from your Pico installation before, make sure to either upgrade all your plugins and themes to the latest API version 4, or install `PicoDeprecated` by following the plugin's install instructions. + +4. The most important change of Pico 3.0 are updated dependencies - namely [Twig 3.3][Twig], [Symfony YAML 5.4][Yaml], and [Parsedown 1.7][Parsedown]. The new versions of Twig and YAML will very likely cause some issues for you! Refer to the ["Upgrade to Twig 3.3"][UpgradeTwig], ["Upgrade to Symfony YAML 5.4"][UpgradeYaml], and ["Downgrade to Parsedown 1.7"][UpgradeParsedown] sections below to learn what has changed and how to fix the issues. For everything else that was changed, refer to the ["Everything else that was happening…" section][UpgradeMisc] below. + +Please take the opportunity to check whether your webserver is proberly configured, and access to Pico's internal files and directories is denied. Just refer to the ["URL Rewriting" section in the docs][UrlRewriting]. By following the instructions, you will not just enable URL rewriting, but also deny access to Pico's internal files and directories. + +## Upgrade to Twig 3.3 + +Skipping Twig 2 altogether, Pico now ships with the [Twig 3.3][Twig] template engine for theming. This update will likely cause some issues, for a complete list of deprecated features please refer to the docs as of [Twig 1.x][TwigDeprecated1] and [Twig 2.x][TwigDeprecated2]. Most changes affect plugin developers only, but a few changes might also break your custom theme, most notably the following: + +* Pico's `map` Twig filter has been removed. Use Twig's new built-in `map` filter (for advanced usage) or `column` filter (for simple usages) instead. +* Pico's `markdown` Twig filter now throws an error when invalid data (e.g. an array) is passed. +* You can no longer add an `if` condition to the `for` loop (i.e. `{% raw %}{% for … in … if … %}{% endraw %}`), as previously used by Pico's default theme and many 3rd-party themes. Use a `filter` filter or an `{% raw %}{% if … %}{% endraw %}` condition inside the `{% raw %}{% for … in … %}{% endraw %}` body instead. +* The `{% raw %}{% spaceless %}{% endraw %}` tag was deprecated in favour of the `spaceless` filter. You can use `{% raw %}{% apply spaceless %}{% endraw %}` as an alternative. +* Speaking of the `{% raw %}{% apply … %}{% endraw %}` tag, the `{% raw %}{% filter … %}{% endraw %}` tag was deprecated in favour of the `{% raw %}{% apply … %}{% endraw %}` tag. +* The `sameas` and `divisibleby` tests are deprecated in favor of `same as` and `divisible by` tests respectively. +* The `{% raw %}{% raw %}{% endraw %}` tag (don't confuse this with the `raw` filter) was deprecated. Use `{% raw %}{% verbatim %}{% endraw %}` instead. +* The `_self` global variable now returns the current template name instead of the current `\Twig\Template` object. `_self` was often used to retrieve the current template's name, so simply replace `{% raw %}{{ _self.templateName }}{% endraw %}` by `{% raw %}{{ _self }}{% endraw %}`. + +Twig 3.3 also brings many new Twig features to Pico 3.0 though. If you've ever run into an unsupported Twig filter or function due to Pico's older Twig version, now's the time to try it again! Please refer to [Twig's documentation][Twig] for a complete list of all features. + +If you encounter issues with existing 3rd-party Pico themes, be sure to let their respective developers know and point them toward this page. + +## Upgrade to Symfony YAML 5.4 + +Pico now utilizes the latest [Symfony YAML 5.4][Yaml] release to parse YAML. This change should go mostly unnoticed, but might still cause some minor issues with the YAML Frontmatters your Markdown files, or your config files. Please check out Symfony's [changelog][YamlChangelog] for a complete list of changes. Most notably the following might cause some minor issues: + +* Unquoted YAML values must no longer start with a percent sign (`%`), at sign (`@`), grave accent (```), vertical bar (`|`), or greater-than sign (`>`). This will most likely cause some issues with Pico's URL placeholders (e.g. `%base_url%`, or `%assets_url%`), as you must now quote these strings. For example, `Logo: %assets_url%/img/pico-white.svg` must be replaced by `Logo: "%assets_url%/img/pico-white.svg"`. +* When surrounding strings with double-quotes, you must now escape the backslash character (`\`; e.g. `class: "Foo\Bar"` must be replaced by `class: "Foo\\Bar"`). +* Symfony YAML streamlined the use of mappings (i.e. `key: value` pairs): You can no longer use non-string mapping keys (replace e.g. `123: integer` by `"123": integer`), as they now cause errors. Duplicate mapping keys (i.e. using the same key twice) will now also cause an error. Symfony YAML now additionally requires a whitespace after the colon (`:`) separating key and value of a mapping (replace e.g. `key:value` by `key: value`). +* You can no longer use mappings inside multi-line strings. +* Support for the comma (`,`) as a group separator for floats has been dropped. Use the underscore (`_`) instead (i.e. use `1_234.56` instead of `1,234.56`). +* Symfony YAML changed the behaviour of various custom (non-standard) YAML tags (e.g. `!php/object`). Check out the changelog for more details. + +## Downgrade to Parsedown 1.7 + +In regards of Pico's Markdown parser - [Parsedown][] resp. [Parsedown Extra][ParsedownExtra] - we perform a downgrade to Parsedown 1.7. We upgraded to Parsedown 1.8-beta with Pico 2.1 due to its major improvements regarding its improved support for [CommonMark][], but considering its long development time and abandonment in favour of Parsedown 2.0 (also still in development), we decided to switch back to the more commonly used stable Parsedown 1.7. This shouldn't have much of an impact on Pico users, however, we do recommend you give your content files a quick look to make sure they still render correctly in the older Parsedown 1.7 version. + +## Everything else that was happening… + +As explained earlier, Pico 3.0 comes with a rather small number of changes to its core. Both [Pico's default theme][PicoTheme] and Pico's official [`PicoDeprecated` plugin][PicoDeprecated] now use API version 4, even though this API version doesn't really change much apart from the already mentioned above. + +As a convinience feature, you can now use the `%page_id%`, `%page_url%`, and `%page_path%` placeholders in your Markdown files. They will be replaced by the current page's ID (e.g. `sub/index` for `content/sub/index.md`, `sub/page` for `content/sub/page.md`, …), its URL (`sub` resp. `sub/page` in our examples), or its directory path (`sub` in both examples) respectively. This is useful for e.g. asset management: You can now put assets for pages in the `content/sub/` directory in the `assets/sub/` directory, and reference them using `%assets_url%/%page_path%/my_asset.png`. Furthermore, Pico now prints an error message when the designated theme directory doesn't exist. Speaking of themes, Pico's default theme no longer justifies contents by default, and now includes non-hidden pages without a title in the navigation menu. Last but not least, there's now a new `page()` Twig function, returning a page's data when passing a page ID (use `{% raw %}{{ page("sub/page").title }}{% endraw %}` instead of `{% raw %}{{ pages["sub/page"].title }}{% endraw %}`). + +And that's basically it. However, please note that this document doesn't cover all improvements and changes, because they simply don't affect the average Pico user, but developers. Below you will find a complete, more tech-oriented list of changes. It's a extract of Pico's [`CHANGELOG.md`][Changelog]. Please note that Pico's `CHANGELOG.md` isn't supposed to be read as-is; it's rather an supplement to the actual code changes. + +If you have a question about one of the new features of Pico 3.0, please check out the ["Getting Help" section][GettingHelp] of the docs and don't be afraid to open a new [Issue][Issues] on GitHub. + +
    +

    Pico's CHANGELOG.md

    +
    +
    + +``` +* [New] Pico 3.0 is a major release, but comes with relatively small changes + to Pico's core; its major change are updated dependencies (see below) +* [New] Introduce API version 4 (with barely noticable changes, see below) +* [New] Add new continous integration (CI) pipeline using GitHub Actions +* [New] Add new build script and Makefile to simplify Pico's build and release + process; see `CONTRIBUTING.md` for details +* [New] Add `%page_id%`, `%page_url%` and `%page_path%` Markdown placeholders + to replace the current page's ID, URL, and containing directory resp. +* [New] `Pico::prepareFileContent()` and `Pico::substituteFileContent()` both + now receive the (optional) `$pageId` argument for the new `%page_*%` + Markdown placeholders +* [New] Add `page()` Twig function to access a page's data +* [Changed] ! Pico now requires PHP 7.2.5 or later (this includes full PHP 8 + support, also see #528, #534, #608) +* [Changed] ! Pico now depends on Twig 3.3, skipping Twig 2.x altogether; this + is a BC-breaking change, as Twig 2.x and 3.x changed and removed + some commonly used features; check out Twig's changelog and + deprecation notices for details +* [Changed] ! Pico now depends on Symfony YAML 5.4, skipping various milestones + in between; this is a BC-breaking change, because Symfony YAML + changed its behaviour multiple times in between; check out Symfony + YAML's changelog for details +* [Changed] ! Pico downgrades to Parsedown 1.7.4 and Parsedown Extra 0.8.1; + this is a BC-breaking change in theory, but shouldn't have much of + an impact in real-life scenarios +* [Changed] #603: Pico's `markdown` Twig filter now raises an error if an + invalid variable type (e.g. an array) is passed +* [Changed] Enable PHP strict typing for Pico's internal classes; Pico's + `PicoPluginInterface` interface and `AbstractPicoPlugin` class + don't use strict typing to maintain BC, but you can (and should) + enable it for your plugin (see `DummyPlugin` for an example) +* [Changed] Various other code improvements due to the upgrade to PHP 7.2 +* [Fixed] #602: Fix contents and meta data of meta pages (pages starting with + an `_`) getting replaced by the 404 page when being requested +* [Fixed] Add a proper error message for a missing theme directory +* [Removed] ! Remove Pico's `map` Twig filter; it conflicts with Twig's `map` + filter and can be replaced by Twig's `column` or `map` filter +``` + +
    +
    +
    + +
    +

    CHANGELOG.md of Pico's default theme

    +
    +
    + +``` +* [New] Update to API version 4 (no changes necessary) +* [Changed] Include non-hidden pages without a title in the navigation menu; + use the page ID as fallback for the missing page title +* [Changed] Don't justify text contents by default +* [Changed] Update syntax to Twig 3.3 +* [Changed] Update credits in theme footer +``` + +
    +
    +
    + +
    +

    CHANGELOG.md of PicoDeprecated

    +
    +
    + +``` +* [New] Update to API version 4 (no functional changes necessary) +* [New] Add new continous integration (CI) pipeline using GitHub Actions +* [New] Add new build script and Makefile to simplify PicoDeprecated's build + and release process; see Pico's `CONTRIBUTING.md` for details +* [New] Add `PicoDeprecated::VERSION` and `PicoDeprecated::VERSION_ID` + constants (similar to Pico's matching constants) +* [New] Add plugin and theme compatibility plugin for API version 3 +* [Changed] Enable PHP strict typing +* [Changed] ! Move classes to `\picocms\PicoDeprecated\…` PHP namespace +* [Fixed] Don't instantiate compatibility plugins multiple times +* [Fixed] Update Twig API usage to be compatible with Twig 3.3 +``` + +
    +
    +
    + +[UpgradeTwig]: #upgrade-to-twig-33 +[UpgradeYaml]: #upgrade-to-symfony-yaml-54 +[UpgradeParsedown]: #downgrade-to-parsedown-17 +[UpgradeMisc]: #everything-else-that-was-happening + +[GettingHelp]: {{ site.github.url }}/docs/#getting-help +[Issues]: {{ site.gh_project_url }}/issues +[Changelog]: {{ site.gh_project_url }}/blob/{{ page.gh_release }}/CHANGELOG.md + +[Upgrade]: {{ site.github.url }}/docs/#upgrade +[UpgradePico10]: {{ site.github.url }}/in-depth/upgrade-pico-10 +[UpgradePico20]: {{ site.github.url }}/in-depth/upgrade-pico-20 +[UpgradePico21]: {{ site.github.url }}/in-depth/upgrade-pico-21 +[LatestRelease]: {{ site.gh_project_url }}/releases/latest +[UrlRewriting]: {{ site.github.url }}/docs/#url-rewriting + +[Twig]: https://twig.symfony.com/doc/3.x/ +[TwigDeprecated1]: https://twig.symfony.com/doc/1.x/deprecated.html +[TwigDeprecated2]: https://twig.symfony.com/doc/2.x/deprecated.html +[Yaml]: https://symfony.com/doc/5.4/components/yaml.html +[YamlChangelog]: https://github.com/symfony/yaml/blob/5.4/CHANGELOG.md +[Parsedown]: https://parsedown.org/ +[ParsedownExtra]: https://parsedown.org/extra/ +[CommonMark]: https://commonmark.org/ + +[Composer]: https://getcomposer.org/ +[PicoTheme]: https://github.com/picocms/pico-theme +[PicoDeprecated]: https://github.com/picocms/pico-deprecated + +[Nextcloud]: https://nextcloud.com/ +[NextcloudApp]: https://apps.nextcloud.com/apps/cms_pico