diff --git a/codegen.sh b/codegen.sh index 85624d7c0..f39f8bf33 100755 --- a/codegen.sh +++ b/codegen.sh @@ -1,12 +1,21 @@ #!/bin/bash set -e _PWD=$PWD -SPECS=$(find -name 'spec.json' | xargs -n1 dirname) +SPECS=$(find $PWD -name 'spec.json' | xargs -n1 dirname) for SPEC in $SPECS; do echo "=== spec $SPEC ===" - cd $SPEC && spec && cd $_PWD + cd $SPEC && rm -rf spec && spec && cd $_PWD SRC=$(dirname $(dirname $SPEC)) echo "=== codegen $SRC ===" - cd $SRC && ../codegen/codegen.php && go fmt && cd $_PWD -done \ No newline at end of file + GOPATHS=$(codegen/codegen.php $(basename $SRC) | tee -a /dev/stderr | xargs --no-run-if-empty -n1 dirname | sort | uniq) + for FOLDER in $GOPATHS; do + if [[ $FOLDER != "." ]]; then + echo "== go fmt $FOLDER ==" + cd $FOLDER + go fmt + cd $_PWD + fi + done +done + diff --git a/codegen/codegen.php b/codegen/codegen.php index b13d26c7a..026f20c3d 100755 --- a/codegen/codegen.php +++ b/codegen/codegen.php @@ -1,15 +1,34 @@ #!/usr/bin/env php set_paths(array(__DIR__ . "/templates/")); $tpl->set_compile_location("/tmp", true); $tpl->add_default("newline", "\n"); -$api_files = glob("docs/src/spec/*.json"); +$generators = array(); +exec("find -L " . __DIR__ . "/" . $project . " -name index.php", $generators); + +$api_files = glob($project . "/docs/src/spec/*.json"); $apis = array_map(function($filename) { return array_change_key_case_recursive(json_decode(file_get_contents($filename), true)); }, $api_files); @@ -33,17 +54,34 @@ usort($apis, function($a, $b) { return strcmp($a['interface'], $b['interface']); }); -foreach (array("structs", "handlers", "interfaces", "request", "") as $type) { +$parsers = array( + "uint64" => "parseUInt64", + "bool" => "parseBool", +); + +foreach ($generators as $generator) { + $tpl->set_paths(array(dirname($generator) . "/", __DIR__ . "/templates/")); + + $dirname = strstr(dirname($generator), $project. "/"); + if (empty($dirname)) { + $dirname = $project; + } + // echo "generator=". dirname($generator) . " project=$project, dirname=$dirname\n"; + if (!is_dir($dirname) && !empty($dirname)) { + mkdir($dirname, 0777, true); + } + $common = compact("parsers"); + include($generator); +} + +/* foreach (array("structs", "handlers", "interfaces", "request", "") as $type) { foreach ($apis as $api) { if (is_array($api['struct'])) { $name = ucfirst($api['interface']); $filename = str_replace("..", ".", strtolower($name) . "." . $type . ".go"); $tpl->load("http_$type.tpl"); - $tpl->assign("parsers", array( - "uint64" => "parseUInt64", - "bool" => "parseBool", - )); + $tpl->assign("parsers", $tpl->assign("package", $api['package']); $tpl->assign("name", $name); $tpl->assign("self", strtolower(substr($name, 0, 1))); @@ -82,6 +120,7 @@ foreach (array("routes") as $type) { file_put_contents($filename, $contents); } +*/ // camel case to snake case function decamel($input) { diff --git a/codegen/codegen_old.php b/codegen/codegen_old.php new file mode 100755 index 000000000..c74663b27 --- /dev/null +++ b/codegen/codegen_old.php @@ -0,0 +1,94 @@ +#!/usr/bin/env php +set_paths(array(__DIR__ . "/")); +$tpl->set_compile_location("/tmp", true); +$tpl->add_default("newline", "\n"); + +$api_files = glob("docs/src/spec/*.json"); +$apis = array_map(function($filename) { + return array_change_key_case_recursive(json_decode(file_get_contents($filename), true)); +}, $api_files); + +usort($apis, function($a, $b) { + return strcmp($a['interface'], $b['interface']); +}); + +foreach (array("structs", "handlers", "interfaces", "request", "") as $type) { + foreach ($apis as $api) { + if (is_array($api['struct'])) { + $name = ucfirst($api['interface']); + $filename = str_replace("..", ".", strtolower($name) . "." . $type . ".go"); + + $tpl->load("http_$type.tpl"); + $tpl->assign("parsers", array( + "uint64" => "parseUInt64", + "bool" => "parseBool", + )); + $tpl->assign("package", $api['package']); + $tpl->assign("name", $name); + $tpl->assign("self", strtolower(substr($name, 0, 1))); + $tpl->assign("api", $api); + $tpl->assign("structs", $api['struct']); + $imports = array(); + foreach ($api['struct'] as $struct) { + if (isset($struct['imports'])) + foreach ($struct['imports'] as $import) { + $imports[] = $import; + } + } + $tpl->assign("imports", $imports); + $tpl->assign("calls", $api['apis']); + $contents = str_replace("\n\n}", "\n}", $tpl->get()); + + $save = true; + if ($type === "" && file_exists($filename)) { + $save = false; + } + if ($save) { + file_put_contents($filename, $contents); + } + } + } +} + +foreach (array("routes") as $type) { + $name = ucfirst($api['interface']); + $filename = str_replace("..", ".", $type . ".go"); + + $tpl->load("http_$type.tpl"); + $tpl->assign("package", reset($apis)['package']); + $tpl->assign("apis", $apis); + $contents = $tpl->get(); + + file_put_contents($filename, $contents); +} + +// camel case to snake case +function decamel($input) { + preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches); + $ret = $matches[0]; + foreach ($ret as &$match) { + $match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match); + } + return implode('_', $ret); +} diff --git a/codegen/composer.json b/codegen/composer.json new file mode 100644 index 000000000..eae1c2b80 --- /dev/null +++ b/codegen/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "monotek/minitpl": "^1.1" + } +} diff --git a/codegen/composer.lock b/codegen/composer.lock new file mode 100644 index 000000000..2722ba0bc --- /dev/null +++ b/codegen/composer.lock @@ -0,0 +1,67 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "27ca9291b11653ca55b2eb53454a2d60", + "content-hash": "789a4ed7b74ed2be14054128f82abcde", + "packages": [ + { + "name": "monotek/minitpl", + "version": "v1.1.4", + "source": { + "type": "git", + "url": "https://github.com/titpetric/minitpl.git", + "reference": "613a596b3dee3c121283fad3f84d06d83ecb5125" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/titpetric/minitpl/zipball/613a596b3dee3c121283fad3f84d06d83ecb5125", + "reference": "613a596b3dee3c121283fad3f84d06d83ecb5125", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "Monotek\\MiniTPL": "code" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "CC BY-SA 3.0" + ], + "authors": [ + { + "name": "Tit Petric", + "email": "tit.petric@monotek.net", + "homepage": "http://titpetric.github.io", + "role": "developer" + } + ], + "description": "Miniature fully featured PHP template engine", + "homepage": "https://github.com/titpetric/minitpl", + "keywords": [ + "minitpl", + "monotek", + "php", + "small", + "smarty", + "template", + "tiny" + ], + "time": "2016-02-07 13:23:38" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/codegen/crm/index.php b/codegen/crm/index.php new file mode 100644 index 000000000..2da0ce18a --- /dev/null +++ b/codegen/crm/index.php @@ -0,0 +1,56 @@ +load("http_routes.tpl"); +$tpl->assign($common); +$tpl->assign("package", basename($dirname)); +$tpl->assign("name", $name); +$tpl->assign("api", $api); +$tpl->assign("apis", $apis); +$tpl->assign("self", strtolower(substr($name, 0, 1))); +$tpl->assign("structs", $api['struct']); +$imports = array(); +foreach ($api['struct'] as $struct) { + if (isset($struct['imports'])) + foreach ($struct['imports'] as $import) { + $imports[] = $import; + } +} +$tpl->assign("imports", $imports); +$tpl->assign("calls", $api['apis']); +$contents = str_replace("\n\n}", "\n}", $tpl->get()); + +file_put_contents($filename, $contents); +echo $filename . "\n"; + +foreach ($apis as $api) { + if (is_array($api['struct'])) { + $name = ucfirst($api['interface']); + $filename = $dirname . "/" . str_replace("..", ".", strtolower($name) . ".go"); + + $tpl->load("http_.tpl"); + $tpl->assign($common); + $tpl->assign("package", basename(__DIR__)); + $tpl->assign("name", $name); + $tpl->assign("api", $api); + $tpl->assign("self", strtolower(substr($name, 0, 1))); + $tpl->assign("structs", $api['struct']); + $imports = array(); + foreach ($api['struct'] as $struct) { + if (isset($struct['imports'])) + foreach ($struct['imports'] as $import) { + $imports[] = $import; + } + } + $tpl->assign("imports", $imports); + $tpl->assign("calls", $api['apis']); + $contents = str_replace("\n\n}", "\n}", $tpl->get()); + + if (!file_exists($filename)) { + file_put_contents($filename, $contents); + echo $filename . "\n"; + } + } +} diff --git a/codegen/crm/rest/index.php b/codegen/crm/rest/index.php new file mode 100644 index 000000000..5401d36c6 --- /dev/null +++ b/codegen/crm/rest/index.php @@ -0,0 +1,42 @@ + function($name, $api) { + return strtolower($name) . ".go"; + }, + "http_request.tpl" => function($name, $api) { + return strtolower($name) . "_requests.go"; + }, + "http_handlers.tpl" => function($name, $api) { + return strtolower($name) . "_handlers.go"; + } +); + +foreach ($templates as $template => $fn) +foreach ($apis as $api) { + if (is_array($api['struct'])) { + $name = ucfirst($api['interface']); + $filename = $dirname . "/" . $fn($name, $api); + + $tpl->load($template); + $tpl->assign($common); + $tpl->assign("package", basename(__DIR__)); + $tpl->assign("name", $name); + $tpl->assign("api", $api); + $tpl->assign("self", strtolower(substr($name, 0, 1))); + $tpl->assign("structs", $api['struct']); + $imports = array(); + foreach ($api['struct'] as $struct) { + if (isset($struct['imports'])) + foreach ($struct['imports'] as $import) { + $imports[] = $import; + } + } + $tpl->assign("imports", $imports); + $tpl->assign("calls", $api['apis']); + $contents = str_replace("\n\n}", "\n}", $tpl->get()); + + file_put_contents($filename, $contents); + echo $filename . "\n"; + } +} diff --git a/codegen/crm/types/index.php b/codegen/crm/types/index.php new file mode 100644 index 000000000..5427926df --- /dev/null +++ b/codegen/crm/types/index.php @@ -0,0 +1,29 @@ +load("http_structs.tpl"); + $tpl->assign($common); + $tpl->assign("package", basename(__DIR__)); + $tpl->assign("name", $name); + $tpl->assign("api", $api); + $tpl->assign("self", strtolower(substr($name, 0, 1))); + $tpl->assign("structs", $api['struct']); + $imports = array(); + foreach ($api['struct'] as $struct) { + if (isset($struct['imports'])) + foreach ($struct['imports'] as $import) { + $imports[] = $import; + } + } + $tpl->assign("imports", $imports); + $tpl->assign("calls", $api['apis']); + $contents = str_replace("\n\n}", "\n}", $tpl->get()); + + file_put_contents($filename, $contents); + echo $filename . "\n"; + } +} diff --git a/codegen/sam b/codegen/sam new file mode 120000 index 000000000..b6e47f999 --- /dev/null +++ b/codegen/sam @@ -0,0 +1 @@ +crm \ No newline at end of file diff --git a/codegen/templates/http_.tpl b/codegen/templates/http_.tpl index ab4bc069f..431dbb0c6 100644 --- a/codegen/templates/http_.tpl +++ b/codegen/templates/http_.tpl @@ -6,6 +6,12 @@ import ( var _ = errors.Wrap +type {name} struct {} + +func ({name}) New() *{name} { + return &{name}{ldelim}{rdelim} +} + {foreach $calls as $call} func (*{name}) {call.name|capitalize}(r *{name|lcfirst}{call.name|capitalize}Request) (interface{}, error) { return nil, errors.New("Not implemented: {name}.{call.name}") diff --git a/codegen/templates/http_handlers.tpl b/codegen/templates/http_handlers.tpl index 4cb5d854d..34e0ed627 100644 --- a/codegen/templates/http_handlers.tpl +++ b/codegen/templates/http_handlers.tpl @@ -10,7 +10,7 @@ import ( {foreach $calls as $call} func ({self}h *{name}Handlers) {call.name|capitalize}(w http.ResponseWriter, r *http.Request) { - params := {name|lcfirst}{call.name|capitalize}Request{}.new() + params := {name|capitalize}{call.name|capitalize}Request{}.new() resputil.JSON(w, params.Fill(r), func() (interface{}, error) { return {self}h.{name}.{call.name|capitalize}(params) }) } {/foreach} diff --git a/codegen/templates/http_interfaces.tpl b/codegen/templates/http_interfaces.tpl index dd0fd91a5..5c24138cd 100644 --- a/codegen/templates/http_interfaces.tpl +++ b/codegen/templates/http_interfaces.tpl @@ -8,20 +8,17 @@ import ( // HTTP handlers are a superset of internal APIs type {name}Handlers struct { - *{name} -} - -func ({name}Handlers) new() *{name}Handlers { - return &{name}Handlers{ - {name}{}.New(), - } + {name} {name}API } // Internal API interface type {name}API interface { {foreach $calls as $call} - {call.name|capitalize}(*{name|lcfirst}{call.name|capitalize}Request) (interface{}, error) + {call.name|capitalize}(*{name|expose}{call.name|capitalize}Request) (interface{}, error) {/foreach} + + // Authenticate API requests + Authenticator() func(http.Handler) http.Handler } // HTTP API interface @@ -29,11 +26,4 @@ type {name}HandlersAPI interface { {foreach $calls as $call} {call.name|capitalize}(http.ResponseWriter, *http.Request) {/foreach} - - // Authenticate API requests - Authenticator() func(http.Handler) http.Handler } - -// Compile time check to see if we implement the interfaces -var _ {name}HandlersAPI = &{name}Handlers{} -var _ {name}API = &{name}{} \ No newline at end of file diff --git a/codegen/templates/http_request.tpl b/codegen/templates/http_request.tpl index e0a30ebee..0ef30b8b0 100644 --- a/codegen/templates/http_request.tpl +++ b/codegen/templates/http_request.tpl @@ -11,19 +11,19 @@ var _ = chi.URLParam {foreach $calls as $call} // {name} {call.name} request parameters -type {name|lcfirst}{call.name|capitalize}Request struct { +type {name|expose}{call.name|capitalize}Request struct { {foreach $call.parameters as $params} {foreach $params as $method => $param} - {param.name} {param.type}{newline} + {param.name|expose} {param.type}{newline} {/foreach} {/foreach} } -func ({name|lcfirst}{call.name|capitalize}Request) new() *{name|lcfirst}{call.name|capitalize}Request { - return &{name|lcfirst}{call.name|capitalize}Request{} +func ({name|expose}{call.name|capitalize}Request) new() *{name|expose}{call.name|capitalize}Request { + return &{name|expose}{call.name|capitalize}Request{} } -func ({self} *{name|lcfirst}{call.name|capitalize}Request) Fill(r *http.Request) error { +func ({self} *{name|expose}{call.name|capitalize}Request) Fill(r *http.Request) error { r.ParseForm() get := map[string]string{} post := map[string]string{} @@ -38,14 +38,14 @@ func ({self} *{name|lcfirst}{call.name|capitalize}Request) Fill(r *http.Request) {foreach $call.parameters as $method => $params} {foreach $params as $param} {if strtolower($method) === "path"} - {self}.{param.name} = {if ($param.type !== "string")}{$parsers[$param.type]}({/if}chi.URLParam(r, "{param.name}"){if ($param.type !== "string")}){/if}{newline} + {self}.{param.name|expose} = {if ($param.type !== "string")}{$parsers[$param.type]}({/if}chi.URLParam(r, "{param.name}"){if ($param.type !== "string")}){/if}{newline} {elseif substr($param.type, 0, 2) !== '[]'} - {self}.{param.name} = {if ($param.type !== "string")}{$parsers[$param.type]}({method|strtolower}["{param.name}"]){else}{method|strtolower}["{param.name}"]{/if}{newline} + {self}.{param.name|expose} = {if ($param.type !== "string")}{$parsers[$param.type]}({method|strtolower}["{param.name}"]){else}{method|strtolower}["{param.name}"]{/if}{newline} {/if} {/foreach} {/foreach} return nil } -var _ RequestFiller = {name|lcfirst}{call.name|capitalize}Request{}.new() +var _ RequestFiller = {name|expose}{call.name|capitalize}Request{}.new() {/foreach} diff --git a/codegen/templates/http_routes.tpl b/codegen/templates/http_routes.tpl index de3447ae6..d2599a41a 100644 --- a/codegen/templates/http_routes.tpl +++ b/codegen/templates/http_routes.tpl @@ -7,15 +7,17 @@ import ( "runtime" "reflect" "github.com/go-chi/chi" + + "github.com/crusttech/crust/{package}/rest" ) func MountRoutes(r chi.Router) { {foreach $apis as $api} - {api.interface|strtolower} := {api.interface|capitalize}Handlers{}.new() + {api.interface|strtolower} := &rest.{api.interface|capitalize}Handlers{{api.interface|capitalize}{ldelim}{rdelim}.New()} {/foreach} {foreach $apis as $api} r.Group(func (r chi.Router) { - r.Use({api.interface|strtolower}.Authenticator()) + r.Use({api.interface|strtolower}.{api.interface}.Authenticator()) r.Route("{api.path}", func(r chi.Router) { {foreach $api.apis as $call} r.{eval echo capitalize(strtolower($call.method))}("{call.path}", {api.interface|strtolower}.{call.name|capitalize}) diff --git a/codegen/vendor/autoload.php b/codegen/vendor/autoload.php new file mode 100644 index 000000000..7787228a5 --- /dev/null +++ b/codegen/vendor/autoload.php @@ -0,0 +1,7 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + + private $classMapAuthoritative = false; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731 + if ('\\' == $class[0]) { + $class = substr($class, 1); + } + + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative) { + return false; + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if ($file === null && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if ($file === null) { + // Remember that this class does not exist. + return $this->classMap[$class] = false; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) { + if (0 === strpos($class, $prefix)) { + foreach ($this->prefixDirsPsr4[$prefix] as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/codegen/vendor/composer/LICENSE b/codegen/vendor/composer/LICENSE new file mode 100644 index 000000000..1a2812488 --- /dev/null +++ b/codegen/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) 2016 Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/codegen/vendor/composer/autoload_classmap.php b/codegen/vendor/composer/autoload_classmap.php new file mode 100644 index 000000000..7a91153b0 --- /dev/null +++ b/codegen/vendor/composer/autoload_classmap.php @@ -0,0 +1,9 @@ + array($vendorDir . '/monotek/minitpl/code'), +); diff --git a/codegen/vendor/composer/autoload_psr4.php b/codegen/vendor/composer/autoload_psr4.php new file mode 100644 index 000000000..b265c64a2 --- /dev/null +++ b/codegen/vendor/composer/autoload_psr4.php @@ -0,0 +1,9 @@ += 50600 && !defined('HHVM_VERSION'); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInita6e366c180070d1defcfe90f77724cd9::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + return $loader; + } +} diff --git a/codegen/vendor/composer/autoload_static.php b/codegen/vendor/composer/autoload_static.php new file mode 100644 index 000000000..55982c4a6 --- /dev/null +++ b/codegen/vendor/composer/autoload_static.php @@ -0,0 +1,26 @@ + + array ( + 'Monotek\\MiniTPL' => + array ( + 0 => __DIR__ . '/..' . '/monotek/minitpl/code', + ), + ), + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixesPsr0 = ComposerStaticInita6e366c180070d1defcfe90f77724cd9::$prefixesPsr0; + + }, null, ClassLoader::class); + } +} diff --git a/codegen/vendor/composer/installed.json b/codegen/vendor/composer/installed.json new file mode 100644 index 000000000..704eaf5a2 --- /dev/null +++ b/codegen/vendor/composer/installed.json @@ -0,0 +1,52 @@ +[ + { + "name": "monotek/minitpl", + "version": "v1.1.4", + "version_normalized": "1.1.4.0", + "source": { + "type": "git", + "url": "https://github.com/titpetric/minitpl.git", + "reference": "613a596b3dee3c121283fad3f84d06d83ecb5125" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/titpetric/minitpl/zipball/613a596b3dee3c121283fad3f84d06d83ecb5125", + "reference": "613a596b3dee3c121283fad3f84d06d83ecb5125", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2016-02-07 13:23:38", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "Monotek\\MiniTPL": "code" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "CC BY-SA 3.0" + ], + "authors": [ + { + "name": "Tit Petric", + "email": "tit.petric@monotek.net", + "homepage": "http://titpetric.github.io", + "role": "developer" + } + ], + "description": "Miniature fully featured PHP template engine", + "homepage": "https://github.com/titpetric/minitpl", + "keywords": [ + "minitpl", + "monotek", + "php", + "small", + "smarty", + "template", + "tiny" + ] + } +] diff --git a/codegen/vendor/monotek/minitpl/.gitignore b/codegen/vendor/monotek/minitpl/.gitignore new file mode 100644 index 000000000..2dd5d1617 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/.gitignore @@ -0,0 +1,2 @@ +test/compile +vendor diff --git a/codegen/vendor/monotek/minitpl/.gitmodules b/codegen/vendor/monotek/minitpl/.gitmodules new file mode 100644 index 000000000..166a06f5a --- /dev/null +++ b/codegen/vendor/monotek/minitpl/.gitmodules @@ -0,0 +1,3 @@ +[submodule "git_hooks"] + path = git_hooks + url = git@github.com:titpetric/git_hooks.git diff --git a/codegen/vendor/monotek/minitpl/README.markdown b/codegen/vendor/monotek/minitpl/README.markdown new file mode 100644 index 000000000..97645c8b6 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/README.markdown @@ -0,0 +1,37 @@ +# MiniTPL + +The goal of the MiniTPL template engine is to provide a miniature +framework which allows you to rapidly create and consume +Smarty-like templates without adding the overhead of Smarty to +your choice of a PHP framework. + +In benchmarks the speed of Mini TPL is very close to PHP itself. +All that is usually needed for Mini TPL is a 3KB PHP code overhead. +So it beats Smarty, and usual PHP vsprintf and str_replace functionality. + +With a total size of about 13KB and the functionality contained, this is +one of the smallest full featured template engines for PHP to date. + +MiniTPL is available on [packagist as monotek/minitpl](https://packagist.org/packages/monotek/minitpl). + +To start using MiniTPL in your project with [composer](http://getcomposer.org/), create a composer.json file: +``` +{ + "require": { + "monotek/minitpl": ">=1.0" + } +} +``` + +And run `composer install`. You can start using MiniTPL right away + +``` +load("test.tpl"); +$tpl->render(); +``` \ No newline at end of file diff --git a/codegen/vendor/monotek/minitpl/code/Monotek/MiniTPL/Compiler.php b/codegen/vendor/monotek/minitpl/code/Monotek/MiniTPL/Compiler.php new file mode 100644 index 000000000..c87c67139 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/code/Monotek/MiniTPL/Compiler.php @@ -0,0 +1,345 @@ +_tag_php_open = "<"."?php"; + $this->_tag_php_close = "?".">\n"; + $this->_global_variables = array(); + $this->_literals = array(); + } + + protected function load_contents($filename) + { + if (($contents = file_get_contents($filename)) !== false) { + if (substr($contents, 0, 3) == "\xEF\xBB\xBF") { + return substr($contents, 3); + } + } + return $contents; + } + + /** Compile template file into php code */ + function compile($filename, $output_filename, $find_path, $nocache) + { + $contents = $this->load_contents($filename); + $r = 0; + if ($contents!==false && $contents!=="") { + while (preg_match_all("/\{include\ (.*?)\}/s", $contents, $matches)) { + $matches = array_unique($matches[1]); + foreach ($matches as $file) { + $cn = ""; + if (($fn = call_user_func($find_path, $file))!==false) { + $cn = $this->load_contents($fn.$file); + } + $contents = str_replace("{include ".$file."}", $cn, $contents); + } + } + while (preg_match_all("/\{load\ (.*?)\}/s", $contents, $matches)) { + $matches = array_unique($matches[1]); + foreach ($matches as $file) { + $file_var = (substr($file,0,1) == '$') ? $this->_split_exp($file) : '"'.$file.'"'; + $cn = $this->_code('$this->push();$this->load('.$file_var.');$this->assign($_v);$this->render();$this->pop();'); + $contents = str_replace("{load ".$file."}", $cn, $contents); + } + } + $nocache = $nocache ? $this->_code("@unlink(__FILE__);") : ""; + $contents = str_replace("{*nocache*}",$nocache,$contents); + $contents = $this->_strip_comments($contents); + $contents = $this->_parse_constants($contents); + $contents = $this->_parse_functions($contents, $filename); + $contents = $this->_parse_expressions($contents); + $contents = $this->_parse_variables($contents); + if (!empty($this->_global_variables)) { + $globals = array_unique($this->_global_variables); + $contents = $this->_code('global '.implode(", ",$globals).';').$contents; + } + $contents = $this->_template_cleanup($contents); + $this->_r_mkdir(dirname($output_filename)); + if ($f = @fopen($output_filename,"w")) { + fwrite($f, $contents); + fclose($f); + $r = 1; + } + } + return $r; + } + + function _r_mkdir($dir) + { + if (file_exists($dir)) return; + if (!file_exists(dirname($dir))) $this->_r_mkdir(dirname($dir)); + @mkdir($dir); + } + + /** Insert system configuration, clean up code */ + function _template_cleanup($contents) + { + // set up variables + $contents = $this->_code('$_v=&$this->vars;') . $contents; + // strip unnecessary php tags + $contents = str_replace($this->_tag_php_close.$this->_tag_php_open, "", $contents); + // strip new line whitespace between php code + $contents = str_replace($this->_tag_php_close."\n".$this->_tag_php_open.' ', "", $contents); + $contents = str_replace("echo ;", "", $contents); + foreach ($this->_literals as $key=>$value) { + $contents = str_replace("[[".$key."]]", $value, $contents); + } + return $contents; + } + + /** Strip template style comments */ + function _strip_comments($contents) + { + $contents = preg_replace("/\{\*.+\*\}/sU", "", $contents); + return $contents; + } + + /** Replace constant definitions */ + function _parse_constants($contents) + { + $matches = array(); + if (preg_match_all("/\{(\_[a-zA-Z0-9\_]+)\}/", $contents, $matches)) { + $matches = array_unique($matches[1]); + foreach ($matches as $m) { + $contents = str_replace("{".$m."}", $this->_code("echo ".$m.";"), $contents); + } + } + return $contents; + } + + /** Search and replace for function blocks and inline definitions */ + function _parse_functions($contents, $filename) + { + $inlines = $blocks = array(); + + if (preg_match_all("/\{(block|inline)\ ([a-zA-Z0-9\_\-]+)\}(.*?)\{\/\\1\}/s", $contents, $matches)) { + foreach ($matches[0] as $k=>$ma) { + $m = array("content"=>trim($matches[3][$k]), "src"=>$ma); + if ($matches[1][$k]=="block") { + $blocks[$matches[2][$k]] = $m; + } else { + $inlines[$matches[2][$k]] = $m; + } + } + } + + if (preg_match_all("/\]+)\>(.*?)\<\/script\>/s", $contents, $matches)) { + foreach ($matches[0] as $k=>$parameters) { + if (strpos($parameters,"text/template")!==false || strpos($parameters,"text/x-jquery")!==false) { + $key = count($this->_literals)."_literal"; + $this->_literals[$key] = $matches[2][$k]; + $contents = str_replace($matches[2][$k], "[[".$key."]]", $contents); + } + } + } + + foreach ($blocks as $name=>$code) { + $lambda = sprintf("%u", crc32($code['content']))."_".sprintf("%u", crc32($filename)); + $block_code = "if (!function_exists('".$name."_".$lambda."')) { function ".$name."_".$lambda."(\$_v) {".$this->_tag_php_close.$code['content'].$this->_tag_php_open." } }"; + $contents = str_replace($code['src'], $this->_code($block_code), $contents); + } + + foreach ($inlines as $name=>$code) { + $contents = str_replace($code['src'], '', $contents); + } + + $matches = array(); + while (preg_match_all("/\{inline\:([a-zA-Z0-9\_\-]+)\}/s", $contents, $matches)) { + foreach ($matches[0] as $k=>$ma) { + $contents = str_replace($ma, $inlines[$matches[1][$k]]['content'], $contents); + } + } + + foreach ($blocks as $name=>$code) { + $contents = str_replace("{block:".$name."}", $this->_code($name."_".$lambda."(&\$_v);"), $contents); + } + return $contents; + } + + /** Parse expression syntax: if, elseif, foreach, else, for, eval, eval_literal */ + function _parse_expressions($contents) + { + // foreach parsing + if (preg_match_all("/\{foreach (.+)\}/sU", $contents, $matches)) { + foreach ($matches[1] as $k=>$exp) { + $exp = trim(trim($exp,"()")); + list($e_left, $e_right) = explode(" as ", $exp); + $e_right = explode("=>", $e_right); + + $left_exp = $this->_split_exp($e_left); + $code = ""; + if (substr($left_exp, 0, 5) !== "array") { + $code = "if(!empty(".$left_exp."))"; + } + $code .= "foreach(".$left_exp." as ".$this->_split_exp($e_right[0]); + if (count($e_right)==2) { + $code .= '=>'.$this->_split_exp($e_right[1]); + } + $code .= '){'; + $contents = str_replace($matches[0][$k], trim($this->_code($code)), $contents); + } + } + // if & for & elseif parsing + if (preg_match_all("/\{(if|elseif|for|while) (.+)\}/sU", $contents, $matches)) { + foreach ($matches[1] as $k=>$v) { + if ($v=="for") { + $matches[2][$k] = trim($matches[2][$k],"()"); + } + $code = $v."(".$this->_split_exp($matches[2][$k])."){"; + if ($v=="elseif") { + $code = "}".$code; + } + $contents = str_replace($matches[0][$k], $this->_code($code), $contents); + } + } + // eval & eval_literal parsing + if (preg_match_all("/\{(eval|eval_literal) (.+)\}/sU", $contents, $matches)) { + foreach ($matches[1] as $k=>$type) { + $code = rtrim(trim($matches[2][$k]),';'); + if ($type=="eval") { + $code = $this->_split_exp($code); + } + $code .= ";"; + $contents = str_replace($matches[0][$k], $this->_code($code), $contents); + } + } + $contents = str_replace("{else}", $this->_code("}else{"), $contents); + $contents = str_replace(array("{/foreach}","{/while}","{/for}","{/if}"), trim($this->_code("}")), $contents); + return $contents; + } + + /** Parse variables */ + function _parse_variables($contents) + { + $mycontent = preg_replace("/\<\?php.+\?\>/sU","",$contents); + // [a-zA-Z\_\$\"\'\[\]\ ] + if (preg_match_all("/\{([^\{]+)\}/sU", $mycontent, $matches)) { + foreach ($matches[1] as $k=>$v) { + if (strstr($v,"\n")===false && $v{0}!=" ") { + if ($v{0}!='$' && !in_array($v{0}, array("'",'"'))) { + // shorthand variables {v} + $v = '$'.$v; + } + $code = ""; + if (strstr($v,"|")!==false) { + list($left,$right) = explode("|",$v); + $left = $this->_split_exp($left); + switch ($right) { + case "toupper": $right = "strtoupper"; break; + case "tolower": $right = "strtolower"; break; + case "escape": $code = "echo htmlspecialchars(".$left.", ENT_QUOTES);"; break; + } + if ($code=='') { + $code = "echo ".$right."(".$left.");"; + } + } else { + $code = "echo ".$this->_split_exp($v).";"; + } + $contents = str_replace($matches[0][$k], $this->_code($code), $contents); + } + } + } + return $contents; + } + + /** Split up variables from a php expression and replace them with actual variable locations */ + function _split_exp($exp) + { + $code = str_replace(".","__1","<"."?php if (".$exp.") { ?".">"); + $tokens = token_get_all($code); + $objects = array(); + $variable = false; + $variables = array(); + $variable_continues = false; + foreach ($tokens as $k=>$v) { + if (is_array($v)) { + if ($v[0] == T_OBJECT_OPERATOR) { + $variable_continues = false; + $objects[] = $variable; + } + if ($v[0] == T_VARIABLE) { + if (!$variable_continues && isset($variable) && !in_array($variable,$objects)) { + $variables[] = $variable; + } + $variable = $variable_continues ? $variable.$v[1] : $v[1]; + if (strstr($variable,"__1")!==false) { + $variable = str_replace("__1",".",$variable); + $variable_continues = false; + if (substr($variable,-1)==".") { + $variable_continues = true; + } + } else if ($variable_continues) { + $variable_continues = false; + } + } + $v[0] = token_name($v[0]); + $tokens[$k] = $v; + } + } + if (isset($variable) && !in_array($variable,$variables) && !in_array($variable,$objects)) { + $variables[] = $variable; + } + // globalize objects + foreach ($objects as $object) { + if ($object!='$this' && is_object($GLOBALS[substr($object,1)])) { + $this->_global_variables[] = $object; + } else { + $variables[] = $object; + } + } + + // closure to sort vars by length and alphabetically + usort($variables, function($a, $b) { + if (strlen($a)==strlen($b)) { + if ($a==$b) { + return 0; + } + return ($a<$b) ? 1 : -1; + } + return (strlen($a)_get_var($var), $exp); + } + } + return $exp; + } + + /** Helper function for replacing tags into actual variable locations */ + function _get_var($var) { + $left_modifier = substr($var,1); // remove $ + $retval = $var; + if ($var{0}!='"' && $var{0}!="'") { + $retval = '$_v'; + if (strstr($left_modifier,'.')!==false) { + // we have ourselves a table index + $table_indices = explode('.',$left_modifier); + foreach ($table_indices as $v) { + $retval .= (($v{0}=='$') ? "[".$this->_get_var($v)."]" : "['".$v."']"); + } + } else { + $retval .= (($left_modifier{0}=='$') ? "[".$this->_get_var($left_modifier)."]" : "['".$left_modifier."']"); + } + } + return $retval; + } + + /** Helper function for php code shorthand syntax, optimizing compiler size */ + function _code($s) { + return $this->_tag_php_open." ".$s.$this->_tag_php_close; + } +} diff --git a/codegen/vendor/monotek/minitpl/code/Monotek/MiniTPL/Template.php b/codegen/vendor/monotek/minitpl/code/Monotek/MiniTPL/Template.php new file mode 100644 index 000000000..bc49f95cb --- /dev/null +++ b/codegen/vendor/monotek/minitpl/code/Monotek/MiniTPL/Template.php @@ -0,0 +1,182 @@ +set_compile_location("cache/", false); + $this->set_paths($paths); + $this->_defaults = array(array("ldelim","{"), array("rdelim","}")); + $this->_nocache = false; + } + + function add_default($k,$v='') + { + $this->_defaults[] = array($k,$v); + } + + function _default_vars() + { + if (empty($this->stack)) { + $this->vars = array(); + } + $this->filename = false; + foreach ($this->_defaults as $v) { + $this->assign($v[0],$v[1]); + } + } + + function push() + { + $this->stack[] = $this->filename; + } + + function pop() + { + list($this->filename) = array_splice($this->stack, -1); + } + + /** Template loader */ + function load($filename) + { + $r = 0; + $this->_default_vars(); + if (($path = $this->_find_path($filename))!==false) { + $f_original = $path.$filename; + $f_compiled = $this->_compile_path($path).$filename; + if (file_exists($f_compiled)) { + $r = 1; + if (file_exists($f_original) && (filemtime($f_original) > filemtime($f_compiled))) { + $r = $this->compile($f_original, $f_compiled); + } + } else { + $r = $this->compile($f_original, $f_compiled); + } + $this->filename = $f_compiled; + if (!$r) { + throw new \Exception(sprintf(self::E_TEMPLATE_COMPILE, $filename)); + } + } + $this->source = $filename; + return (bool)$r; + } + + /** Compile template */ + function compile($s,$d) + { + $c = new Compiler; + return $c->compile($s,$d,array(&$this,"_find_path"),$this->_nocache); + } + + /** Sets searchable template paths */ + function set_paths($paths=false) { + if ($paths===false) { + $paths = array("templates/"); + } + if (is_string($paths)) { + $paths = func_get_args(); + } + $this->_paths = $paths; + } + + /** Sets compile location */ + function set_compile_location($path, $is_absolute) + { + $this->_compile_location = rtrim($path,"/")."/"; + $this->_compile_absolute = $is_absolute; + } + + /** Compile path calculation */ + function _compile_path($path) + { + if ($this->_compile_absolute) { + return $this->_compile_location.$path; + } + return $path.$this->_compile_location; + } + + /** Finds first path with existing template file */ + function _find_path($filename) { + foreach ($this->_paths as $path) { + // even if only compiled template exists, it's ok + if (file_exists($path.$filename) || file_exists($this->_compile_path($path).$filename)) { + return $path; + } + } + return false; + } + + /** Assign data to the template */ + function assign($key,$value='') + { + if (is_array($key)) { + // $key is an array, use $value as prefix if set + if ($value != '') { + $value .= '_'; + } + foreach ($key as $k=>$v) { + $this->vars[$value.$k] = $v; + } + } else { + // $key is a string, do stuff depending on value and prefix + $concat = ($key{0}=='.'); + if ($concat) { + $key = substr($key,1); + } + $this->vars[$key] = ($concat ? (is_array($value) ? array_merge($this->vars[$key],$value) : $this->vars[$key].$value) : $value); + } + return ""; // {$this->assign} calls, ouch + } + + /** Get variable */ + function getVar($key) + { + return isset($this->vars[$key]) ? $this->vars[$key] : false; + } + + /** Render the template to standard output */ + function render() + { + if ($this->filename === false) { + throw new \Exception(sprintf(self::E_FILENAME_EMPTY, $this->source)); + } + include($this->filename); + } + + /** Render the template and return text */ + function get() + { + ob_start(); + $this->render(); + $s = ob_get_contents(); + ob_end_clean(); + return $s; + } +} diff --git a/codegen/vendor/monotek/minitpl/composer.json b/codegen/vendor/monotek/minitpl/composer.json new file mode 100644 index 000000000..b520863d4 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/composer.json @@ -0,0 +1,34 @@ +{ + + "name": "monotek/minitpl", + + "description": "Miniature fully featured PHP template engine", + + "keywords": ["monotek", "minitpl", "template", "php", "tiny", "small", "smarty"], + + "homepage": "https://github.com/titpetric/minitpl", + + "authors": [ + { + "name": "Tit Petric", + "email": "tit.petric@monotek.net", + "homepage": "http://titpetric.github.io", + "role": "developer" + } + ], + + "license": "CC BY-SA 3.0", + + "type": "library", + + "require": { + "php": ">=5.3.0" + }, + + "autoload": { + "psr-0": { + "Monotek\\MiniTPL": "code" + } + } + +} diff --git a/codegen/vendor/monotek/minitpl/documentation/documentation_en.markdown b/codegen/vendor/monotek/minitpl/documentation/documentation_en.markdown new file mode 100644 index 000000000..ab2815271 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/documentation/documentation_en.markdown @@ -0,0 +1,783 @@ +Monotek Mini Template +===================== + +Last update - Tue 18 Dec 2012 11:24:08 AM CET + +by Tit Petrič ( tit.petric@monotek.net ) / Monotek d.o.o. + + +Introduction +------------ + +This is a production stable version of our internal templating +system, which supports template compilation, and is PHP4 and +PHP5 compatible. It uses some very advanced PHP functionality, +to keep down the size of the code and at the same time still +provide exceptional functionality. + +The total code is 13.5KB and is propperly indented, contains +minimal commenting and perfectly readable with all white space +left in tact. + +The code falls under the [Creative Commons Attribution - +Share Alike](http://creativecommons.org/licenses/by-sa/3.0/) license. + +Installation and Requirement +---------------------------- + +Monotek Mini Template requires PHP version 4.3.0 or later. + +It can work with lower php versions also, if you provide +your own [file_get_contents()](http://php.net/file_get_contents) function. + +Depending on the folder location where you use the template object, +it will need the following folders: + +> templates/
+> templates/cache/ * + +Since this templating system is a compiling template system, +you will need a writable cache directory. + + +Language reference +------------------ + +Since syntax for the template system is loosely based on Smarty +and PHP language syntax, knowing some PHP basics while using this +template system will help you a long way. + +1. Language constructs +2. Loops +3. Conditions +4. Block and Inline definitions +5. Advanced, embedding php code +6. PHP usage reference + +---------------------------------------------------------- + +

