{"id":15292249,"url":"https://github.com/goodbye-html/goodbye-html","last_synced_at":"2025-04-13T11:11:33.569Z","repository":{"id":56203768,"uuid":"206966291","full_name":"goodbye-html/goodbye-html","owner":"goodbye-html","description":"A very simple package for separating PHP logic from HTML or any other text. It allows you to insert variables, if/else statements and ternary operators into any text file and dynamically get parsed content of this file.","archived":false,"fork":false,"pushed_at":"2024-11-01T17:25:21.000Z","size":389,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-27T02:21:36.394Z","etag":null,"topics":["html","html-files","parser","php","php-string","shortcode","statements","wordpress"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/goodbye-html.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2019-09-07T12:39:00.000Z","updated_at":"2024-11-01T13:53:51.000Z","dependencies_parsed_at":"2024-11-01T14:33:18.224Z","dependency_job_id":"17406059-f0af-4fb8-a283-cb990466ab13","html_url":"https://github.com/goodbye-html/goodbye-html","commit_stats":{"total_commits":115,"total_committers":2,"mean_commits":57.5,"dds":"0.060869565217391286","last_synced_commit":"ff416ce3d73781e61fd66381e388bdc7aed32801"},"previous_names":["goodbye-html/goodbye-html","serhiicho/goodbye-html"],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goodbye-html%2Fgoodbye-html","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goodbye-html%2Fgoodbye-html/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goodbye-html%2Fgoodbye-html/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goodbye-html%2Fgoodbye-html/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/goodbye-html","download_url":"https://codeload.github.com/goodbye-html/goodbye-html/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248703198,"owners_count":21148118,"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":["html","html-files","parser","php","php-string","shortcode","statements","wordpress"],"created_at":"2024-09-30T16:17:05.095Z","updated_at":"2025-04-13T11:11:33.301Z","avatar_url":"https://github.com/goodbye-html.png","language":"PHP","readme":"# Goodbye HTML\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/goodbye-html/goodbye-html/actions/workflows/php.yml\"\u003e\u003cimg src=\"https://github.com/goodbye-html/goodbye-html/actions/workflows/php.yml/badge.svg?branch=main\" alt=\"Goodbye HTML\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://packagist.org/packages/serhii/goodbye-html\"\u003e\u003cimg src=\"https://poser.pugx.org/serhii/goodbye-html/d/total.svg\" alt=\"Total Downloads\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://packagist.org/packages/serhii/goodbye-html\"\u003e\u003cimg src=\"https://poser.pugx.org/serhii/goodbye-html/v/stable.svg\" alt=\"Latest Stable Version\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/goobye-html/goodbye-html/blob/main/LICENSE.md\"\u003e\u003cimg alt=\"GitHub\" src=\"https://img.shields.io/github/license/goobye-html/goodbye-html\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nA very simple package for separating PHP logic from HTML or any other text. It allows you to insert **variables**, **if/elseif/else statements**, **loops** and **ternary operators** into any text file and dynamically get parsed content of this file.\n\n- [📝 Release notes](https://github.com/goobye-html/goodbye-html/blob/main/docs/CHANGELOG.md)\n- [✏️ BNF grammar](https://github.com/goobye-html/goodbye-html/blob/main/docs/goodbye-html.bnf)\n\n## Supported PHP versions\n- ✅ 8.2\n- ✅ 8.3\n\n## What is it for?\nThis package is useful when you need to separate PHP logic from HTML or any other text. For example if you need to send an email with some dynamic content, you can create a template file with HTML and insert variables, if/elseif/else statements, loops and ternary operators into it. Then you can pass this file to the parser and get parsed content of this file as a string. Then you can use this string as a content of your email.\n\n## What is it not for?\nThis package is not for creating a full-featured template engine. It's just a simple parser that allows you to insert some PHP logic into any text file. It's not for creating a full-featured template engine like [Twig](https://twig.symfony.com/), [Blade](https://laravel.com/docs/8.x/blade) or [Latte](https://latte.nette.org/en/). If you need a full-featured template engine, you should use one of the mentioned above.\n\n## What Goodbye HTML has?\n- [x] Variables\n    - [x] Assigning variables\n    - [x] Using variables\n    - [x] Printing variables\n- [x] Comparison operators\n    - [x] Equal (==)\n    - [x] Not equal (!=)\n    - [x] Strong equal (===)\n    - [x] Strong not equal (!==)\n    - [x] Greater than (\u003e)\n    - [x] Less than (\u003c)\n    - [x] Greater than or equal (\u003e=)\n    - [x] Less than or equal (\u003c=)\n- [x] If/Else-If/Else statements\n- [x] Expressions\n  - Ternary Expressions (true ? 'yes' : 'no')\n  - Grouped Expressions ((3 + 4) * 5)\n- [x] Loops\n- [x] Prefix operators\n    - Negation operator (!)\n    - Minus operator (-)\n- [x] String concatenation\n- [x] Math operations\n    - Addition\n    - Subtraction\n    - Multiplication\n    - Division\n    - Modulus\n\n## Usage\n\n```php\nuse Serhii\\GoodbyeHtml\\Parser;\n\n$variables = [\n    'title' =\u003e 'Title of the document',\n    'uses_php_3_years' =\u003e true,\n    'show_container' =\u003e false,\n];\n\n// Absolute file path to a text file\n$file_path = __DIR__ . '/hello.html';\n\n$parser = new Parser($file_path, $variables);\n\n// this will parsed content of hello.html file\necho $parser-\u003eparseHtml();\n```\n\nHTML file content with 2 php variables before parsing it\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n\u003chead\u003e\n    \u003cmeta charset=\"UTF-8\"\u003e\n    \u003ctitle\u003e{{ $title }}\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody class=\"{{ $show_container ? 'container' : '' }}\"\u003e\n    \u003cnav\u003e\n        \u003cul\u003e\n            {{ loop 1, 3 }}\n                \u003cli\u003e\u003ca href=\"#\"\u003eLink - {{ $index }}\u003c/a\u003e\u003c/li\u003e\n            {{ end }}\n        \u003c/ul\u003e\n    \u003c/nav\u003e\n\n    {{ if $uses_php_3_years }}\n        \u003ch1\u003eI'm not a pro, but it's only a matter of time\u003c/h1\u003e\n    {{ end }}\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\nParsed HTML to a PHP string\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n\u003chead\u003e\n    \u003cmeta charset=\"UTF-8\"\u003e\n    \u003ctitle\u003eTitle of the document\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody class=\"\"\u003e\n    \u003cnav\u003e\n        \u003cul\u003e\n            \n                \u003cli\u003e\u003ca href=\"#\"\u003eLink - 1\u003c/a\u003e\u003c/li\u003e\n            \n                \u003cli\u003e\u003ca href=\"#\"\u003eLink - 2\u003c/a\u003e\u003c/li\u003e\n            \n                \u003cli\u003e\u003ca href=\"#\"\u003eLink - 3\u003c/a\u003e\u003c/li\u003e\n            \n        \u003c/ul\u003e\n    \u003c/nav\u003e\n\n    \n        \u003ch1\u003eI'm not a pro, but it's only a matter of time\u003c/h1\u003e\n    \n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n### Same example but for WordPress shortcode\n\n```php\nuse Serhii\\GoodbyeHtml\\Parser;\n\nadd_shortcode('my_shortcode', 'shortcode_callback');\n\nfunction shortcode_callback() {\n    $parser = new Parser(__DIR__ . '/shortcodes/main.html', [\n        'title' =\u003e 'Title of the document',\n        'uses_php_3_years' =\u003e true,\n        'show_container' =\u003e false,\n    ]);\n    return $parser-\u003eparseHtml();\n}\n```\n\n## Options\n\nThe instance of `Parser` class takes the third argument as a `ParserOption` enum. You can pass it to the constructor of the `Parser` class as a third argument. For now, it has only a single options:\n\n#### `ParserOption::PARSE_TEXT`\nIf you pass this option, the parser, instead of getting the content of the provided file path, will parse the provided string. This option is useful when you want to parse a string instead of a file.\n\n```php\n$parser = new Parser('\u003cdiv\u003e{{ $title }}\u003c/div\u003e', [\n    'title' =\u003e 'Hello world'\n], ParserOption::PARSE_TEXT);\n\n// output: \u003cdiv\u003eHello world\u003c/div\u003e\n```\n\n## Supported types\n\nTypes that you can pass to the parser to include them in the `html/text` file. Note that not all PHP types are supported for know. More types will be added in next releases.\n\n| PHP Type | Value example |\n|----------|---------------|\n| bool     | true          |\n| string   | 'Is title'    |\n| int      | 24            |\n| float    | 3.1415        |\n| null     | null          |\n\n## Supported prefix operators\n\nPrefix operators are used to change the value of the variable. For example if you have a variable `$is_smoking` and you want to check if it's false, you can use `!` prefix operator to change the value of the variable to false. Or if you have a variable `$age` and you want to make it negative, you can use `-` prefix operator to change the value of the variable to negative.\n\n| Prefix name | Prefix value | Example | Supported types for prefix |\n|-------------|--------------|---------|----------------------------|\n| Not         | !            | !true   | all the types              |\n| Minus       | -            | -24     | int, float                 |\n\n## Supported infix operators\n\nInfix operators are used to perform math operations or string concatenation. For example if you have a variable `$age` and you want to add 1 to it, you can use `+` infix operator to add 1 to the variable. Or if you have a variable `$first_name` and you want to concatenate it with `$last_name`, you can use `.` infix operator to concatenate these 2 variables.\n\n| Operator name    | Operator literal | Example            | Supported types for prefix |\n|------------------|------------------|--------------------|----------------------------|\n| Plus             | +                | 3 + 4              | int, float                 |\n| Minus            | -                | 5 - 4              | int, float                 |\n| Multiply         | *                | 3 * 4              | int, float                 |\n| Divide           | /                | 6 / 3              | int, float                 |\n| Modulo           | %                | 5 % 2              | int, float                 |\n| Concatenate      | .                | 'Hello' . ' world' | string                     |\n| Assigning        | =                | {{ $a = 5 }}       | all the types              |\n| Equal            | ==               | 5 == 5             | all the types              |\n| Not equal        | !=               | 5 != 4             | all the types              |\n| Strong equal     | ===              | 5 === 5            | all the types              |\n| Strong not equal | !==              | 5 !== 4            | all the types              |\n| Greater than     | \u003e                | 5 \u003e 4              | int, float                 |\n| Less than        | \u003c                | 5 \u003c 4              | int, float                 |\n| Greater or equal | \u003e=               | 5 \u003e= 4             | int, float                 |\n| Less or equal    | \u003c=               | 5 \u003c= 4             | int, float                 |\n\n## All the available syntax in html/text file\n\n#### Variable\n\n```html\n\u003c!-- Inside html tags --\u003e\n\u003cdiv\u003e{{ $guest_name }}\u003c/div\u003e\n```\n\n```html\n\u003c!-- Inside attributes --\u003e\n\u003ch2 class=\"{{ $styles }}\"\u003eThe title of the page\u003c/h2\u003e\n```\n\n#### If statements\n\n```html\n\u003c!-- Block syntax --\u003e\n\u003csection\u003e\n    {{ if true }}\n        \u003ch1\u003ePHP is awesome programming language\u003c/h1\u003e\n    {{ end }}\n\u003c/section\u003e\n```\n\n```html\n\u003c!-- Inline syntax --\u003e\n\u003ch1 class=\"{{if $show_container}}container{{end}}\"\u003e\n    This package is cool\n\u003c/h1\u003e\n```\n\n#### If/Else statements\n\n```html\n\u003c!-- Block syntax --\u003e\n\u003csection\u003e\n    {{ if $likes_bread }}\n        \u003ch1\u003eI like bread\u003c/h1\u003e\n    {{ else }}\n        \u003ch1\u003eI don't really like bread\u003c/h1\u003e\n    {{ end }}\n\u003c/section\u003e\n```\n\n```html\n\u003c!-- Inline syntax --\u003e\n\u003csection\u003e\n    \u003ch1\u003e{{ if $late }}It's late{{ else }}It's not late{{ end }}\u003c/h1\u003e\n\u003c/section\u003e\n```\n\n#### If/Else-If/Else statements\n\n\u003e Similar to PHP, you can write `elseif` or `else if` in the same way.\n\n```html\n\u003c!-- Block syntax --\u003e\n\u003csection\u003e\n    {{ if $likes_bread }}\n        \u003ch1\u003eI like bread\u003c/h1\u003e\n    {{ else if $likes_cake }}\n        \u003ch1\u003eI like cake\u003c/h1\u003e\n    {{ elseif $likes_pizza }}\n        \u003ch1\u003eI like pizza\u003c/h1\u003e\n    {{ else }}\n        \u003ch1\u003eI don't really like anything\u003c/h1\u003e\n    {{ end }}\n\u003c/section\u003e\n```\n\n```html\n\u003c!-- Inline syntax --\u003e\n\u003csection\u003e\n    \u003ch1\u003eI like {{ if $likes_bread }}bread{{ else if $likes_cake }}cake{{ else }}just water{{ end }}\u003c/h1\u003e\n\u003c/section\u003e\n```\n\n#### Ternary operator\n\n[Ternary operator](https://en.wikipedia.org/wiki/%3F:) is commonly referred to as the conditional operator, inline if/else. An expression `a ? b : c` evaluates to `b` if the value of `a` is true, and otherwise to `c`. One can read it aloud as \"if a then b otherwise c\".\n\n```html\n\u003c!-- Inside html attributes --\u003e\n\u003csection class=\"{{ $wrap ? 'container' : '' }}\"\u003e\n    \u003ch1\u003eTitle\u003c/h1\u003e\n\u003c/section\u003e\n```\n\n```html\n\u003c!-- With strings --\u003e\n\u003csection class=\"container\"\u003e\n    {{ 23 === 23 ? '\u003ch1\u003eMain title\u003c/h1\u003e' : '\u003ch2\u003eSecondary\u003c/h2\u003e' }}\n\u003c/section\u003e\n```\n\n```html\n\u003c!-- With variables --\u003e\n\u003csection class=\"container\"\u003e\n    {{ $has_apple ? $with_apple : $without_apple }}\n\u003c/section\u003e\n```\n\n#### Loops\n\nLoop takes 2 integer arguments. The first argument is from what number start looping, and the second argument is where to stop. For example if you start from 1 to 4, it's going to result 4 repeated blocks. Inside each loop you can use $index variable that is going to have a value of current iteration number.\n\n```html\n\u003c!-- Block syntax --\u003e\n\u003cdiv\u003e\n    {{ loop 0, 5 }}\n        \u003ch1\u003eHello world {{ $index }}\u003c/h1\u003e\n    {{ end }}\n\u003c/div\u003e\n```\n\n```html\n\u003c!-- Inline syntax --\u003e\n\u003cdiv\u003e\n    \u003ch1 class=\"{{ loop 1, 4 }}class-{{$index}} {{ end }}\"\u003e\u003c/h1\u003e\n\u003c/div\u003e\n```\n\n```html\n\u003c!-- With integer variables --\u003e\n\u003cdiv\u003e\n    {{ loop $from, $to }}\n        \u003ch1\u003eHello world {{ $index }}\u003c/h1\u003e\n    {{ end }}\n\u003c/div\u003e\n```\n\n#### Assigning statements\n\nYou can assign values to variables inside your text files using curly braces. For example if you want to assign value 5 to variable `$a`, you can do it like this `{{ $a = 5 }}`. You can also use prefix operators to change the value of the variable. For example if you want to assign value false to variable `$is_smoking`, you can do it like this `{{ $is_smoking = !true }}`.\n\n```html\n\u003cdiv\u003e{{ $age = 33 }}\u003c/div\u003e\n```\n\n## Getting started\n\n```bash\n$ composer require serhii/goodbye-html\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoodbye-html%2Fgoodbye-html","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgoodbye-html%2Fgoodbye-html","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoodbye-html%2Fgoodbye-html/lists"}