---
Title: A Page with Twig Template
Description:
Author: Marcus
Date: 2020-06-07

data:
  url: https://jsonplaceholder.typicode.com/users
  type: json
---

# A Page with Twig Template 

💡 If you end up with empty `<p></p>` in your html that's most likely from Twig directives (like `for`)
Best is you wrap the code in `<div markdown="0"></div>` in case you enabled `content_config.extra` in your config settings

{{dump(meta.data)}}


{% for user in meta.data %}

|           Smarty          |          Value          |
|---------------------------|-------------------------|
| `{{ user.id }}`           | {{ user.id }}           |
| `{{ user.name }}`         | {{ user.name }}         |
| `{{ user.address.city }}` | {{ user.address.city }} |

{{dump(user.company)}}

{% endfor %}
view raw a_page.md hosted with ❤ by GitHub
<?php
/**
* Pico External Data Plugin - Fetch External Data and Add it to Meta
*
* In your YAML section add the following keys:
*
* data.url: remote resource or local file or pico page
* data.type: json|internal|pico|csv
*
* Remote API Example:
*
* ```
* ---
* data:
* url: https://jsonplaceholder.typicode.com/users
* type: json
* ---
*
* # External Data
*
* {{dump(meta.data)}}
*
* ```
*
* Data From Local Pico Page
*
* ```
* ---
* data:
* url: data.md
* type: pico
* ---
*
* # External Data
*
* {{dump(meta.data)}}
*
* ```
*
* You can access the data globally in $meta['data']
*
* if your data comes back like this:
*
* ```
* {
* "users": [
* {"id": 1, "name": "user"},
* ]
* }
* ```
* you access it `$meta['data']['users']`
*
*
* if your data comes back like this:
*
* ```
* [
* {"id": 1, "name": "user"},
* {"id": 2, "name": "user2"}
* ]
* ```
* you access it `$meta['data']`
*
*
*
*
* @author Marcus Obst
* @link https://marcus-obst.de/blog/pico-cms-external-api
* @license http://opensource.org/licenses/MIT The MIT License
* @version 0.2
*/
class ExternalData extends AbstractPicoPlugin
{
const API_VERSION = 2;
protected $enabled = true;
protected $type = null;
protected $dependsOn = [];
/**
* Triggered after Pico has parsed the meta header
*
* @see DummyPlugin::onMetaParsing()
* @see Pico::getFileMeta()
*
* @param string[] &$meta parsed meta data
*
* @return void
*/
public function onMetaParsed(array &$meta)
{
$type = 'text';
$remote = false;
if (empty($meta['data']['url']) && empty($meta['data']['type'])) {
return;
}
if (!empty($meta['data']['type'])) {
$type = $meta['data']['type'];
}
if (!empty($meta['data']['url'])) {
$url = $meta['data']['url'];
}
if (empty($meta['data']['type']) && pathinfo($url, PATHINFO_EXTENSION)) {
$type = pathinfo($url, PATHINFO_EXTENSION);
}
if (strpos($url, 'http') === false && !in_array($type, ['pico','internal'])) {
$url = $this->getBaseUrl().$url;
$remote = true;
}
/**
* Parse meta section of another pico page
* grab the YAML section
*/
if (in_array($type, ['pico','internal'])) {
$file = $this->getConfig('content_dir').$url;
if (file_exists($file)) {
$data = $this->parseFileMeta(file_get_contents($file), $this->getMetaHeaders());
// get standard meta keys
$tempMeta = $this->getPico()->getFileMeta();
unset($tempMeta['data']);
// subtract the standard meta keys
$meta['data'] = array_diff_key($data, $tempMeta);
}
return;
}
/**
* Adjust to your need
* @link https://www.php.net/manual/en/context.php
*/
$arrContextOptions= [
'http' => [
'ignore_errors' => true
],
"ssl" => [
"verify_peer"=>false,
"verify_peer_name"=>false,
],
];
$meta['data'] = file_get_contents($url, false, stream_context_create($arrContextOptions));
if ($type === 'json') {
// if change data if you have to.
$meta['data'] = json_decode($meta['data'], true);
}
}
}
<?php
/**
* Render Inline Twig Templates
*
* Instead of rely on Pico's `%meta.*% replacement mechanism,
* write Twig tags directly into you page.
*
* This might be an security issue, you need to know what you are doing!
*
* @author Marcus Obst
* @link https://gist.github.com/marcus-at-localhost/19c8133509f6cd3001cd96ce7038ab92
* @license http://opensource.org/licenses/MIT
* @version 0.2
*/
class TwigStringLoader extends AbstractPicoPlugin
{
const API_VERSION = 2;
/**
* Fix urlencode() curly brackets in src and href
*
* @link https://stackoverflow.com/a/20104953/814031
* @param string $template_string html string
* @return string
*/
protected function fix_template_variable_tokens($template_string)
{
$pattern = "/%7B%7B(.*?)%7D%7D/";
$replacement = '{{$1}}';
return preg_replace($pattern, $replacement, $template_string);
}
public function onPageRendering(&$templateName, array &$twigVariables)
{
// fix urlencoded src or href attributes with twig curly braces
// @link https://github.com/erusev/parsedown/issues/266#issuecomment-159139099
$twigVariables['content'] = $this->fix_template_variable_tokens($twigVariables['content']);
// render Twig Template from String
$template = $this->getTwig()->createTemplate($twigVariables['content']);
$twigVariables['content'] = $template->render($twigVariables);
}
public function onTwigRegistered(Twig_Environment &$twig)
{
$twig->addExtension(new \Twig\Extension\StringLoaderExtension());
}
}