1. Language constructs Δ Jump to top

+ +Theese basic language constructs provide you with some insight +into the workings of the template system, so you can start to +create your own templates. + +Let me just start by saying, all language constructs are +defined between curly brace tokens (`{` and `}`). In case +the template engine doesn't recognise the token, it leaves +it as-is, with curly braces in tact. This should make the +template engine javascript/json safe, no escaping is required. + +#### 1.1. Variables + +Using variables from templates is easy. Variables are enclosed +in curly braces like so: `{variable}`. Since variables are parsed +on the last stage, prefixing variables with the dollar sign is +optional. So, `{$variable}` is the same as `{variable}`. + +~~~~~~~~~~~~~ +{variable} is the same as {$variable} +~~~~~~~~~~~~~ + +#### 1.2. Arrays + +There is a shorthand syntax for using arrays inside a template. +The array index separator is a dot (`.`). Consecutive dots can be +used for traversing into array depth like `{$array.items.0}`, or +even variables starting with `$`, like `{$sections.$news_section.title}`. +PHP syntax for arrays is also supported. + +~~~~~~~~~~~~ +{$array.items} is the same as {$array['items']} +{$array.items.0} is the same as {$array['items'][0]} +{$array.$items.0} is the same as {$array[$items][0]} +~~~~~~~~~~~~ + +#### 1.3. Modifiers + +Modifiers are PHP functions, which take one arbitrary value +(usually, string), and return a string, which gets shown. +Some functions in PHP can be used as modifiers +(strtoupper, ucfirst, str_rot13, strrev, count, ...). + +~~~~~~~~~~~~~~~~~~~~~~~~ +/** Custom modifier example */ + +function add_it_up($array) +{ + $size = 0; + foreach ($array as $value) { + $size += $value['size']; + } + return $size; +} +~~~~~~~~~~~~~~~~~~~~~~~~ + +To use the above function in a template, just do `{$variable|add_it_up}`, +which will loop trough all `$variable` items and add up the value of +the size element and return the total sum of all sizes. + +You can't pass additional parameters to modifiers. If you need to +do that, then take a look at advanced templating, +which will show you a way to embed php code inside a template. + +The modifier `escape` is a special template modifier, which +gets replaced by a `htmlspecialchars($left, ENT_QUOTES);` call. +It is used for escaping data, that might contain quotes or `<`, `>`. +Here are a few examples of the correct use of the escape modifier. + +~~~~~~~~~~~~~~~ + + +Read more ... +

