-
Notifications
You must be signed in to change notification settings - Fork 9
Cookbook Data
- See: https://github.com/joomlatools/joomlatools-pages/pull/560
- See: https://github.com/joomlatools/joomlatools-pages/wiki/Data#frontmatter
It's possible to inject data dynamically in the page and layout frontmatter. To do that use the following:
- data://path/to/folder will fetch the complete data array and inject it, while
- data://path/to/folder[property] will inject a specific property.
A use case example of the data://
alias might be when you want to store a webservice api key in a config file then use that api key in your page front matter. Here's an example using the JustGiving.com api:
In your page's front matter you'll have code like this:
---
collection:
model: webservice?url=https://api.justgiving.com/{appId}/v1/account/{accountEmail}/pages?charityid={charityId}
---
Where {appId}
, {accountEmail}
, and {charityId}
relate to your JustGiving account. If, like us, you keep your api keys, config values and other sensitive values in a config file, how do you get those values in the front matter? You can't use php.
This is where the data://
alias comes in, it's easier to explain this with code so I'll dive right in and and explain as I go along.
First things first, the actual data file, any kind of data file will do, but we recommend an.ini
file because it's the most common format for config values and we can make use of section support of the ini format (see: https://en.wikipedia.org/wiki/INI_file).
Place your config file in your Pages root's data
folder, so, for example, /joomlatools-pages/data/config.ini
and fill it up with the values you want to store, something like this:
[justgiving]
appid=c12345d
email[email protected]
charityid=000000
A note about the above.. adding [justgiving]
above the block of values means that you don't have to have a separate config.ini
for each type of value you want to store, This is an example of the ini format's section support.
OK, we're armed with our config file and values, what do we do next? Next, you need to create a custom collection type by extending Pages' webservice model. This is so that Pages knows that you have config values and what to do with those config values.
To do that we need to make use of Pages' Extension API and create a file in our Pages root's extensions/pages/model/
folder (extensions
is a Pages reserved namespace).
This time it DOES matter what kind of file you create, it has to be a .php
file, for example, /joomlatools-pages/extensions/pages/model/justgiving.php
. Fill it up with the following code:
<?php
class ExtPagesModelJustgiving extends ComPagesModelWebservice
{
public function __construct(KObjectConfig $config)
{
parent::__construct($config);
$this->getState()
->insertRequired('jg_appid', 'alnum')
->insertRequired('jg_email', 'email')
->insertRequired('jg_charityid', 'int')
->insertRequired('jg_staging', 'boolean', false);
}
protected function _initialize(KObjectConfig $config)
{
$config->append([
'data_path' => 'fundraisingPages/fundraisingPage',
'identity_key' => 'slug',
'cache_path' => $this->getObject('com://site/pages.config')->getSitePath('cache') . '/justgiving',
'url' => 'https://{host}/{jg_appid}/v1/account/{jg_email}/pages?charityid={jg_charityid}'
]);
parent::_initialize($config);
}
public function getUrl(array $variables = array())
{
if($variables['jg_staging']) {
$variables['host'] = 'api.staging.justgiving.com';
} else {
$variables['host'] = 'api.justgiving.com';
}
return KHttpUrl::fromTemplate($this->_url, $variables);
}
public function fetchData($count = false)
{
$data = parent::fetchData();
$slugs = array();
array_walk($data, function(&$item) use(&$slugs)
{
$item['slug'] = $this->getObject('filter.factory')
->createFilter('slug')
->sanitize($item['eventName']);
$i = 0;
while(in_array( $item['slug'].'-'.$i, $slugs)) {
$i++;
}
$slugs[] = $item['slug'].'-'.$i;
if($i > 0) {
$item['slug'] = $item['slug'].'-'.$i;
}
});
return $data;
}
}
In the above file the block that starts with $this->getState()
is where the magic is happening.
$this->getState()
->insertRequired('jg_appid', 'alnum')
->insertRequired('jg_email', 'email')
->insertRequired('jg_charityid', 'int')
->insertRequired('jg_staging', 'boolean', false);
}
What you're doing here is you're telling Pages that in order to use this model, the state (value) of the following variables must be known. Really simple right?
Now for the fun bit, hooking it all up!
In your site where, on the page where you want to display your data list, in the front matter call the justgiving model we created above like this:
---
collection:
model: justgiving
state:
jg_appid: data://config/justgiving[appid]
jg_email: data://config/justgiving[email]
jg_charityid: data://config/justgiving[charityid]
---
You'll remember from this PR that Pages supports the data://
alias everywhere in the front matter.
Firstly, notice the repetition of the word state
?, Yes you guessed correctly that's where you set the state (value) of the variables that your model expects.
Secondly, did you spot the justgiving[value]
format of the alias? That's where the [justgiving]
bit of the config.ini
file, that we created in the first step, comes into play.
As per the instructions in the wiki (data://path/to/folder[property] will inject a specific property) the location of the value we want is PAGES_ROOT/data/config.php/[justgiving]/value
, easy right?
Now all that's left is to output our collection...
---
collection:
model: justgiving
state:
jg_appid: data://config/justgiving[appid]
jg_email: data://config/justgiving[email]
jg_charityid: data://config/justgiving[charityid]
---
<ul>
<? foreach(collection() as $event): ?>
<li><?= $event->title ?></li>
<? endforeach; ?>
</ul>
Happy coding :)
Got a question or need help? We have a forum on Github Discussions where you can get in touch with us.