Last active
August 29, 2015 14:05
-
-
Save ikkez/ef2cfaa3009c439ea484 to your computer and use it in GitHub Desktop.
F3 Asset Manager
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>F3 Asset Manager</title> | |
</head> | |
<body> | |
<h1>Asset Collector</h1> | |
<F3:include href="templates/assets_widget.html" /> | |
<F3:asset type="css" src="foo/main.css" key="5" /> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
Asset manager for the PHP Fat-Free Framework | |
The contents of this file are subject to the terms of the GNU General | |
Public License Version 3.0. You may not use this file except in | |
compliance with the license. Any of the license terms and conditions | |
can be waived if you get permission from the copyright holder. | |
Copyright (c) 2014 by ikkez | |
Christian Knuth <ikkez0n3@gmail.com> | |
@version 0.3.0 | |
@date: 08.08.2014 | |
**/ | |
class Assets extends Prefab { | |
/** @var \Template */ | |
protected $template; | |
/** @var array */ | |
protected $assets; | |
public function __construct($autoAddMarker=false) { | |
$this->template = \Template::instance(); | |
$f3 = \Base::instance(); | |
$this->reset(); | |
if($autoAddMarker) { | |
$this->template->extend('head', 'Assets::render_head'); | |
$this->template->extend('body', 'Assets::render_body'); | |
} | |
$this->template->extend('asset', 'Assets::add'); | |
$this->template->afterrender(function($data) use ($f3) { | |
$data=str_replace('{>ASSETS-HEAD<}',$f3->call('\Assets->getAssets','head'),$data); | |
$data=str_replace('{>ASSETS-FOOTER<}', $f3->call('\Assets->getAssets','footer'),$data); | |
return $data; | |
}); | |
} | |
/** | |
* reset form handler data | |
*/ | |
public function reset() { | |
$this->assets = array(); | |
} | |
/** | |
* get asset code from slot | |
* @param string $slot | |
* @return string | |
*/ | |
public function getAssets($slot='head') { | |
if(!isset($this->assets[$slot])) | |
return ''; | |
ksort($this->assets[$slot]); | |
return implode("\n",$this->assets[$slot])."\n"; | |
} | |
/** | |
* add asset code to slot | |
* @param string $code | |
* @param string $slot | |
* @param mixed $priority | |
*/ | |
public function addAsset($code,$slot='head',$priority=null) { | |
if(!isset($this->assets[$slot])) | |
$this->assets[$slot]=array(); | |
if($priority) | |
$this->assets[$slot][$priority] = ($slot=='head'?"\t":'').$code; | |
else | |
$this->assets[$slot][] = ($slot=='head'?"\t":'').$code; | |
} | |
/** | |
* parse node data and push new asset code | |
* @param $node | |
* @return mixed | |
*/ | |
public function _asset($node) | |
{ | |
$node = \Base::instance()->unserialize($node); | |
$params = $node['@attrib']; | |
unset($node['@attrib']); | |
if (array_key_exists('type',$params) && array_key_exists('src',$params)) { | |
$type = $this->template->resolve($params['type']); | |
$src = $this->template->resolve($params['src']); | |
$slot = isset($params['slot']) ? $params['slot'] : 'head'; | |
$prio = isset($params['key']) ? $this->template->resolve($params['key']) : null; | |
if($type=='css') | |
$this->addAsset('<link rel="stylesheet" type="text/css" href="'.$src.'" />', | |
$slot,$prio); | |
elseif ($type=='js') | |
$this->addAsset('<script src="'.$src.'"></script>', $slot, $prio); | |
} | |
return $this->assets; | |
} | |
/** | |
* auto-append slot marker into <head> | |
* @param $node | |
* @return string | |
*/ | |
public function _head($node) | |
{ | |
unset($node['@attrib']); | |
$content = array(); | |
// bypass inner content nodes | |
foreach ($node as $el) | |
$content[] = $this->template->build($el); | |
return '<head>'.implode("\n", $content).'{>ASSETS-HEAD<}</head>'; | |
} | |
/** | |
* auto-append footer slot marker into <body> | |
* @param $node | |
* @return string | |
*/ | |
public function _body($node) | |
{ | |
$params = ''; | |
if (isset($node['@attrib'])) { | |
$params = $this->resolveAttr($node['@attrib']); | |
unset($node['@attrib']); | |
} | |
$content = array(); | |
// bypass inner content nodes | |
foreach ($node as $el) | |
$content[] = $this->template->build($el); | |
return '<body'.$params.'>'.implode("\n", $content)."\n".'{>ASSETS-FOOTER<}</body>'; | |
} | |
/** | |
* general bypass for unhandled tag attributes | |
* @param array $attr | |
* @return string | |
*/ | |
public function resolveAttr(array $attr) | |
{ | |
$out = ''; | |
foreach ($attr as $key => $value) { | |
// build dynamic tokens | |
if (preg_match('/{{(.+?)}}/s', $value)) | |
$value = $this->template->build($value); | |
if (preg_match('/{{(.+?)}}/s', $key)) | |
$key = $this->template->build($key); | |
// inline token | |
if (is_numeric($key)) | |
$out .= ' '.$value; | |
// value-less parameter | |
elseif($value==NULL) | |
$out .= ' '.$key; | |
// key-value parameter | |
else | |
$out .= ' '.$key.'="'.$value.'"'; | |
} | |
return $out; | |
} | |
/** | |
* handle <asset> template tag | |
* @param $node | |
* @return mixed | |
*/ | |
static public function add(array $node) | |
{ // dynamic build on final rendering | |
return '<?php \Assets::instance()->_asset(\''. | |
\Base::instance()->serialize($node).'\'); ?>'; | |
} | |
/** | |
* handle <head> template tag | |
* @param $node | |
* @return mixed | |
*/ | |
static public function render_head(array $node) | |
{ // static build is enough to insert a marker | |
$that = \Assets::instance(); | |
return $that->_head($node); | |
} | |
/** | |
* handle <head> template tag | |
* @param $node | |
* @return mixed | |
*/ | |
static public function render_body(array $node) | |
{ // static build is enough to insert a marker | |
$that = \Assets::instance(); | |
return $that->_body($node); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<F3:asset type="{{ @type }}" src="{{ @jq }}" slot="footer" /> | |
<F3:asset type="js" src="js/widget_a.js" slot="footer"/> | |
<F3:asset type="css" src="js/widget_a.css" key="20" /> | |
<div class="widget_a"> | |
<h3>Widget</h3> | |
<p>Lorem Ipsun...</p> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$f3 = require('lib/base.php'); | |
$f3->route('GET /asset-test', function (Base $f3) { | |
$f3->set('type','js'); | |
$f3->set('jq','jquery.min.js'); | |
\Assets::instance(true); | |
echo \Template::instance()->render('templates/assets.html'); | |
}); | |
$f3->run(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
oh, seems like i have overlook your comment. well nice idea ;)
i'll consider this when i'll come to complete this plugin. there are still some issues with sorting by dependency and the lack of adding remote/external assets from CDNs. and a feature to minify the given files :)