{site.title|escape}

+~~~~~~~~~~~~~~~ + +Aditional template modifiers are `toupper` for `strtoupper` and +`tolower` for `strtolower`. No additional functions are created +for theese special modifiers. + +~~~~~~~~~~~~~~ +{variable|escape} +{variable|toupper} +{variable|add_id_up} +~~~~~~~~~~~~~~ + +The above code gets compiled to: + +~~~~~~~~~~~~~~ +vars; + echo htmlspecialchars($_v['variable'], ENT_QUOTES); + echo strtoupper($_v['variable']); + echo add_id_up($_v['variable']); +?> +~~~~~~~~~~~~~~ + +A common use for modifiers is outputting data for javascript, +using the php function `json_encode`. + +#### 1.4. Objects + +You can also call object methods as modifiers, from global or +local objects. The compiler will determine at run-time, if +you have a global object by the name, and modify the code +accordingly. + +~~~~~~~~~~~ +{$variable|$memcache->get} +~~~~~~~~~~~ + +If the global object doesn't exist, it assumes a local object. + +~~~~~~~~~~~ +vars; + echo $_v['memcache']->get($_v['variable']); +?> +~~~~~~~~~~~ + +However, if a global object by the name $memcache exists at +compile time: + +~~~~~~~~~~ +vars; + global $memcache; + echo $memcache->get($_v['variable']); +?> +~~~~~~~~~~ + +You can also use variables from objects, in the same way. + +~~~~~~~~~~~~ +{$memcache->variable} +~~~~~~~~~~~~ + +Compiles to one of theese: + +~~~~~~~~~~ +vars; + echo $_v['memcache']->variable; +?> +~~~~~~~~~~ + +~~~~~~~~~~ +vars; + global $memcache; + echo $memcache->variable; +?> +~~~~~~~~~~ + +#### 1.5. Constants + +Value starting with `_` is assumed to be a constant. The template +system will output the value of the constant if defined, +or just the name of the constant. Item `{_MY_CONSTANT}` will be +used as a constant, because of those rules, however `{$_my_variable}` +wouldnt be, since it starts with the variable identifier `$`. + +~~~~~~~~~~~ +{_MY_CONSTANT} +{_this_is_also_a_constant} +{$_my_variable} +~~~~~~~~~~~ + +The above code gets compiled to: + +~~~~~~~~~~~ +vars; + echo _MY_CONSTANT; + echo _this_is_also_a_constant; + echo $_v['_my_variable']; +?> +~~~~~~~~~~~ + +#### 1.6. Includes + +The statement `{include filename.tpl}` gets replaced with the content +of the specified template, before it does any processing. In case +you change the filename.tpl template, you have to regenerate the +cache of the main template manually (by deleting the cache it or +updating the source template, so the timestamp is modified). + +There is no limit to the number of files you can include. + +~~~~~~~~~~~ + + + {$title} + + +{include site_header.tpl} +{$contents} +{include site_footer.tpl} + + +~~~~~~~~~~~ + +If you need to include template files dynamically, you can use `{load}` to +do this. This will solve some caching problems and enable you to use templates +based on what you pass to the main template as variables via `assign`. + +Keep in mind that with this you can't use the `inline` and `block` definitions +outside the loaded template, but with `include` you can. + +~~~~~~~~~~~ + + + {$title} + + +{load $dynamic_header} +{load $dynamic_contents_template} +{load $dynamic_footer} + + +~~~~~~~~~~~ + + +#### 1.7. Comments + +Comments are enclosed between `{*` and `*}`. Comments are stripped +at compile time, and don't show up in the compiled code or in +the template engine output. This is useful for extensive documentation +if needed, since it doesn't give any overhead at run-time. + +~~~~~~~~~~~ +{* This is a comment that won't be shown anywhere, + except in the source template, only to developers. *} + +Hello world! +~~~~~~~~~~~ + +The above compiles to: + +`Hello world!` + +

