\Pico

Pico

Pico is a stupidly simple, blazing fast, flat file CMS.

  • Stupidly Simple: Pico makes creating and maintaining a website as simple as editing text files.
  • Blazing Fast: Pico is seriously lightweight and doesn't use a database, making it super fast.
  • No Database: Pico is a "flat file" CMS, meaning no database woes, no MySQL queries, nothing.
  • Markdown Formatting: Edit your website in your favourite text editor using simple Markdown formatting.
  • Twig Templates: Pico uses the Twig templating engine, for powerful and flexible themes.
  • Open Source: Pico is completely free and open source, released under the MIT license.

See http://picocms.org/ for more info.

Summary

Methods
Properties
Constants
__construct()
getRootDir()
getVendorDir()
getConfigDir()
getPluginsDir()
getThemesDir()
run()
loadPlugin()
getPlugin()
getPlugins()
setConfig()
getConfig()
getRequestUrl()
resolveFilePath()
getRequestFile()
loadFileContent()
load404Content()
getRawContent()
is404Content()
getMetaHeaders()
getYamlParser()
parseFileMeta()
getFileMeta()
getParsedown()
prepareFileContent()
substituteFileContent()
parseFileContent()
getFileContent()
getPages()
getCurrentPage()
getPreviousPage()
getNextPage()
getPageTree()
getTwig()
getBaseUrl()
isUrlRewritingEnabled()
getPageUrl()
getPageId()
getBaseThemeUrl()
getUrlParameter()
getFormParameter()
getFiles()
getFilesGlob()
getAbsolutePath()
triggerEvent()
No public properties found
VERSION
VERSION_ID
API_VERSION
SORT_ASC
SORT_DESC
SORT_NONE
loadPlugins()
loadComposerPlugins()
loadLocalPlugins()
sortPlugins()
loadConfig()
evaluateRequestUrl()
readPages()
sortPages()
discoverPageSiblings()
discoverCurrentPage()
buildPageTree()
getTwigVariables()
getTwigTemplate()
filterVariable()
$rootDir
$vendorDir
$configDir
$pluginsDir
$themesDir
$locked
$plugins
$nativePlugins
$enableLocalPlugins
$config
$requestUrl
$requestFile
$rawContent
$is404Content
$yamlParser
$metaHeaders
$meta
$parsedown
$content
$pages
$currentPage
$previousPage
$nextPage
$pageTree
$twig
$twigVariables
$twigTemplate
N/A
No private methods found
No private properties found
N/A

Constants

VERSION

VERSION

Pico version

VERSION_ID

VERSION_ID

Pico version ID

API_VERSION

API_VERSION

Pico API version

SORT_ASC

SORT_ASC

Sort files in alphabetical ascending order

SORT_DESC

SORT_DESC

Sort files in alphabetical descending order

SORT_NONE

SORT_NONE

Don't sort files

Properties

$rootDir

$rootDir : string

Root directory of this Pico instance

Type

string

$vendorDir

$vendorDir : string

Vendor directory of this Pico instance

Type

string

$configDir

$configDir : string

Config directory of this Pico instance

Type

string

$pluginsDir

$pluginsDir : string

Plugins directory of this Pico instance

Type

string

$themesDir

$themesDir : string

Themes directory of this Pico instance

Type

string

$locked

$locked : boolean

Boolean indicating whether Pico started processing yet

Type

boolean

$plugins

$plugins : array<mixed,object>

List of loaded plugins

Type

array<mixed,object>

$nativePlugins

$nativePlugins : array<mixed,\PicoPluginInterface>

List of loaded plugins using the current API version

Type

array<mixed,\PicoPluginInterface>

$enableLocalPlugins

$enableLocalPlugins : boolean

Boolean indicating whether Pico loads plugins from the filesystem

Type

boolean

$config

$config : array|null

Current configuration of this Pico instance

Type

array|null

$requestUrl

$requestUrl : string|null

Part of the URL describing the requested contents

Type

string|null

$requestFile

$requestFile : string|null

Absolute path to the content file being served

Type

string|null

$rawContent

$rawContent : string|null

Raw, not yet parsed contents to serve

Type

string|null

$is404Content

$is404Content : boolean

Boolean indicating whether Pico is serving a 404 page

Type

boolean

$yamlParser

$yamlParser : \Symfony\Component\Yaml\Parser|null

