// require_once PHPTAL_DIR.'PHPTAL/Php/Attribute.php'; // METAL Specification 1.0 // // argument ::= expression // // Example: // //
//

//


// // PHPTAL: (here not supported) // // // /** * @package phptal.php.attribute.metal * @author Laurent Bedubourg */ class PHPTAL_Php_Attribute_METAL_UseMacro extends PHPTAL_Php_Attribute { static $ALLOWED_ATTRIBUTES = array( 'metal:fill-slot', 'metal:define-macro', 'tal:define', ); public function start() { $this->pushSlots(); foreach ($this->tag->children as $child){ $this->generateFillSlots($child); } $macroname = strtr($this->expression,'-','_'); // local macro (no filename specified) and non dynamic macro name if (preg_match('/^[a-z0-9_]+$/i', $macroname)) { $code = sprintf( '%s%s($tpl, $ctx)', $this->tag->generator->getFunctionPrefix(), $macroname ); $this->tag->generator->pushCode($code); } // external macro or ${macroname}, use PHPTAL at runtime to resolve it else { $code = $this->tag->generator->interpolateTalesVarsInString($this->expression); $code = sprintf('executeMacro(%s); ?>', $code); $this->tag->generator->pushHtml($code); } $this->popSlots(); } public function end() { } private function pushSlots() { // reset template slots on each macro call ? // // NOTE: defining a macro and using another macro on the same tag // means inheriting from the used macro, thus slots are shared, it // is a little tricky to understand but very natural to use. // // For example, we may have a main design.html containing our main // website presentation with some slots (menu, content, etc...) then // we may define a member.html macro which use the design.html macro // for the general layout, fill the menu slot and let caller templates // fill the parent content slot without interfering. if (!$this->tag->hasAttribute('metal:define-macro')){ $this->tag->generator->pushCode('$ctx->pushSlots()'); } } private function popSlots() { // restore slots if not inherited macro if (!$this->tag->hasAttribute('metal:define-macro')){ $this->tag->generator->pushCode('$ctx->popSlots()'); } } private function generateFillSlots($tag) { if (false == ($tag instanceOf PHPTAL_Php_Tree)) return; // if the tag contains one of the allowed attribute, we generate it foreach (self::$ALLOWED_ATTRIBUTES as $attribute){ if ($tag->hasAttribute($attribute)){ $tag->generate(); return; } } // recurse foreach ($tag->children as $child){ $this->generateFillSlots($child); } } } ?>