2. Loops Δ Jump to top

+ +#### for, foreach, foreach / else, while + +Since the main goal when doing pseudo code here is to make it +friendly for the developer, syntax is PHP inspired. While +this isn't ideal for web designers that make templates, it +is ideal for the majority of the PHP developers, since they +don't need to learn a new language for templating. + +~~~~~~~~~~~~ + +{for $i=0; $i +{/for} +{foreach $array as $value} + I like values like I like: {value}
+{/foreach} +{foreach $array as $key=>$value} + I like my value {value} to have a key {key}.
+{/foreach} +{foreach $array as $key=>$value} + I like my value {value} to have a key {key}.
+{else} + I'm sorry, I have nothing in the array.
+{/foreach} +{while ($k++ < 10)} + Well, k is {k}
+{/while} + +~~~~~~~~~~~~ + +You see, this is very friendly for a PHP developer. Lets compare +it to the original PHP code (two ways): + +~~~~~~~~~~~~ +echo ''; +for ($i=0; $i'; +} +foreach ($array as $value) { + echo 'I like values like I like: '.$value.'
'; +} +foreach ($array as $key=>$value) { + echo 'I like my value '.$value.' to have a key '.$key.'.
'; +} +if (!empty($array)) { + foreach ($array as $key=>$value) { + echo 'I like my value '.$value.' to have a key '.$key.'.
'; + } +} else { + echo "I'm sorry, I have nothing in the array.
"; +} +while ($k++ < 10) { + echo "Well, k is ".$k."
"; +} +echo ''; +~~~~~~~~~~~~ + +While this example illustrates the similarity in syntax, +it also shows how writing templates is actually less time +consuming and more readable in the long run. + +If you notice, the statements all support full PHP syntax. + +While not very obvious with `foreach`, you can see that +the code is practically identical for other statements, +where you can mix the complete PHP syntax along with +template features like the table addressing shorthand. + +~~~~~~~~~~~~~~~~~~~ +

{foreach $items.news as $newsitem}-{/foreach}

+

{foreach $items['news'] as $newsitem}+{/foreach}

+

{for $i=0; $i!{/for}

+

{for $i=0; $i?{/for}

+~~~~~~~~~~~~~~~~~~~ + + +

3. Conditions Δ Jump to top

+ +The syntax for the `if` and `elseif` statements are +PHP compatible. You can call functions, methods, use +constants and arithmetic operations. Variables are parsed +with the templating extensions for using arrays, so both +syntaxes can be used at the same time. + +#### 3.1. if statement + +~~~~~~~~~~~~~ +{if $is.admin && $user['name']=="black"} + {* Hello black! Only you can edit things, + but only as long as you stay an admin. *} + ... +{/if} +~~~~~~~~~~~~~ + +#### 3.2. if/elseif/else statement + +~~~~~~~~~~~~~ +{if $is.admin && $user['name']=="black"} + {* Hello black! Only you can edit things, + but only as long as you stay an admin. *} + ... +{elseif $is_moderator} + {* Hello moderator! You can do some things. *} +{else} + {* You are a nobody and you earn nothing! *} +{/if} +~~~~~~~~~~~~~ + +#### 3.3. foreach/else statement + +~~~~~~~~~~~~~ +{foreach $newsitems.$section.items as $item} +
+

{item.title}

+
{item.content}
+
+{else} +
+ No newsitems exist in the chosen section. +
+{/if} +~~~~~~~~~~~~~ + +#### 3.4. nocache + +Minitpl template files are translated into PHP code to give you +the best possible execution speed. Using `include` statements +sometimes makes it hard to invalidate this cache, so for +development purposes we have included a `nocache` directive. +This erases your template cache after the file has been used once. + +~~~~~~~~~~~~ +{*nocache*} +~~~~~~~~~~~~ + +This behaviour needs to be activated by setting `$tpl->_nocache` to `true`. + +

4. Block and Inline definitions Δ Jump to top

+ +Depending on the usage, you might want to reuse pieces of +the template multiple times in the same or multiple templates. +You can achieve this by using Block and Inline definitions. +The difference between a block and inline definition is, +that the `block` definition defines a PHP function, and +can be used recursively in the template, for example, to +traverse a tree structure. The `inline` definition only +allows the same piece of template code to be reused multiple +times. + +#### 4.1 block definition and usage + +~~~~~~~~~~~ +{block recurse} +{if $i++ < 10} + call {i} + {block:recurse} +{/if} +{/block} + +{block:recurse} +~~~~~~~~~~~ + +The compiled template will look something like this: + +~~~~~~~~~~~ +vars; + function recurse_1213891842_673($_v) { + if ($_v['i']++ < 10) { + echo "call ".$_v['i']; + recurse_1213891842_673(&$_v); + } + } + recurse_1213891842_673(&$_v); +?> +~~~~~~~~~~~ + +As you can see, the block definition gets compiled into +a function definition, which lives in the same variable space. + +While traversing a tree this way isn't very practical, +it is however possible. You probablly won't ever need +this functionality. In our experience recursion itself +is very rare, and even if used, it is handled on the PHP +level, and not the templating level. + +You can use `block` definitions instead of `inline` definitions +if you are worried about code overhead. I would consider this + when an `inline` definition is multiple kilobytes in size and +is beeing used extensively in the same template. + +#### 4.2 inline definition and usage + +The inline keyword comes from `C++`, where the compiler +would replace the calls to an inline function definition +with the function itself. This is a speed gain for +`C++`, since calling a function many times is more +expensive, than copying the code around. The practical +reason for this inside a template goes along the same +train of thought. + +~~~~~~~~~~ +{inline newsitem} +
+

{news.title}

+
{news.content}
+
+{/inline} + +
+ {foreach $newsitems.top.items as $news}{inline:newsitem}{/foreach} +
+ +
+{foreach $newsitems.$section.items as $news}{inline:newsitem}{/foreach} +
+~~~~~~~~~~ + +Usage of `inline` definition decreases template size before +compilation, and helps with design standardisation. Same page +components can be literally re-used inside the template and +changing one aspect of the design is done in one place instead +of every place the same code snippet is used. + +

5. Advanced, embedding php code Δ Jump to top

+ +Since the above language constructs only take care of the +read only aspect of template programming, there is sometimes +also a need to modify variables inside templates for various +uses. The `eval` and `eval_literal` constructs take care +of that. The `php` construct is ment for more advanced +operations, and like `eval` lives in the template variable +space. + +#### 5.1 eval + +The eval construct allows quick operations on local +template variables. For example, if you want to build +a table with alternating css styles on rows, you would +do something like this: + +~~~~~~~~~~~~~ +{eval $style="even";} + +{foreach $rows as $row} +{eval $style = ($style=="even") ? "odd" : "even"} + + + +{/foreach} +
{row.message}
+~~~~~~~~~~~~~ + +All variables when using the `eval` construct, are +mapped to local template variables. + +It is not ok to use variables named or starting with +`$_v`, since that will result in naming errors on +compile time, and you won't be able to use your data +in the template, since it's in the wrong location. + +#### 5.2 eval_literal + +When you need global variables and objects, to execute more complex +code, you can use the `eval_literal` construct. The code inside +does not get evaluated, meaning it is kept as-is. + +~~~~~~~~~~~ +{eval_literal + global $cms_module; + $_v['menu_data'] = + $cms_module->get_menu("branch", array("item","menu")); } +~~~~~~~~~~~ + +#### 5.3 php + +~~~~~~~~~~~~~~~ +{php} +function mygettime() +{ + return array("time"=>time(),"date"=>date("r"),"microtime"=>microtime()); +} +$mygettime = mygettime(); +{/php} + +{mygettime|var_dump} +~~~~~~~~~~~~~~~ + +The above code gets compiled into: + +~~~~~~~~~ +vars; + + function mygettime() + { + return array("time"=>time(),"date"=>date("r"),"microtime"=>microtime()); + } + + $_v['mygettime'] = mygettime(); + + echo var_dump($_v['mygettime']); +?> +~~~~~~~~~ + +This is by far the least used construct and also least tested. +If you want to build objects or functions or use a lot of PHP +code inside the template, you are definetly doing something wrong, +even if supported by the templating system. + +It is not ok to use variables named or starting with +`$_v`, since that will result in naming errors on +compile time, and you won't be able to use your data +in the template, since it's in the wrong location. + +

6. PHP usage reference Δ Jump to top

+ +This section is about functionality of the template system in PHP. +You already know how to make templates like the ones above, this +teaches you how to create the PHP code, that uses the templates. + +#### 6.1 Basic usage + +For basic usage, you need to include the file `class.template.php`. +The functions used include `class.template_compiler.php` if needed. +The following methods are exported: + +`load`, `assign`, `render`, `get`, `set_paths`, `set_compile_location`, `compile` + +You will probablly only use the first four methods unless you +want to change the default paths, where the system is searching for +templates, or if you want to do your own compiling of templates +for whatever reason. + +##### 6.1. load ( string $filename ) + +With this method you specify which template file to load. It will +search trough the configured paths (Default: `templates/`) and +use the template. Calling this method resets the template to it's +defaults, and you have to fill up the content using the `assign` +method. + +##### 6.2. assign ( mixed $key, [ mixed $value = '' ] ) + +This is the most complex method available, and it's behaviour is +dependant on the parameters supplied. + +If the first parameter is an array, and the second parameter stays +at the default value, an entry will be created for each key and value +pair in the first parameter. + +If the first parameter is an array, and the second parameter is +a string value, an entry will be created for each key and value +pair in the first parameter, using the second parameter as a prefix +for each key. + +If the first parameter is a string, the second parameter will be +assigned as it's value. The second parameter can be any PHP type. + +~~~~~~~~ +$data = array(); // some example data +$data['title'] = "Leno promises smooth transition to O'Brien"; +$data['content'] = "For months, Fallon has been widely considered + the top choice to succeed O’Brien when he steps + down next year. On Thursday, published reports ..."; + +/* This will define an entry {timestamp} */ + +$tpl->assign("timestamp", time()); + +/* This will define entries {title} and {content} */ + +$tpl->assign($data); + +/* This example will define {news_title} and {news_content} */ + +$tpl->assign($data, "news"); + +/* This will define the item {news}, which contains an array. + You can output the fields with {news.title} and {news.content} */ + +$tpl->assign("news", $data); +~~~~~~~~ + +##### 6.3. render and get + +Theese methods dont have any arguments. Template compilation is +done in the background, if needed. The method `render` outputs +the data to standard output, while the method `get` simply returns +it, in order to use it in PHP. + +##### 6.4. set_paths ( [ $paths = false ] ) + +The method `set_paths`, takes an array, with possible locations +for template files. The compiled location is set with the +`set_compile_location` function documented later. Paths passed to +this function, must end with a trailing slash. + +The template system will traverse the `$paths` array searching +for template files, until one is found. If none are found, an +error is printed, and the script execution is terminated. + +This is useful if you have multiple template locations, which +are overridable. For example, you can have the following CMS +structure. + +~~~~~~~~~~~~~~~ +$paths = array(); + +/* This is the most important location, everything + can be overriden from inside the theme. */ + +$paths[] = "theme/templates/"; + +/* This is the second most important location, + it usually defines the look of the cms modules */ + +$paths[] = "modules/".$module_name."/templates/"; + +/* This is the least important template location, + it usually provides system wide templates, like + a paginator template, an xml / rss template, or + other very general templates. */ + +$paths[] = "include/templates/"; + +$tpl->set_paths($paths); +~~~~~~~~~~~~~~~ + +Templating constructs like `{include}` are affected by the path +settings. The included templates use the same paths in the same +order, until a needed template is found. + +The following syntax is also allowed since 2012/05/24: + +~~~~~~~~~~~~~~~ +$tpl->set_paths("theme/templates/","modules/".$module_name."/templates/","include/templates/"); +~~~~~~~~~~~~~~~ + +##### 6.5. $this->set_compile_location( [ $compile_location = "cache/" [ , $is_absolute = false ] ] ); + +By default the compile location of the templates is relative to the +source template folder. So, with the template locations listed above, +you would need a `cache/` folder under every location, to store the compiled +template files for later use. + +You can modify this behavior with the `set_compile_location` function. +You can set the cache location to a common folder, and mark it as +an absolute location (as opposed to the default, relative path). + +~~~~~~~~~~~~~~~ +$tpl->set_compile_location("/tmp/minitpl", true); +~~~~~~~~~~~~~~~ + +The example will store all your templates under `/tmp/minitpl`. This +location needs to be writable. The compiled files under the location +can be safely deleted any time, if you want to regenerate them. + +When caching, a full path structure will be created, to avoid any +conflicts between templates, that use same names. For example: + +If you have a template named `site.tpl` under two distinct locations like +`theme/templates/` and `theme/issue2012/templates/` and use both sources, +the conflict is resolved by creating the following structure in the +cache location: + +~~~~~~~~~~~~~~~ +/tmp/minitpl/theme/templates/site.tpl +/tmp/minitpl/theme/issue2012/templates/site.tpl +~~~~~~~~~~~~~~~ + +This can let you change your source folders with `set_paths~ and and the +same time only have one cache location for all your templates. When +you want to expunge any stale cache files or use minitpl in a more complex +system, this is a much simpler approach for cache management. \ No newline at end of file diff --git a/codegen/vendor/monotek/minitpl/documentation/documentation_sl.markdown b/codegen/vendor/monotek/minitpl/documentation/documentation_sl.markdown new file mode 100644 index 000000000..2ac40fdbd --- /dev/null +++ b/codegen/vendor/monotek/minitpl/documentation/documentation_sl.markdown @@ -0,0 +1,705 @@ +Monotek Mini Template +===================== + +Zadnje posodobljeno - Tue 18 Dec 2012 11:24:30 AM CET + +Avtor: Tit Petrič ( tit.petric@monotek.net ) / Monotek d.o.o.
+ + +Predstavitev +------------ + +Stabilna Produkcijska različica podpira sestavljanje šablone in je združljiva +s PHP4 in PHP5. Za ohranjanje majhne velikosti kode uporablja zelo napredne +funkcije, ob tem pa poskrbi za izjemno uporabnost. + +Celotna koda je velika 13,5 KB in vsebuje minimalno količino komentarjev in +zamik kode z uporabo tabulatorjev za berljivost. + +Koda je zaščitena z [Creative Commons Priznanje Avtorstva - Deljenje pod +enakimi pogoji](http://creativecommons.org/licenses/by-sa/3.0/) licenco. + + +Namestitev in potrebna programska oprema +---------------------------- + +Za delovanje Monotek Mini Template potrebujete PHP različice 4.3.0 ali novejšo. +Sistem lahko deluje tudi s starejšimi PHP različicami, če priskrbite svojo +[file_get_contents()}(http://php.net/file_get_contents) funkcijo. + +Glede na mapo, kjer uporabljate template objekt, potrebujete mape: + +> templates/
+> templates/cache/ * + +Ker pa se ta template sistem sestavlja, boste potrebovali tudi cache mapo. + +Jezikovna vezava +------------------ + +Ker je način uporabe template sistema podoben Smarty template sistemu in PHP +programskem jeziku, vam bo poznavanje PHP osnov v pomoč pri uporabi tega +template sistema. + +1. Sestava jezika +2. Zanke +3. Pogoji +4. Block in Inline definicije +5. Napredno, vstavljanje PHP kode +6. Uporaba template sistema v PHP + +---------------------------------------------------------- + +

1. Jezikovna sestava Δ Skok na vrh

+ +Jezikovna sestava vam ponuja razlago delovanja sistema, da boste lahko pričeli +z ustvarjanjem in uporabo svojih template datotek. Prva stvar, katero je +potrebno povedat je, da so vse jezikovne sestave definirane med zavitima +oklepajema (`{` in `}`). Če template sistem ne prepozna jezikovne sestave, je +ne prevaja. To omogoča uporabo javascript in json zapisov brez težav. + +#### 1.1. Spremenljivke + +Uporaba spremenljivk je enostavna. Spremenljivke so zaprte med zavite oklepaje: +`{spremenljivka}`. Ker so spremenljivke prevedene v zadnji stopnji, je uporaba +znaka dolar pred njimi neobvezna. Zato ni nobene razlike med zapisom +`{$spremenljivka}` in zapisom `{spremenljivka}`, oba sta pravilna. + +~~~~~~~~~~~~~ +{spremenljivka} je enako kot {$spremenljivka} +~~~~~~~~~~~~~ + +#### 1.2. Množice + +Obstaja kratek način uporabe množic znotraj template. Če želite izpisati +spremenljivko, ki se nahaja znotraj množice, za naslavljanje uporabite operator +`.` (pika). Množice lahko naslavljate v poljubno globino kot `$mnozica.tocka.0` +ali pa tudi z uporabo spremenljivk, ki se začnejo z znakom dolar +`{$mnozica.$novice.naslov}`. Prav tako je mogoča uporaba PHP jezikovne sestave +kot je razvidno iz spodnjega primera. + +~~~~~~~~~~~~ +{$array.items} je enako kot {$array['items']} +{$array.items.0} je enako kot {$array['items'][0]} +{$array.$items.0} je enako kot {$array[$items][0]} +~~~~~~~~~~~~ + +#### 1.3. Prikrojevalci + +Prikrojevalci so PHP funkcije, ki iz poljubne vrednosti (ponavadi besede) +vrnejo besedo, ki se prikaže. Nekatere PHP funkcije se lahko uporabljajo +kot prikrojevalci (strtoupper, ucfirst, str_rot13, strrev, count, ...). + +~~~~~~~~~~~~~~~~~~~~~~~~ +/** Primer uporabe prikrojevalcev */ + +function add_it_up($array) +{ + $size = 0; + foreach ($array as $value) { + $size += $value['size']; + } + return $size; +} +~~~~~~~~~~~~~~~~~~~~~~~~ + +Za uporabo zgornje funkcije kot prikrojevalca v template datoteko vpišite +`{$variable|add_it_up}`. Prikrojevalec bo šel čez vse elemente spremenljivke +in seštel vrednosti pod ključem `size`, ter izpisal seštevek. + +Podajanje dodatnih parametrov prikrojevalcem ni omogočeno. Če ne morete okoli +tega, potem si oglejte kategorijo naprednih zmožnosti +kjer boste zvedeli za način, kako vključiti PHP kodo v template datoteko. + +Template sistem vključuje poseben prikrojevalec z imenom `escape`, kater se +zamenja z klicem `htmlspecialchars($left, ENT_QUOTES);`. Ta prikrojevalec vam +služi za izpis podatkov znotraj HTML, kateri mogoče vsebujejo narekovaje ali +pa znake `<` (manjše) in `>` (večje). V primeru je demonstrirana pravilna +uporaba uporaba tega prikrojevalca. + +~~~~~~~~~~~~~~~ + + +Read more ... +

{site.title|escape}

+{content} {* pričakujemo HTML, tukaj ne rabimo escape *} +~~~~~~~~~~~~~~~ + +Dodatna template prikrojevalca sta še `toupper` za `strtoupper` in `tolower` +za `strtolower`. Za naštete prikrojevalce ni narejenih posebnih funkcij. + +~~~~~~~~~~~~~~ +{variable|escape} +{variable|toupper} +{variable|add_id_up} +~~~~~~~~~~~~~~ + +Zgornja koda se prevede v naslednje: + +~~~~~~~~~~~~~~ +vars; + echo htmlspecialchars($_v['variable'], ENT_QUOTES); + echo strtoupper($_v['variable']); + echo add_id_up($_v['variable']); +?> +~~~~~~~~~~~~~~ + +V praksi se prikrojevalci pogosto uporabljajo za izpis podatkov v json notaciji +za uporabo znotraj javascript knjižnic (uporaba funkcije `json_encode`) + +#### 1.4. Objekti + +Objekte lahko kličete tudi kot prikrojevalce, za globalne ali lokalne objekte. +Ob prevajanju se določi, če obstaja globalni objekt z navedenim imenom in +se glede na to prilagodi prevedeno kodo. + +~~~~~~~~~~~ +{$variable|$memcache->get} +~~~~~~~~~~~ + +Če globalni objekt ne obstaja se predvideva, da obstaja lokalni objekt. + +~~~~~~~~~~~ +vars; + echo $_v['memcache']->get($_v['variable']); +?> +~~~~~~~~~~~ + +Če globalni objekt v času prevajanja obstaja se template prevede tako: + +~~~~~~~~~~ +vars; + global $memcache; + echo $memcache->get($_v['variable']); +?> +~~~~~~~~~~ + +Na enak način lahko uporabljate tudi spremenljivke iz objektov. + +~~~~~~~~~~~~ +{$memcache->variable} +~~~~~~~~~~~~ + +Kar se prevede se v naslednje: + +~~~~~~~~~~ +vars; + echo $_v['memcache']->variable; +?> +~~~~~~~~~~ + +ali + +~~~~~~~~~~ +vars; + global $memcache; + echo $memcache->variable; +?> +~~~~~~~~~~ + +#### 1.5. Konstante + +Vrednost, ki ima na začetku znak `_` se smatra za konstanto. Template sistem +bo izpisal vrednost konstante, če je ta določena, ali pa ime konstante če ni. +Zaradi teh pravil bo niz `{_MOJA_KONSTANTA}` uporabljen kot konstanta, medtem +ko bo `{$_MOJA_NESPREMENLJIVKA}` uporabljen kot spremenljivka, ker se začne z +znakom za dolar `$`. + +~~~~~~~~~~~ +{_MY_CONSTANT} +{_this_is_also_a_constant} +{$_my_variable} +~~~~~~~~~~~ + +Zgornja koda se prevede v naslednje: + +~~~~~~~~~~~ +vars; + echo _MY_CONSTANT; + echo _this_is_also_a_constant; + echo $_v['_my_variable']; +?> +~~~~~~~~~~~ + +#### 1.6. Vključitev ločenih template datotek + +Niz `{include imedatoteke.tpl}` se zamenja z vsebino določene template +datoteke ob začetku prevajanja. V primeru, da želite spremeniti vsebino +vključene template datoteke, morate obnoviti prevedeno kodo glavne template +datoteke. To naredite ročno (z izbrisom vsebine cache direktorija ali obnovo +časa posodobitve glavne template datoteke). V template datotekah lahko +vključite poljubno število drugih template datotek. + +~~~~~~~~~~~ + + + {$title} + + +{include site_header.tpl} +{$contents} +{include site_footer.tpl} + + +~~~~~~~~~~~ + +Če želite imeti dejansko nalaganje skupnih datotek, kar reši nekatere težave +okoli dinamičnega nalaganja in hranjenja cache datotek, potem uporabite `{load}`: + +Imejte v mislih, da s to metodo ni možna uporaba `inline` in `blok` definicij +izven naložene template datoteke. To lahko dosežete z uporabo `include`. + +~~~~~~~~~~~ + + + {$title} + + +{load $dynamic_header} +{load $dynamic_contents_template} +{load $dynamic_footer} + + +~~~~~~~~~~~ + +#### 1.7. Komentarji + +Komentarji so zaprti med `{*` in `*}`. Komentarji se odstranijo med prevajalnim časom in se ne prikažejo v prevedeni kodi ali izpisu. Uporabni so za izčrpno dokumentacijo, s čimer ne povzročajo povečanega časa obdelave. + +~~~~~~~~~~~ +{* This is a comment that won't be shown anywhere, + except in the source template, only to developers. *} + +Hello world! +~~~~~~~~~~~ + +Kar se prevede v: + +~~~~~~~~~~~ +`Hello world!` +~~~~~~~~~~~ + +

2. Zanke Δ Skok na vrh

+ +#### for, foreach, foreach / else, while + +Cilj sintakse je pomagati razvijalcu, zato je podobna PHP sintaksi. +Medtem ko to ni idealno za spletne programerje, ki izdelujejo template +datoteke, je idealno za veliko večino PHP razvijalcev, katerim se ni +potrebno naučiti novega programskega jezika za template sistem. +Pravtako, osnove PHP jezika kot so predstavljene, nebi smele predstavljati +večjih problemov za oblikovalce, ki že zdaj izdelujejo template datoteke +npr. za Smarty. Običajno programer naredi prvo template datoteko, oblikovalci +jo pa za tem popravljajo. + +~~~~~~~~~~~~ + +{for $i=0; $i +{/for} +{foreach $array as $value} + I like values like I like: {value}
+{/foreach} +{foreach $array as $key=>$value} + I like my value {value} to have a key {key}.
+{/foreach} +{foreach $array as $key=>$value} + I like my value {value} to have a key {key}.
+{else} + I'm sorry, I have nothing in the array.
+{/foreach} +{while ($k++ < 10)} + Well, k is {k}
+{/while} + +~~~~~~~~~~~~ + +Kot vidite, je template sistem zelo prijazen PHP razvijalcem. +Primerjava z originalno PHP kodo (dva načina): + +~~~~~~~~~~~~ +echo ''; +for ($i=0; $i'; +} +foreach ($array as $value) { + echo 'I like values like I like: '.$value.'
'; +} +foreach ($array as $key=>$value) { + echo 'I like my value '.$value.' to have a key '.$key.'.
'; +} +if (!empty($array)) { + foreach ($array as $key=>$value) { + echo 'I like my value '.$value.' to have a key '.$key.'.
'; + } +} else { + echo "I'm sorry, I have nothing in the array.
"; +} +while ($k++ < 10) { + echo "Well, k is ".$k."
"; +} +echo ''; +~~~~~~~~~~~~ + +Medtem ko ta primer prikazuje podobnost v skladnji, prikazuje tudi, kako vam +pisanje template datotek lahko vzame manj časa in je končni izdelek bolj +berljiv. Če ste morda opazili, izjave podpirajo celotno PHP sintakso. +Medtem ko to ni očitno ko pride do `foreach` zanke, lahko vidite, da je +pri ostalih primerih prevedena koda skoraj identična template kodi. + +~~~~~~~~~~~~~~~~~~~ +

{foreach $items.news as $newsitem}-{/foreach}

+

{foreach $items['news'] as $newsitem}+{/foreach}

+

{for $i=0; $i!{/for}

+

{for $i=0; $i?{/for}

+~~~~~~~~~~~~~~~~~~~ + +

3. Pogoji Δ Skok na vrh

+ +Sintaksa za `if` in `elseif` izjave je enaka kot v PHP. Z njimi lahko kličete +funkcije, metode, uporabljate konstante in izvajate aritmetične operacije. +Spremenljivke so prevedene v lokalne spremenljivke, katere ste določili pri +prikazu template datoteke. Istočasno se lahko uporablja PHP sintakso za +naslavljanje množic kot pa tudi olajšano (shorthand) sintakso z uporabo pike. +V prvem primeru je demonstrirana različna sintaksa za množice. + +#### 3.1. if izjave + +~~~~~~~~~~~~~ +{if $is.admin && $user['name']=="black"} + {* Hello black! Only you can edit things, + but only as long as you stay an admin. *} + ... +{/if} +~~~~~~~~~~~~~ + +#### 3.2. if/elseif/else izjave + +~~~~~~~~~~~~~ +{if $is.admin && $user['name']=="black"} + {* Hello black! Only you can edit things, + but only as long as you stay an admin. *} + ... +{elseif $is_moderator} + {* Hello moderator! You can do some things. *} +{else} + {* You are a nobody and you earn nothing! *} +{/if} +~~~~~~~~~~~~~ + +#### 3.3. foreach/else izjave + +~~~~~~~~~~~~~ +{foreach $newsitems.$section.items as $item} +
+

{item.title}

+
{item.content}
+
+{else} +
+ No newsitems exist in the chosen section. +
+{/if} +~~~~~~~~~~~~~ + +#### 3.4. nocache + +MiniTPL template datoteke se prevajajo v PHP datoteke po potrebi +za najboljšo možno hitrost izvajanja. Z uporabo `{include}` direktiv +se osveževanje php datotek rahlo zakomplicira. Za potrebe razvoja smo +dodali `nocache` direktivo. Z uporabo direktive zagotovite, da se vaš +template cache zbriše po vsaki uporabi. + +~~~~~~~~~~~~ +{*nocache*} +~~~~~~~~~~~~ + +To funkcionalnost se mora omogočiti z setiranjem `$tpl->_nocache` na `true`. + +

4. Bloki in Inline definicije Δ Skok na vrh

+ +Odvisno od uporabe boste morda želeli večkrat uporabiti delce iste kode v +eni ali večih template datotekah. To lahko dosežete z uporabo `block` in +`inline` definicij. Razlika med `block` definicijo in `inline` definicijo je +v tem, da se `block` definicija prevede v PHP funkcijo in jo lahko uporabljamo +rekurzivno, naprimer za ustvarjanje drevesne strukture. Uporaba `inline` +definicije vam omogoča le večkratno uporabo enake kode. + +#### 4.1 block definicija in uporaba + +~~~~~~~~~~~ +{block recurse} +{if $i++ < 10} + call {i} + {block:recurse} +{/if} +{/block} + +{block:recurse} +~~~~~~~~~~~ + +Prevedena template datoteka bo izgledala nekako takole: + +~~~~~~~~~~~ +vars; + function recurse_1213891842_673($_v) { + if ($_v['i']++ < 10) { + echo "call ".$_v['i']; + recurse_1213891842_673(&$_v); + } + } + recurse_1213891842_673(&$_v); +?> +~~~~~~~~~~~ + +Kot lahko vidite, se `block` definicija prevede v funkcijo, ki uporablja +iste spremenljivke, katere ste določili template datoteki. + +Ustvarjanje ali izris drevesne strukture ta način ni zelo praktičen, je pa +možen. Vrjetno nikoli ne boste potrebovali tega. Po naših izkušnjah je +rekurzija uporabljena le redko, če pa že, pa v PHP kodi in ne v template +datotekah. + +Uporabite lahko `block` konstrukt namesto `inline`, če vas skrbi za velikost +prevedene template datoteke. Sam bi to predlagal, ko pridete do tega, da je +ena `inline` definicija dolga več kilobyteov in se jo uporablja večkrat v +isti template datoteki. + +#### 4.2 inline definicija in uporaba + +Ključna beseda `inline` prihaja iz programskega jezika `C++`, kjer prevajalnik +zamenja klice inline funkcij z vsebino funkcije. S tem v `C++` pridobimo na +hitrosti, ker je klicanje funkcije bolj praktično za berljivost, kot pa +kopiranje kode po najvišjem nivoju. Iz enakega razloga se uporablja tudi +v tem template sistemu. + +~~~~~~~~~~ +{inline newsitem} +
+

{news.title}

+
{news.content}
+
+{/inline} + +
+ {foreach $newsitems.top.items as $news}{inline:newsitem}{/foreach} +
+ +
+{foreach $newsitems.$section.items as $news}{inline:newsitem}{/foreach} +
+~~~~~~~~~~ + +Uporaba `inline` definicij zmanjša velikost template datotek pred prevajanjem +in pripomore k lepši obliki template datotek. Določeni sestavni deli so lahko +torej večkrat uporabljeni v template datoteki. + +

5. Napredno, vstavljanje PHP kode Δ Skok na vrh

+ +Medtem ko zgornji jezikovni sestavki poskrbijo le za izpis, včasih potrebujemo +tudi posodobiti spremenljivke znotraj template datoteke. Za to poskrbijo +sestavki `eval`, `eval_literal` in `php`. Sestavek `php` je namenjen +zahtevnejšim operacijam in ima kot `eval` dostop direktno do spremenljivk +katere ste podali template datoteki. + +#### 5.1 eval + +Eval sestavek vam omogoča hitre operacije z lokalnimi template spremenljivkami. +Če želite naprimer narediti tabelo, ki ima v vsaki vrstici drugačen CSS stil, +bi to naredili nekako takole: + +~~~~~~~~~~~~~ +{eval $style="even";} + +{foreach $rows as $row} +{eval $style = ($style=="even") ? "odd" : "even"} + + + +{/foreach} +
{row.message}
+~~~~~~~~~~~~~ + +Uporabo spremenljivke `$_v` odsvetujemo, saj lahko povzročajo napake +pri prevajanju, ali pa z uporabo te spremenljivke prepišete podatke, kateri +so bili namenjeni prikazu. + +Uporaba `{` in `}` znotraj `eval` in `eval_literal` sestavkov ni mogoča. + +#### 5.2 eval_literal + +Ko potrebujete za izvajanje kode globalne spremenljivke ali objekte, +lahko uporabite `eval_literal` sestavek. Koda znotraj sestavka se ne prevede, +ostane torej taka kot je. + +~~~~~~~~~~~ +{eval_literal + global $cms_module; + $_v['menu_data'] = + $cms_module->get_menu("branch", array("item","menu")); } +~~~~~~~~~~~ + +Uporaba `{` in `}` znotraj `eval` in `eval_literal` sestavkov ni mogoča. + +#### 5.3 php + +~~~~~~~~~~~~~~~ +{php} +function mygettime() +{ + return array("time"=>time(),"date"=>date("r"),"microtime"=>microtime()); +} +$mygettime = mygettime(); +{/php} + +{mygettime|var_dump} +~~~~~~~~~~~~~~~ + +Zgornja koda se prevede v: + +~~~~~~~~~ +vars; + + function mygettime() + { + return array("time"=>time(),"date"=>date("r"),"microtime"=>microtime()); + } + + $_v['mygettime'] = mygettime(); + + echo var_dump($_v['mygettime']); +?> +~~~~~~~~~ + +To je najmanj uporabljen in najmanj testiran sestavek. Če želite zgraditi +objekte ali funkcije ali uporabiti veliko PHP kode znotraj tamplate datoteke, +definitivno delate nekaj narobe, čeprav template sistem to podpira. + +Uporabo spremenljivke `$_v` odsvetujemo, saj lahko povzročajo napake +pri prevajanju, ali pa z uporabo te spremenljivke prepišete podatke, kateri +so bili namenjeni prikazu. + +

6. Uporaba template sistema v PHP Δ Skok na vrh

+ +V tej kategoriji bomo pregledali zmogljivosti template sistema v PHP. +Ker že znate izdelovati template datoteke vam bomo v tem oddelku prikazali, +kako narediti PHP kodo s katero uporabimo template datoteke. + +#### 6.1 Osnovna uporaba + +Za osnovno uporabo morate vključiti datoteko `class.template.php`. Uporabljene +funkcije bodo po potrebi same vključile datoteko `class.template_compiler.php`. +Za razvijalce so na voljo naslednje metode: + +`load`, `assign`, `render`, `get`, `set_paths`, `compile` + +Ponavadi boste uporabljali le prve štiri metode, če seveda ne želite +spremeniti map, kjer sistem išče template datoteke ali pa bi želeli sami +prevajati template datoteke. + +##### 6.1. load ( string $filename ) + +S to metodo določite katera template datoteka se naj naloži. Metoda bo +preiskala nastavljene poti (Privzeto: `templates/`) in naložila želeno +template datoteko. Klic te metode izprazni podatke namenjene template +datoteki, katerega naknadno določite z uporabo `assign` metode. + +##### 6.2. assign ( mixed $key, [ mixed $value = '' ] ) + +Za programerja je ta metoda najbolj ključna. Rezultat metode je različen glede +na količino in vrstni red podanih parametrov. + +Če je prvi parameter množica, drug parameter pa ni podan, potem se template +datoteki določi ena vrednost z ključem vnosa v množico, za vsak vnos. + +Če je prvi parameter množica in drug parameter niz znakov, bo narejen vnos +za vsako vrednost v množici. Za ključ vnosa bo uporabljen niz v drugem +parametru, kateremu sledi `_` in potem ključ vnosa iz množice. + +Če je prvi parameter niz znakov, potem bo drug parameter določen kot vrednost +dosegljiva pod ključem prvega parametra. Tip drugega parametra ni pomemben. + +~~~~~~~~ +$data = array(); // some example data +$data['title'] = "Leno promises smooth transition to O'Brien"; +$data['content'] = "For months, Fallon has been widely considered + the top choice to succeed O’Brien when he steps + down next year. On Thursday, published reports ..."; + +/* This will define an entry {timestamp} */ + +$tpl->assign("timestamp", time()); + +/* This will define entries {title} and {content} */ + +$tpl->assign($data); + +/* This example will define {news_title} and {news_content} */ + +$tpl->assign($data, "news"); + +/* This will define the item {news}, which contains an array. + You can output the fields with {news.title} and {news.content} */ + +$tpl->assign("news", $data); +~~~~~~~~ + +##### 6.3. render, get + +Te metode nimajo parametrov. Prevajanje template datotek je izvedeno v ozadju, +če je potrebno. Metoda `render` izpiše podatke v navadni obliki, medtem ko +jih medota `get` vrne v obliki katero lahko uporabimo v PHP. + +##### 6.4. set_paths ( [ $paths = false ] ) + +Metoda `set_paths` vzame množico z možnimi lokacijami za template datoteke. +Lokacija za prevajanje template datotek je mapa `cache`, katera mora obstajati +v vsaki od podanih map. Podane mape se morajo končati z vrezom (slash). + +Template sistem bo pregledal `$paths` množico, dokler ne najde template +datoteke, katero želimo naložiti preko metode `load`. Če datoteke ne najde, +izpiše napako, izvajanje se konča. + +Metoda je uporabna v primeru, če želite imeti več map s template datotekami. +Naprimer, če želite imeti CMS strukturo. + +~~~~~~~~~~~~~~~ +$paths = array(); + +/* This is the most important location, everything + can be overriden from inside the theme. */ + +$paths[] = "theme/templates/"; + +/* This is the second most important location, + it usually defines the look of the cms modules */ + +$paths[] = "modules/".$module_name."/templates/"; + +/* This is the least important template location, + it usually provides system wide templates, like + a paginator template, an xml / rss template, or + other very general templates. */ + +$paths[] = "include/templates/"; + +$tpl->set_paths($paths); +~~~~~~~~~~~~~~~ + +Konstrukt `{include}` v template datotekah upošteva nastavitve podane preko +metode `set_paths`. Pred prevajanjem sistem išče datoteke za vključitev na +istih lokacijah, dokler jih ne najde. diff --git a/codegen/vendor/monotek/minitpl/phpunit.xml b/codegen/vendor/monotek/minitpl/phpunit.xml new file mode 100644 index 000000000..5a059e95c --- /dev/null +++ b/codegen/vendor/monotek/minitpl/phpunit.xml @@ -0,0 +1,22 @@ + + + + test/TemplateTest.php + + + + + code + + vendor + + + + vendor + /usr/local/bin/phpunit + + + + + + diff --git a/codegen/vendor/monotek/minitpl/test/.gitignore b/codegen/vendor/monotek/minitpl/test/.gitignore new file mode 100644 index 000000000..4ebc8aea5 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/.gitignore @@ -0,0 +1 @@ +coverage diff --git a/codegen/vendor/monotek/minitpl/test/TemplateTest.php b/codegen/vendor/monotek/minitpl/test/TemplateTest.php new file mode 100644 index 000000000..0fc503419 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/TemplateTest.php @@ -0,0 +1,128 @@ +set_paths("test/templates/"); + $tpl->set_compile_location("test/compile/", false); + $tpl->add_default("key", "val"); + + $source = "test/templates/".$template; + $return = $tpl->compile($source, $destination); + + $this->assertTrue((bool)$return); + $this->assertFileEquals($destination, $compiled); + } + + public function compileProvider() + { + $tests = array(); + $templates = glob("test/templates/*.tpl"); + sort($templates); + foreach ($templates as $template) { + $tests[] = array(basename($template)); + } + return $tests; + } + + public function testRendering() + { + $tpl = new Monotek\MiniTPL\Template; + + $tpl->set_paths("test/templates/"); + $tpl->set_compile_location("test/compile/", false); + $tpl->add_default("key", "val"); + + $retval = array(); + exec("rm -rf test/templates/test -rf", $retval); + + $this->assertTrue($tpl->load("08_utf8_bom.tpl")); + + touch("test/templates/test/compile/08_utf8_bom.tpl", filemtime("test/templates/08_utf8_bom.tpl") - 86400); + + $this->assertTrue($tpl->load("08_utf8_bom.tpl")); + + $items = array(); + $items[] = array("id" => $i++); + $items[] = array("id" => $i++); + $items[] = array("id" => $i++); + $tpl->assign("items", $items); + $tpl->assign(array("foo"=>"bar", "d" => array("burger")), "foo"); + $tpl->assign(".foo_foo", "baz"); + $tpl->assign(".foo_d", array("steak", "beef", "pork", "chicken")); + + $contents1 = $tpl->get(); + + ob_start(); + $tpl->render(); + $contents2 = ob_get_contents(); + ob_end_clean(); + + $this->assertEquals($contents1, $contents2); + + $this->assertFalse($tpl->_find_path("404.tpl")); + + $tpl->set_compile_location("test/compile/", false); + $this->assertEquals("test/templates/test/compile/", $tpl->_compile_path("test/templates/")); + $tpl->set_compile_location("/test/compile/", true); + $this->assertEquals("/test/compile/test/templates/", $tpl->_compile_path("test/templates/")); + + $retval = array(); + exec("rm -rf test/templates/test -rf", $retval); + } + + public function testException() + { + $this->setExpectedException("Exception"); + $tpl = new Monotek\MiniTPL\Template; + $tpl->set_compile_location("test/compile/", false); + $tpl->set_paths("test/templates2/"); + $tpl->load("fail_to_compile.tpl"); + } + + /** + * @dataProvider varsProvider + */ + public function testVars($expression, $expected, $description) + { + global $tpl; + $tpl = new Monotek\MiniTPL\Compiler; + + $result = $tpl->_split_exp($expression); + $this->assertEquals($expected, $result); + } + + public function testFailure() + { + $this->setExpectedException("Exception"); + $tpl = new Monotek\MiniTPL\Template; + $this->assertFalse($tpl->load("missing.tpl")); + $tpl->render(); + } + + public function varsProvider() + { + $vars = array(); + $vars[] = array('news_section_news_list.tpl', 'news_section_news_list.tpl', "normal string"); + $vars[] = array('$var', "\$_v['var']", "variable"); + $vars[] = array('$var.netko', "\$_v['var']['netko']", "array index"); + $vars[] = array('$var . "netko"', "\$_v['var'] . \"netko\"", "string concat"); + $vars[] = array('$var1 . $var2', "\$_v['var1'] . \$_v['var2']", "variable concat"); + $vars[] = array('$var1.$var2', "\$_v['var1'][\$_v['var2']]", "array var index"); + $vars[] = array('$items.0', "\$_v['items']['0']", "array int index"); + $vars[] = array('$tpl->get()', "\$tpl->get()", "global function"); + $vars[] = array('$tplx->get()', "\$_v['tplx']->get()", "object function"); + return $vars; + } +} diff --git a/codegen/vendor/monotek/minitpl/test/bootstrap.php b/codegen/vendor/monotek/minitpl/test/bootstrap.php new file mode 100644 index 000000000..226a2f9f1 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/bootstrap.php @@ -0,0 +1,7 @@ +vars;?> +#### 1.1. Variables + +Using variables from templates is easy. Variables are enclosed +in curly braces like so: ` +`. Since variables are parsed +on the last stage, prefixing variables with the dollar sign is +optional. So, ` +` is the same as ` +`. + +~~~~~~~~~~~~~ + + is the same as + +~~~~~~~~~~~~~ diff --git a/codegen/vendor/monotek/minitpl/test/compiled/02_arrays.tpl b/codegen/vendor/monotek/minitpl/test/compiled/02_arrays.tpl new file mode 100644 index 000000000..03cf15679 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/compiled/02_arrays.tpl @@ -0,0 +1,18 @@ +vars;?> +#### 1.2. Arrays + +There is a shorthand syntax for using arrays inside a template. +The array index separator is a dot (`.`). Consecutive dots can be +used for traversing into array depth like ` +`, or +even variables starting with `$`, like ` +`. +PHP syntax for arrays is also supported. + +~~~~~~~~~~~~ + + is the same as + is the same as + is the same as + +~~~~~~~~~~~~ diff --git a/codegen/vendor/monotek/minitpl/test/compiled/03_modifiers.tpl b/codegen/vendor/monotek/minitpl/test/compiled/03_modifiers.tpl new file mode 100644 index 000000000..041c46050 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/compiled/03_modifiers.tpl @@ -0,0 +1,44 @@ +vars;?> +#### 1.3. Modifiers + +Modifiers are PHP functions, which take one arbitrary value +(usually, string), and return a string, which gets shown. +Some functions in PHP can be used as modifiers +(strtoupper, ucfirst, str_rot13, strrev, count, ...). + +~~~~~~~~~~~~~~~~~~~~~~~~ +/** Custom modifier example */ + +function add_it_up($array) +{ + $size = 0; + foreach ($array as $value) { + $size += $value['size']; + } + return $size; +} +~~~~~~~~~~~~~~~~~~~~~~~~ + +To use the above function in a template, just do ` +`, +which will loop trough all `$variable` items and add up the value of +the size element and return the total sum of all sizes. + +~~~~~~~~~~~~~~ + + +~~~~~~~~~~~~~~ + +The above code gets compiled to: + +~~~~~~~~~~~~~~ +vars; + echo htmlspecialchars($_v['variable'], ENT_QUOTES); + echo strtoupper($_v['variable']); + echo add_id_up($_v['variable']); +?> +~~~~~~~~~~~~~~ + +A common use for modifiers is outputting data for javascript, +using the php function `json_encode`. diff --git a/codegen/vendor/monotek/minitpl/test/compiled/04_objects.tpl b/codegen/vendor/monotek/minitpl/test/compiled/04_objects.tpl new file mode 100644 index 000000000..025d4bd6b --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/compiled/04_objects.tpl @@ -0,0 +1,56 @@ +vars;?> +#### 1.4. Objects + +You can also call object methods as modifiers, from global or +local objects. The compiler will determine at run-time, if +you have a global object by the name, and modify the code +accordingly. + +~~~~~~~~~~~ +get($_v['variable']);?> + +~~~~~~~~~~~ + +If the global object doesn't exist, it assumes a local object. + +~~~~~~~~~~~ +vars; + echo $_v['memcache']->get($_v['variable']); +?> +~~~~~~~~~~~ + +However, if a global object by the name $memcache exists at +compile time: + +~~~~~~~~~~ +vars; + global $memcache; + echo $memcache->get($_v['variable']); +?> +~~~~~~~~~~ + +You can also use variables from objects, in the same way. + +~~~~~~~~~~~~ +variable;?> + +~~~~~~~~~~~~ + +Compiles to one of theese: + +~~~~~~~~~~ +vars; + echo $_v['memcache']->variable; +?> +~~~~~~~~~~ + +~~~~~~~~~~ +vars; + global $memcache; + echo $memcache->variable; +?> +~~~~~~~~~~ diff --git a/codegen/vendor/monotek/minitpl/test/compiled/05_constants.tpl b/codegen/vendor/monotek/minitpl/test/compiled/05_constants.tpl new file mode 100644 index 000000000..e9af41345 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/compiled/05_constants.tpl @@ -0,0 +1,15 @@ +vars;?> +#### 1.5. Constants + +Value starting with `_` is assumed to be a constant. The template +system will output the value of the constant if defined, +or just the name of the constant. Item ` +` will be +used as a constant, because of those rules, however ` +` +wouldnt be, since it starts with the variable identifier `$`. + +~~~~~~~~~~~ + + +~~~~~~~~~~~ \ No newline at end of file diff --git a/codegen/vendor/monotek/minitpl/test/compiled/06_includes.tpl b/codegen/vendor/monotek/minitpl/test/compiled/06_includes.tpl new file mode 100644 index 000000000..441fad26c --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/compiled/06_includes.tpl @@ -0,0 +1,17 @@ +vars;?> +#### 1.6. Includes + +#### 1.5. Constants + +Value starting with `_` is assumed to be a constant. The template +system will output the value of the constant if defined, +or just the name of the constant. Item ` +` will be +used as a constant, because of those rules, however ` +` +wouldnt be, since it starts with the variable identifier `$`. + +~~~~~~~~~~~ + + +~~~~~~~~~~~ diff --git a/codegen/vendor/monotek/minitpl/test/compiled/07_eval.tpl b/codegen/vendor/monotek/minitpl/test/compiled/07_eval.tpl new file mode 100644 index 000000000..70d10aa5f --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/compiled/07_eval.tpl @@ -0,0 +1,12 @@ +vars; $_v['key']="nu";?> + + + + + $_v['item']){?> + + + 1){ echo $_v['i'];?> +nd +first + diff --git a/codegen/vendor/monotek/minitpl/test/compiled/08_utf8_bom.tpl b/codegen/vendor/monotek/minitpl/test/compiled/08_utf8_bom.tpl new file mode 100644 index 000000000..b3bbc6291 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/compiled/08_utf8_bom.tpl @@ -0,0 +1,8 @@ +vars;?> +This file contains utf8 BOM. + +It also uses the +load + construct: + +push();$this->load("07_eval.tpl");$this->assign($_v);$this->render();$this->pop();?> diff --git a/codegen/vendor/monotek/minitpl/test/compiled/09_blocks_and_includes.tpl b/codegen/vendor/monotek/minitpl/test/compiled/09_blocks_and_includes.tpl new file mode 100644 index 000000000..588753a98 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/compiled/09_blocks_and_includes.tpl @@ -0,0 +1,18 @@ +vars;?> + + +Functions bro, functions? + + +This is a created function. This is the +st/nd/rd/th time calling this method. + + + +This is like a copy-paste over your +, anywhere you use this construct. + +This is like a copy-paste over your +, anywhere you use this construct. + + diff --git a/codegen/vendor/monotek/minitpl/test/compiled/10_literal_blocks.tpl b/codegen/vendor/monotek/minitpl/test/compiled/10_literal_blocks.tpl new file mode 100644 index 000000000..59b92b1e8 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/compiled/10_literal_blocks.tpl @@ -0,0 +1,23 @@ +vars;?> +The following block is literal (no template constructs work inside the tags) + + + +Or this: + + + + +But this works: + + \ No newline at end of file diff --git a/codegen/vendor/monotek/minitpl/test/compiled/11_expressions.tpl b/codegen/vendor/monotek/minitpl/test/compiled/11_expressions.tpl new file mode 100644 index 000000000..42cbdf3a7 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/compiled/11_expressions.tpl @@ -0,0 +1,15 @@ +vars; for($_v['i']=99; $_v['i']>=1; $_v['i']--){echo $_v['i'];?> + bottles of beer on the wall, + bottles of beer. Take one down and pass it around, + bottles of beer on the wall. + 10){?> + + We have some beer left. + 3){?> + + Our beer is going to run out. + + + Critical! Only + beer left. + \ No newline at end of file diff --git a/codegen/vendor/monotek/minitpl/test/compiled/12_global_objects.tpl b/codegen/vendor/monotek/minitpl/test/compiled/12_global_objects.tpl new file mode 100644 index 000000000..fc8689978 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/compiled/12_global_objects.tpl @@ -0,0 +1,9 @@ +vars; global $tpl;?> +There is a distinct difference between +calling `$tpl->get` or `$tplx->get`. + +When `$tpl` is a global variable, the template engine detects this. + +_paths;?> + _paths;?> +; \ No newline at end of file diff --git a/codegen/vendor/monotek/minitpl/test/compiled/13_foreach_array.tpl b/codegen/vendor/monotek/minitpl/test/compiled/13_foreach_array.tpl new file mode 100644 index 000000000..c9b8a2412 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/compiled/13_foreach_array.tpl @@ -0,0 +1,7 @@ +vars;?> +We check if arrays are empty to suppress warnings/notices. + + +HTTP +HTTP +HTTP diff --git a/codegen/vendor/monotek/minitpl/test/templates/01_variable.tpl b/codegen/vendor/monotek/minitpl/test/templates/01_variable.tpl new file mode 100644 index 000000000..c8936b7b9 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/templates/01_variable.tpl @@ -0,0 +1,10 @@ +#### 1.1. Variables + +Using variables from templates is easy. Variables are enclosed +in curly braces like so: `{variable}`. Since variables are parsed +on the last stage, prefixing variables with the dollar sign is +optional. So, `{$variable}` is the same as `{variable}`. + +~~~~~~~~~~~~~ +{variable} is the same as {$variable} +~~~~~~~~~~~~~ diff --git a/codegen/vendor/monotek/minitpl/test/templates/02_arrays.tpl b/codegen/vendor/monotek/minitpl/test/templates/02_arrays.tpl new file mode 100644 index 000000000..e40328bb3 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/templates/02_arrays.tpl @@ -0,0 +1,13 @@ +#### 1.2. Arrays + +There is a shorthand syntax for using arrays inside a template. +The array index separator is a dot (`.`). Consecutive dots can be +used for traversing into array depth like `{$array.items.0}`, or +even variables starting with `$`, like `{$sections.$news_section.title}`. +PHP syntax for arrays is also supported. + +~~~~~~~~~~~~ +{$array.items} is the same as {$array['items']} +{$array.items.0} is the same as {$array['items'][0]} +{$array.$items.0} is the same as {$array[$items][0]} +~~~~~~~~~~~~ diff --git a/codegen/vendor/monotek/minitpl/test/templates/03_modifiers.tpl b/codegen/vendor/monotek/minitpl/test/templates/03_modifiers.tpl new file mode 100644 index 000000000..1674b2bce --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/templates/03_modifiers.tpl @@ -0,0 +1,43 @@ +#### 1.3. Modifiers + +Modifiers are PHP functions, which take one arbitrary value +(usually, string), and return a string, which gets shown. +Some functions in PHP can be used as modifiers +(strtoupper, ucfirst, str_rot13, strrev, count, ...). + +~~~~~~~~~~~~~~~~~~~~~~~~ +/** Custom modifier example */ + +function add_it_up($array) +{ + $size = 0; + foreach ($array as $value) { + $size += $value['size']; + } + return $size; +} +~~~~~~~~~~~~~~~~~~~~~~~~ + +To use the above function in a template, just do `{$variable|add_it_up}`, +which will loop trough all `$variable` items and add up the value of +the size element and return the total sum of all sizes. + +~~~~~~~~~~~~~~ +{variable|escape} +{variable|toupper} +{variable|add_id_up} +~~~~~~~~~~~~~~ + +The above code gets compiled to: + +~~~~~~~~~~~~~~ +vars; + echo htmlspecialchars($_v['variable'], ENT_QUOTES); + echo strtoupper($_v['variable']); + echo add_id_up($_v['variable']); +?> +~~~~~~~~~~~~~~ + +A common use for modifiers is outputting data for javascript, +using the php function `json_encode`. diff --git a/codegen/vendor/monotek/minitpl/test/templates/04_objects.tpl b/codegen/vendor/monotek/minitpl/test/templates/04_objects.tpl new file mode 100644 index 000000000..859148fe0 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/templates/04_objects.tpl @@ -0,0 +1,53 @@ +#### 1.4. Objects + +You can also call object methods as modifiers, from global or +local objects. The compiler will determine at run-time, if +you have a global object by the name, and modify the code +accordingly. + +~~~~~~~~~~~ +{$variable|$memcache->get} +~~~~~~~~~~~ + +If the global object doesn't exist, it assumes a local object. + +~~~~~~~~~~~ +vars; + echo $_v['memcache']->get($_v['variable']); +?> +~~~~~~~~~~~ + +However, if a global object by the name $memcache exists at +compile time: + +~~~~~~~~~~ +vars; + global $memcache; + echo $memcache->get($_v['variable']); +?> +~~~~~~~~~~ + +You can also use variables from objects, in the same way. + +~~~~~~~~~~~~ +{$memcache->variable} +~~~~~~~~~~~~ + +Compiles to one of theese: + +~~~~~~~~~~ +vars; + echo $_v['memcache']->variable; +?> +~~~~~~~~~~ + +~~~~~~~~~~ +vars; + global $memcache; + echo $memcache->variable; +?> +~~~~~~~~~~ diff --git a/codegen/vendor/monotek/minitpl/test/templates/05_constants.tpl b/codegen/vendor/monotek/minitpl/test/templates/05_constants.tpl new file mode 100644 index 000000000..54fc8efcd --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/templates/05_constants.tpl @@ -0,0 +1,13 @@ +#### 1.5. Constants + +Value starting with `_` is assumed to be a constant. The template +system will output the value of the constant if defined, +or just the name of the constant. Item `{_MY_CONSTANT}` will be +used as a constant, because of those rules, however `{$_my_variable}` +wouldnt be, since it starts with the variable identifier `$`. + +~~~~~~~~~~~ +{_MY_CONSTANT} +{_this_is_also_a_constant} +{$_my_variable} +~~~~~~~~~~~ \ No newline at end of file diff --git a/codegen/vendor/monotek/minitpl/test/templates/06_includes.tpl b/codegen/vendor/monotek/minitpl/test/templates/06_includes.tpl new file mode 100644 index 000000000..d7d4a4455 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/templates/06_includes.tpl @@ -0,0 +1,3 @@ +#### 1.6. Includes + +{include 05_constants.tpl} diff --git a/codegen/vendor/monotek/minitpl/test/templates/07_eval.tpl b/codegen/vendor/monotek/minitpl/test/templates/07_eval.tpl new file mode 100644 index 000000000..33f18dcdd --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/templates/07_eval.tpl @@ -0,0 +1,12 @@ +{eval $key="nu"} + +{inline item} +{if $i>1}{i}nd{else}first{/if} +{/inline} + +{eval $i=1} +{foreach $items as $index => $item} + {eval $id = $key . $i} + {inline:item} + {eval $i++} +{/foreach} diff --git a/codegen/vendor/monotek/minitpl/test/templates/08_utf8_bom.tpl b/codegen/vendor/monotek/minitpl/test/templates/08_utf8_bom.tpl new file mode 100644 index 000000000..5e3d03c5f --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/templates/08_utf8_bom.tpl @@ -0,0 +1,5 @@ +This file contains utf8 BOM. + +It also uses the {ldelim}load{rdelim} construct: + +{load 07_eval.tpl} \ No newline at end of file diff --git a/codegen/vendor/monotek/minitpl/test/templates/09_blocks_and_includes.tpl b/codegen/vendor/monotek/minitpl/test/templates/09_blocks_and_includes.tpl new file mode 100644 index 000000000..695cd6dbb --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/templates/09_blocks_and_includes.tpl @@ -0,0 +1,19 @@ +{inline snippet1} +This is like a copy-paste over your {eval echo __FILE__}, anywhere you use this construct. +{/inline} + +Functions bro, functions? + +{eval $i=1} +{block function_call} +This is a created function. This is the {i++}st/nd/rd/th time calling this method. +{if $i <= 5} +{block:function_call} +{/if} +{/block} + +{inline:snippet1} + +{inline:snippet1} + +{block:function_call} \ No newline at end of file diff --git a/codegen/vendor/monotek/minitpl/test/templates/10_literal_blocks.tpl b/codegen/vendor/monotek/minitpl/test/templates/10_literal_blocks.tpl new file mode 100644 index 000000000..afea61e85 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/templates/10_literal_blocks.tpl @@ -0,0 +1,20 @@ +The following block is literal (no template constructs work inside the tags) + + + +Or this: + + + + +But this works: + + \ No newline at end of file diff --git a/codegen/vendor/monotek/minitpl/test/templates/11_expressions.tpl b/codegen/vendor/monotek/minitpl/test/templates/11_expressions.tpl new file mode 100644 index 000000000..57a46c46b --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/templates/11_expressions.tpl @@ -0,0 +1,11 @@ +{for $i=99; $i>=1; $i--} +{i} bottles of beer on the wall, {i} bottles of beer. Take one down and pass it around, {eval echo $i-1} bottles of beer on the wall. +{/for} + +{if $i > 10} + We have some beer left. +{elseif $i > 3} + Our beer is going to run out. +{else} + Critical! Only {i} beer left. +{/if} \ No newline at end of file diff --git a/codegen/vendor/monotek/minitpl/test/templates/12_global_objects.tpl b/codegen/vendor/monotek/minitpl/test/templates/12_global_objects.tpl new file mode 100644 index 000000000..5baf961b2 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/templates/12_global_objects.tpl @@ -0,0 +1,6 @@ +There is a distinct difference between +calling `$tpl->get` or `$tplx->get`. + +When `$tpl` is a global variable, the template engine detects this. + +{$tpl->_paths} {$tplx->_paths}; \ No newline at end of file diff --git a/codegen/vendor/monotek/minitpl/test/templates/13_foreach_array.tpl b/codegen/vendor/monotek/minitpl/test/templates/13_foreach_array.tpl new file mode 100644 index 000000000..0859bae21 --- /dev/null +++ b/codegen/vendor/monotek/minitpl/test/templates/13_foreach_array.tpl @@ -0,0 +1,13 @@ +We check if arrays are empty to suppress warnings/notices. + +{foreach array("GET", "POST") as $method} +HTTP {method} +{/foreach} + +{foreach (array("GET", "POST") as $method)} +HTTP {method} +{/foreach} + +{foreach $methods as $method} +HTTP {method} +{/foreach} diff --git a/codegen/vendor/monotek/minitpl/test/templates2/fail_to_compile.tpl b/codegen/vendor/monotek/minitpl/test/templates2/fail_to_compile.tpl new file mode 100644 index 000000000..e69de29bb