Symfony YAML instance used for meta header parsing

Type

\Symfony\Component\Yaml\Parser|null

$metaHeaders

$metaHeaders : array<mixed,string>|null

List of known meta headers

Type

array<mixed,string>|null

$meta

$meta : array|null

Meta data of the page to serve

Type

array|null

$parsedown

$parsedown : \ParsedownExtra|null

Parsedown Extra instance used for markdown parsing

Type

\ParsedownExtra|null

$content

$content : string|null

Parsed content being served

Type

string|null

$pages

$pages : array<mixed,array>|null

List of known pages

Type

array<mixed,array>|null

$currentPage

$currentPage : array|null

Data of the page being served

Type

array|null

$previousPage

$previousPage : array|null

Data of the previous page relative to the page being served

Type

array|null

$nextPage

$nextPage : array|null

Data of the next page relative to the page being served

Type

array|null

$pageTree

$pageTree : array<mixed,array>|null

Tree structure of known pages

Type

array<mixed,array>|null

$twig

$twig : \Twig_Environment|null

Twig instance used for template parsing

Type

\Twig_Environment|null

$twigVariables

$twigVariables : array|null

Variables passed to the twig template

Type

array|null

$twigTemplate

$twigTemplate : string|null

Name of the Twig template to render

Type

string|null

Methods

__construct()

__construct(string  $rootDir, string  $configDir, string  $pluginsDir, string  $themesDir, boolean  $enableLocalPlugins = true) 

Constructs a new Pico instance

To carry out all the processing in Pico, call \Pico::run().

Parameters

string $rootDir

root dir of this Pico instance

string $configDir

config dir of this Pico instance

string $pluginsDir

plugins dir of this Pico instance

string $themesDir

themes dir of this Pico instance

boolean $enableLocalPlugins

enables (TRUE; default) or disables (FALSE) loading plugins from the filesystem

getRootDir()

getRootDir() : string

Returns the root directory of this Pico instance

Returns

string —

root directory path

getVendorDir()

getVendorDir() : string

Returns the vendor directory of this Pico instance

Returns

string —

vendor directory path

getConfigDir()

getConfigDir() : string

Returns the config directory of this Pico instance

Returns

string —

config directory path

getPluginsDir()

getPluginsDir() : string

Returns the plugins directory of this Pico instance

Returns

string —

plugins directory path

getThemesDir()

getThemesDir() : string

Returns the themes directory of this Pico instance

Returns

string —

themes directory path

run()

run() : string

Runs this Pico instance

Loads plugins, evaluates the config file, does URL routing, parses meta headers, processes Markdown, does Twig processing and returns the rendered contents.

Throws

\Exception

thrown when a irrecoverable error occurs

Returns

string —

rendered Pico contents

loadPlugin()

loadPlugin(\PicoPluginInterface|string  $plugin) : \PicoPluginInterface

Manually loads a plugin

Manually loaded plugins MUST implement \PicoPluginInterface. They are simply appended to the plugins array without any additional checks, so you might get unexpected results, depending on when you're loading a plugin. You SHOULD NOT load plugins after a event has been triggered by Pico. In-depth knowledge of Pico's inner workings is strongly advised otherwise, and you MUST NOT rely on \PicoDeprecated to maintain backward compatibility in such cases.

If you e.g. load a plugin after the onPluginsLoaded event, Pico doesn't guarantee the plugin's order (\Pico::sortPlugins()). Already triggered events won't get triggered on the manually loaded plugin. Thus you SHOULD load plugins either before \Pico::run() is called, or via the constructor of another plugin (i.e. the plugin's __construct() method; plugins are instanced in \Pico::loadPlugins()).

This method triggers the onPluginManuallyLoaded event.

Parameters

\PicoPluginInterface|string $plugin

either the class name of a plugin to instantiate or a plugin instance

Throws

\RuntimeException

thrown when a plugin couldn't be loaded

Returns

\PicoPluginInterface

instance of the loaded plugin

getPlugin()

getPlugin(string  $pluginName) : object

Returns the instance of a named plugin

Plugins SHOULD implement \PicoPluginInterface, but you MUST NOT rely on it. For more information see \PicoPluginInterface.

Parameters

string $pluginName

name of the plugin

Throws

\RuntimeException

thrown when the plugin wasn't found

Returns

object —

instance of the plugin

getPlugins()

getPlugins() : array<mixed,object>|null

