/** * @param string $id * @param callable $engine * @param null $template * * @return mixed */ public function render($id, $engine = null, $template = null) { $definition = $this->app->views[$id]; if (!$engine) { $engine = \Patron\Engine::get_singleton(); } $page = $this->resolve_view_page($id); $class = $this->resolve_view_classname($definition); $view = new $class($id, $definition, $engine, $this->app->document, $page); $rc = $view(); return $template ? $engine($template, $rc) : $rc; }
protected function evaluate($context, $expression, $tokens, $silent) { $expression_path = []; foreach ($tokens as $i => $part) { $identifier = $part[self::TOKEN_VALUE]; $expression_path[] = $identifier; switch ($part[self::TOKEN_TYPE]) { case self::TOKEN_TYPE_IDENTIFIER: if (!is_array($context) && !is_object($context)) { throw new \InvalidArgumentException(\ICanBoogie\format('Unexpected variable type: %type (%value) for %identifier in expression %expression, should be either an array or an object', ['%type' => gettype($context), '%value' => $context, '%identifier' => $identifier, '%expression' => $expression])); } $exists = false; $next_value = $this->extract_value($context, $identifier, $exists); if (!$exists) { if ($silent) { return null; } throw new ReferenceError(\ICanBoogie\format('Reference to undefined property %path of expression %expression (defined: :keys) in: :value', ['path' => implode('.', $expression_path), 'expression' => $expression, 'keys' => implode(', ', $context instanceof Context ? $context->keys() : array_keys((array) $context)), 'value' => \ICanBoogie\dump($context)])); } $context = $next_value; break; case self::TOKEN_TYPE_FUNCTION: $method = $identifier; $args = $part[self::TOKEN_ARGS]; $args_evaluate = $part[self::TOKEN_ARGS_EVALUATE]; if ($args_evaluate) { $this->engine->error('we should evaluate %eval', ['%eval' => $args_evaluate]); } # # if value is an object, we check if the object has the method # if (is_object($context) && method_exists($context, $method)) { $context = call_user_func_array([$context, $method], $args); break; } # # well, the object didn't have the method, # we check internal functions # $callback = $this->engine->functions->find($method); # # if no internal function matches, we try string and array functions # depending on the type of the value # if (!$callback) { if (is_string($context)) { if (function_exists('str' . $method)) { $callback = 'str' . $method; } else { if (function_exists('str_' . $method)) { $callback = 'str_' . $method; } } } else { if (is_array($context) || is_object($context)) { if (function_exists('ICanBoogie\\array_' . $method)) { $callback = 'ICanBoogie\\array_' . $method; } else { if (function_exists('array_' . $method)) { $callback = 'array_' . $method; } } } } } # # our last hope is to try the function "as is" # if (!$callback) { if (function_exists($method)) { $callback = $method; } } if (!$callback) { if (is_object($context) && method_exists($context, '__call')) { $context = call_user_func_array([$context, $method], $args); break; } } # # # if (!$callback) { throw new \Exception(\ICanBoogie\format('Unknown method %method for expression %expression.', ['%method' => $method, '%expression' => $expression])); } # # create evaluation # array_unshift($args, $context); if (PHP_MAJOR_VERSION > 5 || PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 2) { if ($callback == 'array_shift') { $context = array_shift($context); } else { $context = call_user_func_array($callback, $args); } } else { $context = call_user_func_array($callback, $args); } break; } } return $context; }
/** * JavaScript assets can be collected and rendered into `SCRIPT` elements with the `p:document:js` * element. The `href` attribute is used to add an asset to the collection. The `weight` * attribute specifies the weight of that asset. If the `weight` attribute is not specified, * the weight of the asset is defaulted to 100. If the `href` attribute is not specified, * the assets are rendered. If a template is specified the collection is passed as `this`, * otherwise the collection is rendered into an HTML string of `SCRIPT` elements. * * <pre> * <p:document:js * href = string * weight = int> * <!-- Content: p:with-params, template? --> * </p:document:js> * </pre> * * Example: * * <pre> * <p:document:js href="/public/page.js" /> * <p:document:js href="/public/reset.js" weight="-100" /> * <p:document:js /> * </pre> * * will produce: * * <pre> * <script src="/public/reset.css" type="text/javascript"></script> * <script src="/public/page.css" type="text/javascript"></script> * </pre> * * @param array $args * @param Engine $engine * @param mixed $template * * @return void|string */ public static function markup_document_js(array $args, Engine $engine, $template) { $document = \Brickrouge\get_document(); if (isset($args['href'])) { $document->js->add($args['href'], $args['weight'], dirname($engine->get_file())); return null; } return $template ? $engine($template, $document->js) : (string) $document->js; }