Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add map and sort_by Twig filters #273

Merged
merged 12 commits into from
Nov 30, 2015
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ Released: -
```
* [New] This is Picos first stable release! The Pico Community wants to thank
all contributors and users which made this possible!
* [New] Introducing the `PicoTwigExtension` Twig extension
* [New] New `markdown` filter for Twig to parse markdown strings; Note: If you
want to parse the contents of a page, use the `content` filter instead
* [New] New `sort_by` filter to sort a array by a specified key or key path
* [New] New `map` filter to get the values of the given key or key path
* [New] New PHP version check in `index.php`
* [Changed] Improve documentation
* [Changed] Improve table styling in default theme
Expand Down
9 changes: 5 additions & 4 deletions _build/generate-phpdoc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ set -e

# parameters
PHPDOC_CONFIG="$1"
PHPDOC_CACHE_DIR="$3"
PHPDOC_TARGET_DIR="$4"
PHPDOC_TITLE="$5"
PHPDOC_CACHE_DIR="$2"
PHPDOC_TARGET_DIR="$3"
PHPDOC_TITLE="$4"

# print parameters
echo "Generating phpDocs..."
printf 'PHPDOC_SOURCE_DIR="%s"\n' "$PHPDOC_SOURCE_DIR"
printf 'PHPDOC_CONFIG="%s"\n' "$PHPDOC_CONFIG"
printf 'PHPDOC_CACHE_DIR="%s"\n' "$PHPDOC_CACHE_DIR"
printf 'PHPDOC_TARGET_DIR="%s"\n' "$PHPDOC_TARGET_DIR"
printf 'PHPDOC_TITLE="%s"\n' "$PHPDOC_TITLE"
echo
Expand Down
27 changes: 16 additions & 11 deletions content-sample/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ something like the following:
This template will show a list of your articles, so you probably want to
do something like this:
```
{% for page in pages %}
{% 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>
Expand All @@ -127,16 +127,10 @@ something like the following:
{% endif %}
{% endfor %}
```
4. Let Pico sort pages by date by setting `$config['pages_order_by'] = 'date';`
in your `config/config.php`. To use a descending order (newest articles
first), also add `$config['pages_order'] = 'desc';`. The former won't affect
pages without a `Date` meta header, but the latter does. To use ascending
order for your page navigation again, add Twigs `reverse` filter to the
navigation loop (`{% for page in pages|reverse %}...{% endfor %}`) in your
themes `index.twig`.
5. Make sure to exclude the blog articles from your page navigation. You can
4. Make sure to exclude the blog articles from your page navigation. You can
achieve this by adding `{% if not page starts with "blog/" %}...{% endif %}`
to the navigation loop.
to the navigation loop (`{% for page in pages|reverse %}...{% endfor %}`)
in your themes `index.twig`.

## Customization

Expand All @@ -162,7 +156,7 @@ 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 }}` - Conatins the values you set in `config/config.php`
* `{{ 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
Expand Down Expand Up @@ -211,6 +205,17 @@ Pages can be used like the following:
{% endfor %}
</ul>

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"|split(":")) %}...{% endfor %}`
iterates through all pages, ordered by the `nav` meta header; please note the
`"meta:nav"|split(":")` part of the example, which passes `['meta', 'nav']` to
the filter describing a key path). 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
Expand Down
39 changes: 11 additions & 28 deletions lib/Pico.php
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,7 @@ public function parseFileMeta($rawContent, array $headers)
$meta[$fieldId] = $meta[$fieldName];
unset($meta[$fieldName]);
}
} else {
} elseif (!isset($meta[$fieldId])) {
// guarantee array key existance
$meta[$fieldId] = '';
}
Expand All @@ -786,10 +786,7 @@ public function parseFileMeta($rawContent, array $headers)
}
} else {
// guarantee array key existance
foreach ($headers as $id => $field) {
$meta[$id] = '';
}

$meta = array_fill_keys(array_keys($headers), '');
$meta['time'] = $meta['date_formatted'] = '';
}

Expand Down Expand Up @@ -1119,6 +1116,9 @@ public function getNextPage()
/**
* Registers the twig template engine
*
* This method also registers Picos core Twig filters `link` and `content`
* as well as Picos {@link PicoTwigExtension} Twig extension.
*
* @see Pico::getTwig()
* @return void
*/
Expand All @@ -1127,23 +1127,15 @@ protected function registerTwig()
$twigLoader = new Twig_Loader_Filesystem($this->getThemesDir() . $this->getConfig('theme'));
$this->twig = new Twig_Environment($twigLoader, $this->getConfig('twig_config'));
$this->twig->addExtension(new Twig_Extension_Debug());
$this->twig->addExtension(new PicoTwigExtension($this));

$this->registerTwigFilter();
}

/**
* Registers Picos additional Twig filters
*
* @return void
*/
protected function registerTwigFilter()
{
$pico = $this;

// link filter
// register link filter
$this->twig->addFilter(new Twig_SimpleFilter('link', array($this, 'getPageUrl')));

// content filter
// register content filter
// we pass the $pages array by reference to prevent multiple parser runs for the same page
// this is the reason why we can't register this filter as part of PicoTwigExtension
$pico = $this;
$pages = &$this->pages;
$this->twig->addFilter(new Twig_SimpleFilter('content', function ($page) use ($pico, &$pages) {
if (isset($pages[$page])) {
Expand All @@ -1156,15 +1148,6 @@ protected function registerTwigFilter()
}
return null;
}));

// markdown filter
$this->twig->addFilter(new Twig_SimpleFilter('markdown', function ($markdown) use ($pico) {
if ($pico->getParsedown() === null) {
throw new LogicException("Unable to parse file contents: Parsedown instance wasn't registered yet");
}

return $pico->getParsedown()->text($markdown);
}));
}

/**
Expand Down
Loading