Returns all loaded plugins

Returns

array<mixed,object>|null

setConfig()

setConfig(array  $config) : void

Sets Pico's config before calling Pico::run()

This method allows you to modify Pico's config without creating a {@path "config/config.yml"} or changing some of its variables before Pico starts processing.

You can call this method between \Pico::__construct() and \Pico::run() only. Options set with this method cannot be overwritten by {@path "config/config.yml"}.

Parameters

array $config

array with config variables

Throws

\LogicException

thrown if Pico already started processing

getConfig()

getConfig(string  $configName = null, mixed  $default = null) : mixed

Returns either the value of the specified config variable or the config array

Parameters

string $configName

optional name of a config variable

mixed $default

optional default value to return when the named config variable doesn't exist

Returns

mixed —

if no name of a config variable has been supplied, the config array is returned; otherwise it returns either the value of the named config variable, or, if the named config variable doesn't exist, the provided default value or NULL

getRequestUrl()

getRequestUrl() : string|null

Returns the URL where a user requested the page

Returns

string|null —

request URL

resolveFilePath()

resolveFilePath(string  $requestUrl) : string

Resolves a given file path to its corresponding content file

This method also prevents content_dir breakouts using malicious request URLs. We don't use realpath(), because we neither want to check for file existance, nor prohibit symlinks which intentionally point to somewhere outside the content_dir folder. It is STRONGLY RECOMMENDED to use PHP's open_basedir feature - always, not just with Pico!

Parameters

string $requestUrl

path name (likely from a URL) to resolve

Returns

string —

path to the resolved content file

getRequestFile()

getRequestFile() : string|null

Returns the absolute path to the content file to serve

Returns

string|null —

file pat

loadFileContent()

loadFileContent(string  $file) : string

Returns the raw contents of a file

Parameters

string $file

file path

Returns

string —

raw contents of the file

load404Content()

load404Content(string  $file) : string

Returns the raw contents of the first found 404 file when traversing up from the directory the requested file is in

If no suitable 404.md is found, fallback to a built-in error message.

Parameters

string $file

path to requested (but not existing) file

Returns

string —

raw contents of the 404 file

getRawContent()

getRawContent() : string|null

Returns the raw contents, either of the requested or the 404 file

Returns

string|null —

raw contents

is404Content()

is404Content() : boolean

Returns TRUE when Pico is serving a 404 page

Returns

boolean —

TRUE if Pico is serving a 404 page, FALSE otherwise

getMetaHeaders()

getMetaHeaders() : array<mixed,string>

Returns known meta headers

This method triggers the onMetaHeaders event when the known meta headers weren't assembled yet.

Returns

array<mixed,string> —

known meta headers; the array key specifies the YAML key to search for, the array value is later used to access the found value

getYamlParser()

getYamlParser() : \Symfony\Component\Yaml\Parser

Returns the Symfony YAML parser

This method triggers the onYamlParserRegistered event when the Symfony YAML parser wasn't initiated yet.

Returns

\Symfony\Component\Yaml\Parser —

Symfony YAML parser

parseFileMeta()

parseFileMeta(string  $rawContent, array<mixed,string>  $headers) : array

Parses the file meta from raw file contents

Meta data MUST start on the first line of the file, either opened and closed by --- or C-style block comments (deprecated). The headers are parsed by the YAML component of the Symfony project, keys are lowered. If you're a plugin developer, you MUST register new headers during the onMetaHeaders event first. The implicit availability of headers is for users and pure (!) theme developers ONLY.

Parameters

string $rawContent

the raw file contents

array<mixed,string> $headers

known meta headers

Throws

\Symfony\Component\Yaml\Exception\ParseException

thrown when the meta data is invalid

Returns

array —

parsed meta data

getFileMeta()

getFileMeta() : array|null

Returns the parsed meta data of the requested page

Returns

array|null —

parsed meta data

getParsedown()

getParsedown() : \Parsedown

Returns the Parsedown markdown parser

This method triggers the onParsedownRegistered event when the Parsedown markdown parser wasn't initiated yet.

Returns

\Parsedown —

Parsedown markdown parser

prepareFileContent()

prepareFileContent(string  $rawContent, array  $meta = array()) : string

Applies some static preparations to the raw contents of a page

This method removes the meta header and replaces %...% placeholders by calling the \Pico::substituteFileContent() method.

Parameters

