{"id":26102479,"url":"https://github.com/sedteam/xtemplatese","last_synced_at":"2026-05-20T16:40:24.850Z","repository":{"id":281263677,"uuid":"944441693","full_name":"sedteam/XtemplateSE","owner":"sedteam","description":"XTemplate SE (Seditio Edition)","archived":false,"fork":false,"pushed_at":"2025-03-07T22:20:38.000Z","size":58,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-07T23:24:06.226Z","etag":null,"topics":["engine","php","template-engine","xtemplate"],"latest_commit_sha":null,"homepage":"https://seditio.org","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sedteam.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-03-07T10:55:17.000Z","updated_at":"2025-03-07T22:20:42.000Z","dependencies_parsed_at":"2025-03-07T23:24:13.185Z","dependency_job_id":"544294e0-fa65-4f00-acae-498457546350","html_url":"https://github.com/sedteam/XtemplateSE","commit_stats":null,"previous_names":["sedteam/xtemplatese"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sedteam%2FXtemplateSE","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sedteam%2FXtemplateSE/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sedteam%2FXtemplateSE/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sedteam%2FXtemplateSE/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sedteam","download_url":"https://codeload.github.com/sedteam/XtemplateSE/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242744061,"owners_count":20178171,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["engine","php","template-engine","xtemplate"],"created_at":"2025-03-09T19:41:46.906Z","updated_at":"2026-05-20T16:40:24.844Z","avatar_url":"https://github.com/sedteam.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"PHP XTemplate SE\n============\n\nTable of Contents\n-----------------\n\n*   [Introduction](#introduction)\n*   [How It Works](#how-it-works)\n*   [Installation](#installation)\n*   [Basic Usage](#basic-usage)\n*   [Template Syntax](#template-syntax)\n*   [Blocks and Variables](#blocks-and-variables)\n*   [Arithmetic Operations](#arithmetic-operations)\n*   [Conditional Logic](#conditional-logic)\n*   [Working with Loops](#working-with-loops)\n*   [Callback Functions](#callback-functions)\n*   [Error Handling](#error-handling)\n*   [Performance Optimization](#performance-optimization)\n*   [History](#history)\n*   [License](#license)\n\nIntroduction\n------------\n\n`XTemplate SE` (Seditio Edition) is a modern and enhanced version of the classic `XTemplate` templating engine for PHP. Designed to separate application logic from presentation, it offers advanced features such as nested blocks, arithmetic operations, conditional logic, loops, and callback functions. It is suitable for both simple and complex projects where flexibility and performance are key.\n\nHow It Works\n------------\n\n`XTemplate SE` employs an object-oriented model for template processing, setting it apart from the older `XTemplate` class. The concept of this object-oriented approach was inspired by the `Cotemplate` templating engine from the [Cotonti](https://www.cotonti.com/) project, but it has been completely reworked and significantly improved for greater flexibility and performance.\n\n*   **Object Structure**:\n    *   Templates are broken down into objects: `XtplBlock` (blocks), `XtplVar` (variables), `XtplExpr` (expressions), `XtplData` (data), and `XtplLogical` (conditions).\n    *   Each template element is represented as a class instance, enabling flexible parsing and rendering, unlike the linear processing of the old `XTemplate`.\n*   **Expression Handling**:\n    *   Arithmetic and logical operations are processed via `XtplExpr` using Reverse Polish Notation (RPN) for accurate evaluation with proper precedence and parentheses support.\n    *   The old `XTemplate` relied on basic regex-based expression handling with limited functionality.\n*   **Enhanced Tokenization**:\n    *   Dynamic tokenization supports complex constructs (parentheses, operator precedence), replacing the static approach of the previous version.\n*   **Advantages Over Old XTemplate**:\n    *   **Extensibility**: Easy to add new operators and functions.\n    *   **Reliability**: Built-in error handling (e.g., division by zero).\n    *   **Performance**: Lazy evaluation of expressions and template structure caching.\n\nExample: `{NUM1 + NUM2}` is converted to RPN (`NUM1 NUM2 +`), evaluated with precedence, and returns the correct result.\n\nInstallation\n------------\n\n1.  Download the `XTemplate.php` file from the repository.\n2.  Include it in your project:\n```    \n   \u003c?php\n   require_once 'XTemplate.php';\n ```                   \n    \n\nNo additional dependencies are required.\n\n### Requirements\n\n```\n   PHP 5.4.0 or higher\n   Mbstring\n   PCRE\n   Hash\n```\n\nBasic Usage\n-----------\n\nCreate a template, assign variables, and render the output:\n```\n    \u003c?php\n    require_once 'XTemplate.php';\n    \n    $xtpl = new XTemplate('template.tpl');\n    $xtpl-\u003eassign('USERNAME', 'John Doe');\n    $xtpl-\u003eparse('MAIN');\n    $xtpl-\u003eout('MAIN');\n```        \n\nTemplate `template.tpl`:\n```\n    \u003c!-- BEGIN: MAIN --\u003e\n    \u003ch1\u003eHello, {USERNAME}!\u003c/h1\u003e\n    \u003c!-- END: MAIN --\u003e\n```        \n\nOutput:\n```\n    \u003ch1\u003eHello, John Doe!\u003c/h1\u003e\n ```       \n\nTemplate Syntax\n---------------\n\n*   **Variables**: `{VAR}` — Inserts the value of a variable.\n*   **Blocks**: `\u003c!-- BEGIN: BLOCK --\u003e ... \u003c!-- END: BLOCK --\u003e` — Defines repeatable or conditional sections.\n*   **Comments**: `\u003c!-- ... --\u003e` — Ignored during processing.\n\nBlocks and Variables\n--------------------\n\nBlocks structure the template, while variables are substituted within them.\n\nExample:\n```\n    \u003c!-- BEGIN: MAIN --\u003e\n    \u003cdiv\u003e\n        \u003cp\u003eName: {USER.name}\u003c/p\u003e\n        \u003cp\u003eScore: {USER.score}\u003c/p\u003e\n    \u003c/div\u003e\n    \u003c!-- END: MAIN --\u003e\n  ```      \n\nPHP:\n```\n    $xtpl-\u003eassign('USER', ['name' =\u003e 'Alice', 'score' =\u003e 95]);\n    $xtpl-\u003eparse('MAIN');\n    $xtpl-\u003eout('MAIN');\n```        \n\nOutput:\n```\n    \u003cdiv\u003e\n        \u003cp\u003eName: Alice\u003c/p\u003e\n        \u003cp\u003eScore: 95\u003c/p\u003e\n    \u003c/div\u003e\n```        \n\nArithmetic Operations\n---------------------\n\nSupported operations: `+`, `-`, `*`, `/`, `%`:\n```\n*   Numeric: `{NUM1 + NUM2}`, `{PRICE - DISCOUNT}`\n*   String: `{STR1 + STR2}` (concatenation)\n```\nExample:\n```\n    \u003cp\u003eTotal: {ITEM.price - ITEM.discount}\u003c/p\u003e\n```        \n\nPHP:\n```\n    $xtpl-\u003eassign('ITEM', ['price' =\u003e 10, 'discount' =\u003e 2]);\n ```       \n\nOutput:\n```\n    \u003cp\u003eTotal: 8\u003c/p\u003e\n ```       \n\nConditional Logic\n-----------------\n\nUse `\u003c!-- IF --\u003e` for conditions:\n```\n*   Comparison operators: `==`, `===`, `!=`, `!==`, `\u003c`, `\u003e`, `\u003c=`, `\u003e=`\n*   Logical operators: `AND`, `OR`, `XOR`, `!`\n```\nExample:\n```\n    \u003c!-- IF {SCORE} \u003e 80 --\u003e\n    \u003cp\u003eHigh score!\u003c/p\u003e\n    \u003c!-- ELSE --\u003e\n    \u003cp\u003eTry harder.\u003c/p\u003e\n    \u003c!-- ENDIF --\u003e\n```        \n\nPHP:\n```\n    $xtpl-\u003eassign('SCORE', 85);\n ```       \n\nOutput:\n```\n    \u003cp\u003eHigh score!\u003c/p\u003e\n ```       \n\nComplex conditions with parentheses:\n```\n    \u003c!-- IF ( {NUM1} \u003e {NUM2} ) AND ( {NUM3} \u003c {NUM4} ) --\u003e\n    \u003cp\u003eComplex condition met\u003c/p\u003e\n    \u003c!-- ENDIF --\u003e\n```        \n\nWorking with Loops\n------------------\n\nUse nested blocks or `\u003c!-- FOR --\u003e` loops to iterate over arrays.\n\n### Nested Blocks\n  \n   Example:\n ```  \n   \u003c!-- BEGIN: MAIN --\u003e\n   \u003cul\u003e\n       \u003c!-- BEGIN: ITEMS --\u003e\n       \u003cli\u003e{ITEM.name} - ${ITEM.price}\u003c/li\u003e\n       \u003c!-- END: ITEMS --\u003e\n   \u003c/ul\u003e\n   \u003c!-- END: MAIN --\u003e\n```\nPHP:\n```\n   $xtpl-\u003eassign('ITEMS', [\n       ['name' =\u003e 'Book', 'price' =\u003e 15],\n       ['name' =\u003e 'Pen', 'price' =\u003e 2]\n   ]);\n   $xtpl-\u003eparse('MAIN.ITEMS');\n   $xtpl-\u003eparse('MAIN');\n```\nOutput:\n```\n   \u003cul\u003e\n       \u003cli\u003eBook - $15\u003c/li\u003e\n       \u003cli\u003ePen - $2\u003c/li\u003e\n   \u003c/ul\u003e\n```\n### FOR Loops\n\n   Use `\u003c!-- FOR {VALUE} IN {ARRAY} --\u003e` to iterate over array values, or `\u003c!-- FOR {KEY}, {VALUE} IN {ARRAY} --\u003e` to access both keys and values.\n\n#### Values Only\n\nExample:\n  ``` \n   \u003c!-- FOR {VALUE} IN {MY_ARRAY} --\u003e\n   \u003cp\u003eItem: {VALUE}\u003c/p\u003e\n   \u003c!-- ENDFOR --\u003e\n```\nPHP:\n```\n   $xtpl-\u003eassign('MY_ARRAY', ['Apple', 'Banana', 'Orange']);\n   $xtpl-\u003eparse('MAIN');\n```\nOutput:\n```\n   \u003cp\u003eItem: Apple\u003c/p\u003e\n   \u003cp\u003eItem: Banana\u003c/p\u003e\n   \u003cp\u003eItem: Orange\u003c/p\u003e\n```\n#### Keys and Values\n\nExample:\n  ``` \n   \u003c!-- FOR {KEY}, {VALUE} IN {MY_ARRAY} --\u003e\n   \u003cp\u003e{KEY}: {VALUE}\u003c/p\u003e\n   \u003c!-- ENDFOR --\u003e\n```\nPHP:\n```\n   $xtpl-\u003eassign('MY_ARRAY', ['a' =\u003e 'Apple', 'b' =\u003e 'Banana', 'c' =\u003e 'Orange']);\n   $xtpl-\u003eparse('MAIN');\n```\nOutput:\n```\n   \u003cp\u003ea: Apple\u003c/p\u003e\n   \u003cp\u003eb: Banana\u003c/p\u003e\n   \u003cp\u003ec: Orange\u003c/p\u003e\n ```       \n\nCallback Functions\n------------------\n\nAdd modifiers using `|`:\n```\n*   `{VAR|func}` — Applies the function `func` to `VAR`.\n*   `{VAR|func($this, arg)}` — Passes arguments.\n```\nExample:\n```\n    \u003cp\u003eLast login: {LAST_LOGIN|strtotime|date('Y-m-d', $this)}\u003c/p\u003e\n```        \n\nPHP:\n```\n    $xtpl-\u003eassign('LAST_LOGIN', '2025-03-07 12:00:00');\n ```       \n\nOutput:\n```\n    \u003cp\u003eLast login: 2025-03-07\u003c/p\u003e\n  ```      \n\nError Handling\n--------------\n\nDivision by zero (`/`, `%`) returns messages: `\"Division by zero\"`, `\"Modulo by zero\"`. Unknown operators throw an `\"Unknown operator\"` exception.\n\nExample:\n```\n    \u003cp\u003e{NUM / ZERO}\u003c/p\u003e\n```        \n\nOutput:\n```\n    \u003cp\u003eDivision by zero\u003c/p\u003e\n```        \n\nFor comprehensive error handling, add a `try-catch` block in `XtplVar::evaluate()`.\n\nPerformance Optimization\n------------------------\n\n*   **Caching**: Templates are parsed once and stored in memory.\n*   **Lazy Loading**: Variables are evaluated only when `parse()` is called.\n*   **Tip**: Minimize nested blocks and complex expressions for large datasets.\n\nHistory\n-------\n\n*   **v1.2.0**: Add callback function filtering to XTemplate. Add XTemplate::configure() for global settings initialization\n*   **v1.1.0**: Fixed `%` operator support and improved error handling.\n*   **v1.0.0 (2025-03-07)**: Initial release with support for blocks, variables, arithmetic, conditions, and loops.\n\n\nLicense\n-------\n\nThe project is licensed under the [BSD 3-Clause License](LICENSE). You are free to use, modify, and distribute the code provided the license terms are followed.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsedteam%2Fxtemplatese","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsedteam%2Fxtemplatese","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsedteam%2Fxtemplatese/lists"}