From time to time there are suggestions about having logic in the blueprints, but for security concerns (?), blueprints are static yml files.
It’s not that easy to make a plugin to use logic in blueprint files because they are not very pluggable. However I’ve come up with an idea that works.
Plugin
Installation
- Save the plugin code (down this page) as a file and place it in
plugins/kirby-blueprint-logic/kirby-blueprint-logic.php
. - Done!
Setup
Add a php file and place it in blueprints/_project.php
if your blueprint filename is project.yml
. The underscore is important.
Usage
In the PHP, add stuff just like a blueprint, but you can use logic as well.
title: Project
fields:
<?php
for( $i = 0; $i < 3; $i++ ) : ?>
my_field_<?php echo $i . "\n"; ?>
label: My field <?php echo $i . "\n"; ?>
type: text
<?php endfor;
Pitfalls
- In some odd cases like if you rename a page to
edit
ortemplate
. It can trigger errors.
The plugin code
<?php
if( class_exists('panel') ) {
class BlueprintLogic {
public $path;
public $url;
public $panelpages;
public $id;
public $page;
public $yml;
public $ymlFile;
public $snippet;
public function setup() {
$this->setPath();
}
public function setPath() {
$this->panelpages = panel()->urls()->index() . '/pages/';
$this->setCurrentUrl();
if( $this->isPage() ) {
$path = kirby()->roots()->blueprints() . DS . 'default.yml';
$this->setId();
$this->setPage();
$this->setYml();
$this->setPhp();
if( ! empty( $this->php ) ) {
$this->loadPhp();
}
}
}
public function setCurrentUrl() {
$this->url = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}
public function setId() {
$url = $this->url;
$url = preg_replace('/\/edit$/', '', $url);
$url = preg_replace('/\/toggle$/', '', $url);
$url = preg_replace('/\/template$/', '', $url);
$url = preg_replace('/\/url$/', '', $url);
$url = preg_replace('/\/delete$/', '', $url);
$url = ( strstr($url, '/file/', true) ) ? strstr($url, '/file/', true) : $url;
$url = str_replace($this->panelpages, '', $url);
$this->id = $url;
}
public function setPage() {
$this->page = page($this->id);
}
public function setYml() {
$root = kirby()->roots()->blueprints();
if( file_exists( $root . DS . $this->page->template() . '.yml' ) ) {
$this->yml = $this->page->template();
} else {
$this->yml = 'default';
}
$this->ymlFile = $root . DS . $this->yml . '.yml';
}
public function isPage() {
if( str::contains( $this->url, $this->panelpages ) ) {
return true;
} else {
return false;
}
}
public function setPhp() {
$php = kirby()->roots()->blueprints() . DS . '_' . $this->yml . '.php';
if( file_exists( $php)) {
$this->php = $php;
}
}
public function loadPhp() {
$php_content = tpl::load($this->php, array(
'site' => site(),
'children' => site()->children(),
'page' => $this->page,
));
$yml_content = tpl::load($this->ymlFile);
if( $php_content != $yml_content ) {
f::write($this->ymlFile, $php_content);
go($this->url);
}
}
}
$blueprintlogic = new BlueprintLogic();
$blueprintlogic->setup();
}
I will release it on github in 2017.
What do you think of the idea?