string $rawContent

raw contents of a page

array $meta

meta data to use for %meta.*% replacement

Returns

string —

prepared Markdown contents

substituteFileContent()

substituteFileContent(string  $markdown, array  $meta = array()) : string

Replaces all %.

..% placeholders in a page's contents

Parameters

string $markdown

Markdown contents of a page

array $meta

meta data to use for %meta.*% replacement

Returns

string —

substituted Markdown contents

parseFileContent()

parseFileContent(string  $markdown) : string

Parses the contents of a page using ParsedownExtra

Parameters

string $markdown

Markdown contents of a page

Returns

string —

parsed contents (HTML)

getFileContent()

getFileContent() : string|null

Returns the cached contents of the requested page

Returns

string|null —

parsed contents

getPages()

getPages() : array<mixed,array>|null

Returns the list of known pages

Returns

array<mixed,array>|null —

the data of all pages

getCurrentPage()

getCurrentPage() : array|null

Returns the data of the requested page

Returns

array|null —

page data

getPreviousPage()

getPreviousPage() : array|null

Returns the data of the previous page relative to the page being served

Returns

array|null —

page data

getNextPage()

getNextPage() : array|null

Returns the data of the next page relative to the page being served

Returns

array|null —

page data

getPageTree()

getPageTree() : array<mixed,array>|null

Returns a tree structure of known pages

Returns

array<mixed,array>|null —

the tree structure of all pages

getTwig()

getTwig() : \Twig_Environment|null

Returns the Twig template engine

This method triggers the onTwigRegistered event when the Twig template engine wasn't initiated yet. When initiating Twig, this method also registers Pico's core Twig filter content as well as Pico's \PicoTwigExtension Twig extension.

Returns

\Twig_Environment|null —

Twig template engine

getBaseUrl()

getBaseUrl() : string

Returns the base URL of this Pico instance

Security Notice: You MUST configure Pico's base URL explicitly when using the base URL in contexts that are potentially vulnerable to HTTP Host Header Injection attacks (e.g. when generating emails).

Returns

string —

the base url

isUrlRewritingEnabled()

isUrlRewritingEnabled() : boolean

Returns TRUE if URL rewriting is enabled

Returns

boolean —

TRUE if URL rewriting is enabled, FALSE otherwise

getPageUrl()

getPageUrl(string  $page, array|string  $queryData = null, boolean  $dropIndex = true) : string

Returns the URL to a given page

This method can be used in Twig templates by applying the link filter to a string representing a page ID.

Parameters

string $page

ID of the page to link to

array|string $queryData

either an array containing properties to create a URL-encoded query string from, or a already encoded string

boolean $dropIndex

if the last path component is "index", passing TRUE (default) leads to removing this path component

Returns

string —

URL

getPageId()

getPageId(string  $path) : string|null

Returns the page ID of a given content file

Parameters

string $path

path to the content file

Returns

string|null —

either the corresponding page ID or NULL

getBaseThemeUrl()

getBaseThemeUrl() : string

Returns the URL of the themes folder of this Pico instance

We assume that the themes folder is a arbitrary deep sub folder of the script's base path (i.e. the directory {@path "index.php"} is in resp. the httpdocs directory). Usually the script's base path is identical to \Pico::$rootDir, but this may aberrate when Pico got installed as a composer dependency. However, ultimately it allows us to use \Pico::getBaseUrl() as origin of the theme URL. Otherwise Pico falls back to the basename of \Pico::$themesDir (i.e. assuming that Pico::$themesDir is foo/bar/baz, the base URL of the themes folder will be baz/; this ensures BC to Pico < 2.0). Pico's base URL always gets prepended appropriately.

Returns

string —

the URL of the themes folder

getUrlParameter()

getUrlParameter(string  $name, integer|string  $filter = '', mixed|array  $options = null, integer|string|array<mixed,integer>|array<mixed,string>  $flags = null) : mixed

Filters a URL GET parameter with a specified filter

This method is just an alias for \Pico::filterVariable(), see \Pico::filterVariable() for a detailed description. It can be used in Twig templates by calling the url_param function.

Parameters

string $name

name of the URL GET parameter to filter

integer|string $filter

the filter to apply

mixed|array $options

either a associative options array to be used by the filter or a scalar default value

integer|string|array<mixed,integer>|array<mixed,string> $flags

flags and flag strings to be used by the filter

Returns

mixed —

either the filtered data, FALSE if the filter fails, or NULL if the URL GET parameter doesn't exist and no default value is given

getFormParameter()

getFormParameter(string  $name, integer|string  $filter = '', mixed|array  $options = null, integer|string|array<mixed,integer>|array<mixed,string>  $flags = null) : mixed

Filters a HTTP POST parameter with a specified filter

This method is just an alias for \Pico::filterVariable(), see \Pico::filterVariable() for a detailed description. It can be used in Twig templates by calling the form_param function.

Parameters

string $name

name of the HTTP POST parameter to filter

integer|string $filter

the filter to apply

mixed|array $options

either a associative options array to be used by the filter or a scalar default value

integer|string|array<mixed,integer>|array<mixed,string> $flags

flags and flag strings to be used by the filter

Returns

mixed —

either the filtered data, FALSE if the filter fails, or NULL if the HTTP POST parameter doesn't exist and no default value is given

getFiles()

getFiles(string  $directory, string  $fileExtension = '', integer  $order = self::SORT_ASC) : array

Recursively walks through a directory and returns all containing files matching the specified file extension

Parameters

string $directory

start directory

string $fileExtension

return files with the given file extension only (optional)

integer $order

specify whether and how files should be sorted; use Pico::SORT_ASC for a alphabetical ascending order (this is the default behaviour), Pico::SORT_DESC for a descending order or Pico::SORT_NONE to leave the result unsorted

Returns

array —

list of found files

getFilesGlob()

getFilesGlob(string  $pattern, integer  $order = self::SORT_ASC) : array

Returns all files in a directory matching a libc glob() pattern

Parameters

string $pattern

the pattern to search for; see PHP's glob() function for details

integer $order

specify whether and how files should be sorted; use Pico::SORT_ASC for a alphabetical ascending order (this is the default behaviour), Pico::SORT_DESC for a descending order or Pico::SORT_NONE to leave the result unsorted

Returns

array —

list of found files

getAbsolutePath()

getAbsolutePath(string  $path) : string

Makes a relative path absolute to Pico's root dir

This method also guarantees a trailing slash.

Parameters

string $path

relative or absolute path

Returns

string —

absolute path

triggerEvent()

triggerEvent(string  $eventName, array  $params = array()) : void

Triggers events on plugins using the current API version

Plugins using older API versions are handled by \PicoDeprecated. Please note that \PicoDeprecated also triggers custom events on plugins using older API versions, thus you can safely use this method to trigger custom events on all loaded plugins, no matter what API version - the event will be triggered in any case.

You MUST NOT trigger events of Pico's core with a plugin!

Parameters

string $eventName

name of the event to trigger

array $params

optional parameters to pass

loadPlugins()

loadPlugins() : void

Loads plugins from vendor/pico-plugin.php and Pico::$pluginsDir

See \Pico::loadComposerPlugins() for details about plugins loaded from vendor/pico-plugin.php (i.e. plugins that were installed using composer), and \Pico::loadLocalPlugins() for details about plugins installed to \Pico::$pluginsDir. Pico loads plugins from the filesystem only if \Pico::$enableLocalPlugins is set to TRUE (this is the default).

Pico always loads plugins from vendor/pico-plugin.php first and ignores conflicting plugins in \Pico::$pluginsDir.

The official PicoDeprecated plugin must be loaded when plugins that use an older API version than Pico's API version (\Pico::API_VERSION) are loaded.

Please note that Pico will change the processing order when needed to incorporate plugin dependencies. See \Pico::sortPlugins() for details.

Throws

\RuntimeException

thrown when a plugin couldn't be loaded

loadComposerPlugins()

loadComposerPlugins(array<mixed,string>  $pluginBlacklist = array()) : array<mixed,string>

Loads plugins from vendor/pico-plugin.php

This method loads all plugins installed using composer and Pico's picocms/composer-installer installer by reading the pico-plugin.php in composer's vendor dir.

Parameters

array<mixed,string> $pluginBlacklist

class names of plugins not to load

Returns

array<mixed,string> —

installer names of the loaded plugins

loadLocalPlugins()

loadLocalPlugins(array<mixed,string>  $pluginBlacklist = array()) : void

Loads plugins from Pico::$pluginsDir in alphabetical order

Pico tries to load plugins from <plugin name>/<plugin name>.php and <plugin name>.php only. Plugin names are treated case insensitive. Pico will throw a RuntimeException if it can't load a plugin.

Plugin files MAY be prefixed by a number (e.g. 00-PicoDeprecated.php) to indicate their processing order. Plugins without a prefix will be loaded last. If you want to use a prefix, you MUST NOT use the reserved prefixes 00 to 09. Prefixes are completely optional, however, you SHOULD take the following prefix classification into consideration:

  • 10 to 19: Reserved
  • 20 to 39: Low level code helper plugins
  • 40 to 59: Plugins manipulating routing or the pages array
  • 60 to 79: Plugins hooking into template or markdown parsing
  • 80 to 99: Plugins using the onPageRendered event

Parameters

array<mixed,string> $pluginBlacklist

class names of plugins not to load

Throws

\RuntimeException

thrown when a plugin couldn't be loaded

sortPlugins()

sortPlugins() : void

Sorts all loaded plugins using a plugin dependency topology

Execution order matters: if plugin A depends on plugin B, it usually means that plugin B does stuff which plugin A requires. However, Pico loads plugins in alphabetical order, so events might get fired on plugin A before plugin B.

Hence plugins need to be sorted. Pico sorts plugins using a dependency topology, this means that it moves all plugins, on which a plugin depends, in front of that plugin. The order isn't touched apart from that, so they are still sorted alphabetically, as long as this doesn't interfere with the dependency topology. Circular dependencies are being ignored; their behavior is undefiend. Missing dependencies are being ignored until you try to enable the dependant plugin.

This method bases on Marc J. Schmidt's Topological Sort library in version 1.1.0, licensed under the MIT license. It uses the ArraySort implementation (class \MJS\TopSort\Implementations\ArraySort).

loadConfig()

loadConfig() : void

Loads the config.yml and any other *.yml from Pico::$configDir

After loading {@path "config/config.yml"}, Pico proceeds with any other existing config/*.yml file in alphabetical order. The file order is crucial: Config values which have been set already, cannot be overwritten by a succeeding file. This is also true for arrays, i.e. when specifying test: { foo: bar } in config/a.yml and test: { baz: 42 } in config/b.yml, {{ config.test.baz }} will be undefined!

evaluateRequestUrl()

evaluateRequestUrl() : void

Evaluates the requested URL

Pico uses the QUERY_STRING routing method (e.g. /pico/?sub/page) to support SEO-like URLs out-of-the-box with any webserver. You can still setup URL rewriting to basically remove the ? from URLs. However, URL rewriting requires some special configuration of your webserver, but this should be "basic work" for any webmaster...

With Pico 1.0 you had to setup URL rewriting (e.g. using mod_rewrite on Apache) in a way that rewritten URLs follow the QUERY_STRING principles. Starting with version 2.0, Pico additionally supports the REQUEST_URI routing method, what allows you to simply rewrite all requests to just index.php. Pico then reads the requested page from the REQUEST_URI environment variable provided by the webserver. Please note that QUERY_STRING takes precedence over REQUEST_URI.

Pico 0.9 and older required Apache with mod_rewrite enabled, thus old plugins, templates and contents may require you to enable URL rewriting to work. If you're upgrading from Pico 0.9, you will probably have to update your rewriting rules.

We recommend you to use the link filter in templates to create internal links, e.g. {{ "sub/page"|link }} is equivalent to {{ base_url }}/sub/page and {{ base_url }}?sub/page, depending on enabled URL rewriting. In content files you can use the %base_url% variable; e.g. %base_url%?sub/page will be replaced accordingly.

Heads up! Pico always interprets the first parameter as name of the requested page (provided that the parameter has no value). According to that you MUST NOT call Pico with a parameter without value as first parameter (e.g. http://example.com/pico/?someBooleanParam), otherwise Pico interprets someBooleanParam as name of the requested page. Use /pico/?someBooleanParam= or /pico/?index&someBooleanParam instead.

readPages()

readPages() : void

Reads the data of all pages known to Pico

The page data will be an array containing the following values:

Array key Type Description
id string relative path to the content file
url string URL to the page
title string title of the page (YAML header)
description string description of the page (YAML header)
author string author of the page (YAML header)
time int timestamp derived from the Date header
date string date of the page (YAML header)
date_formatted string formatted date of the page
hidden bool this page shouldn't be visible
raw_content string raw, not yet parsed contents of the page
meta string[] parsed meta data of the page
previous_page &array[] reference to the previous page
next_page &array[] reference to the next page
tree_node &array[] reference to the page's tree node

Please note that the previous_page and next_page keys don't exist until the onCurrentPageDiscovered event is triggered (\Pico::discoverPageSiblings()). The tree_node key doesn't exit until the onPageTreeBuilt event is triggered (\Pico::buildPageTree()).

sortPages()

sortPages() : void

Sorts all pages known to Pico

discoverPageSiblings()

discoverPageSiblings() : void

Walks through the list of all known pages and discovers the previous and next page respectively

discoverCurrentPage()

discoverCurrentPage() : void

Discovers the page data of the requested page as well as the previous and next page relative to it

buildPageTree()

buildPageTree() : void

Builds a tree structure containing all known pages

Pico's page tree is a list of all the tree's branches (no matter the depth). Thus, by iterating a array element, you get the nodes of a given branch. All leaf nodes do represent a page, but inner nodes may or may not represent a page (e.g. if there's a sub/page.md, but neither a sub/index.md nor a sub.md, the inner node sub, that is the parent of the sub/page node, represents no page itself).

A page's file path describes its node's path in the tree (e.g. the page sub/page.md is represented by the sub/page node, thus a child of the sub node and a element of the sub branch). However, the index page of a folder (e.g. sub/index.md), is not a node of the sub branch, but rather of the / branch. The page's node is not sub/index, but sub. If two pages are described by the same node (e.g. if both a sub/index.md and a sub.md exist), the index page takes precedence. Pico's main index page (i.e. index.md) is represented by the tree's root node / and a special case: it is the only node of the `` (i.e. the empty string) branch.

A node is represented by an array with the keys id, page and children. The id key contains a string with the node's name. If the node represents a page, the page key is a reference to the page's data array. If the node is a inner node, the children key is a reference to its matching branch (i.e. a list of the node's children). The order of a node's children matches the order in Pico's pages array.

If you want to walk the whole page tree, start with the tree's root node at $pageTree[""]["/"], or rather, use $pages["index"]["tree_node"]. The root node's children key is a reference to the / branch at $pageTree["/"], that is a list of the root node's direct child nodes and their siblings.

You MUST NOT iterate the page tree itself (i.e. the list of the tree's branches), its order is undefined and the array will be replaced by a non-iterable data structure with Pico 3.0.

getTwigVariables()

getTwigVariables() : array

Returns the variables passed to the template

URLs and paths (namely base_dir, base_url, theme_dir and theme_url) don't add a trailing slash for historic reasons.

Returns

array —

template variables

getTwigTemplate()

getTwigTemplate() : string

Returns the name of the Twig template to render

Returns

string —

template name

filterVariable()

filterVariable(mixed  $variable, integer|string  $filter = '', mixed|array  $options = null, integer|string|array<mixed,integer>|array<mixed,string>  $flags = null) : mixed

Filters a variable with a specified filter

This method basically wraps around PHP's filter_var() function. It filters data by either validating or sanitizing it. This is especially useful when the data source contains unknown (or foreign) data, like user supplied input. Validation is used to validate or check if the data meets certain qualifications, but will not change the data itself. Sanitization will sanitize the data, so it may alter it by removing undesired characters. It doesn't actually validate the data! The behaviour of most filters can optionally be tweaked by flags.

Heads up! Input validation is hard! Always validate your input data the most paranoid way you can imagine. Always prefer validation filters over sanitization filters; be very careful with sanitization filters, you might create cross-site scripting vulnerabilities!

Parameters

mixed $variable

value to filter

integer|string $filter

ID (int) or name (string) of the filter to apply; if omitted, the method will return FALSE

mixed|array $options

either a associative array of options to be used by the filter (e.g. array('default' => 42)), or a scalar default value that will be returned when the passed value is NULL (optional)

integer|string|array<mixed,integer>|array<mixed,string> $flags

either a bitwise disjunction of flags or a string with the significant part of a flag constant (the constant name is the result of "FILTERFLAG" and the given string in ASCII-only uppercase); you may also pass an array of flags and flag strings (optional)

Returns

mixed —

with a validation filter, the method either returns the validated value or, provided that the value wasn't valid, the given default value or FALSE; with a sanitization filter, the method returns the sanitized value; if no value (i.e. NULL) was given, the method always returns either the provided default value or NULL