PHPackages                             serhii/goodbye-html - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Parsing &amp; Serialization](/categories/parsing)
4. /
5. serhii/goodbye-html

ActiveLibrary[Parsing &amp; Serialization](/categories/parsing)

serhii/goodbye-html
===================

Simple html parser for parsing html files into a string

2.11.0(5mo ago)7386[1 issues](https://github.com/goodbye-html/goodbye-html/issues)[1 PRs](https://github.com/goodbye-html/goodbye-html/pulls)MITPHPPHP ^8.2CI failing

Since Sep 24Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/goodbye-html/goodbye-html)[ Packagist](https://packagist.org/packages/serhii/goodbye-html)[ Docs](https://github.com/goodbye-html/goodbye-html)[ RSS](/packages/serhii-goodbye-html/feed)WikiDiscussions master Synced 3d ago

READMEChangelog (10)Dependencies (5)Versions (32)Used By (0)

Goodbye HTML
============

[](#goodbye-html)

 [![Goodbye HTML](https://github.com/goodbye-html/goodbye-html/actions/workflows/php.yml/badge.svg?branch=master)](https://github.com/goodbye-html/goodbye-html/actions/workflows/php.yml) [![Total Downloads](https://camo.githubusercontent.com/8e63907f5312f37bdbc30bde0c7b98b1f058ca342f55e07400b72a2330fb4163/68747470733a2f2f706f7365722e707567782e6f72672f7365726869692f676f6f646279652d68746d6c2f642f746f74616c2e737667)](https://packagist.org/packages/serhii/goodbye-html) [![Latest Stable Version](https://camo.githubusercontent.com/1d75c722e63d3186ec6465ad267ce41d4df8670ab45929a7ecd2f49a35872dce/68747470733a2f2f706f7365722e707567782e6f72672f7365726869692f676f6f646279652d68746d6c2f762f737461626c652e737667)](https://packagist.org/packages/serhii/goodbye-html) [![GitHub](https://camo.githubusercontent.com/661e6a7471c13c2d12aa622241950458325322ba1952c4e8f236f21fe7c1c30f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f676f6f646279652d68746d6c2f676f6f646279652d68746d6c)](https://github.com/goodbye-html/goodbye-html/blob/master/LICENSE.md)

A 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.

- [📝 Release notes](https://github.com/goodbye-html/goodbye-html/blob/master/docs/CHANGELOG.md)
- [✏️ BNF grammar](https://github.com/goodbye-html/goodbye-html/blob/master/docs/goodbye-html.bnf)

Supported PHP versions
----------------------

[](#supported-php-versions)

- ✅ 8.2
- ✅ 8.3
- ✅ 8.4
- ✅ 8.5

What is it for?
---------------

[](#what-is-it-for)

This 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.

What is it not for?
-------------------

[](#what-is-it-not-for)

This 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.

What Goodbye HTML has?
----------------------

[](#what-goodbye-html-has)

- Variables
    - Assigning variables
    - Using variables
    - Printing variables
- Comparison operators
    - Equal (==)
    - Not equal (!=)
    - Strong equal (===)
    - Strong not equal (!==)
    - Greater than (&gt;)
    - Less than (&lt;)
    - Greater than or equal (&gt;=)
    - Less than or equal (&lt;=)
- If/Else-If/Else statements
- Expressions
    - Ternary Expressions (true ? 'yes' : 'no')
    - Grouped Expressions ((3 + 4) \* 5)
- Loops
- Prefix operators
    - Negation operator (!)
    - Minus operator (-)
- String concatenation
- Math operations
    - Addition
    - Subtraction
    - Multiplication
    - Division
    - Modulus

Usage
-----

[](#usage)

```
use Serhii\GoodbyeHtml\Parser;

$variables = [
    'title' => 'Title of the document',
    'uses_php_3_years' => true,
    'show_container' => false,
];

// Absolute file path to a text file
$file_path = __DIR__ . '/hello.html';

$parser = new Parser($file_path, $variables);

// this will parsed content of hello.html file
echo $parser->parseHtml();
```

HTML file content with 2 php variables before parsing it

```
>

    {{ $title }}

            {{ loop 1, 3 }}
                Link - {{ $index }}
            {{ end }}

    {{ if $uses_php_3_years }}
        I'm not a pro, but it's only a matter of time
    {{ end }}

```

Parsed HTML to a PHP string

```
>

    Title of the document

                Link - 1

                Link - 2

                Link - 3

        I'm not a pro, but it's only a matter of time

```

### Same example but for WordPress shortcode

[](#same-example-but-for-wordpress-shortcode)

```
use Serhii\GoodbyeHtml\Parser;

add_shortcode('my_shortcode', 'shortcode_callback');

function shortcode_callback() {
    $parser = new Parser(__DIR__ . '/shortcodes/main.html', [
        'title' => 'Title of the document',
        'uses_php_3_years' => true,
        'show_container' => false,
    ]);
    return $parser->parseHtml();
}
```

Options
-------

[](#options)

The 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:

#### `ParserOption::PARSE_TEXT`

[](#parseroptionparse_text)

If 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.

```
$parser = new Parser('{{ $title }}', [
    'title' => 'Hello world'
], ParserOption::PARSE_TEXT);

// output: Hello world
```

Supported types
---------------

[](#supported-types)

Types 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.

PHP TypeValue examplebooltruestring'Is title'int24float3.1415nullnullSupported prefix operators
--------------------------

[](#supported-prefix-operators)

Prefix 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.

Prefix namePrefix valueExampleSupported types for prefixNot!!trueall the typesMinus--24int, floatSupported infix operators
-------------------------

[](#supported-infix-operators)

Infix 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.

Operator nameOperator literalExampleSupported types for prefixPlus+3 + 4int, floatMinus-5 - 4int, floatMultiply\*3 \* 4int, floatDivide/6 / 3int, floatModulo%5 % 2int, floatConcatenate.'Hello' . ' world'stringAssigning={{ $a = 5 }}all the typesEqual==5 == 5all the typesNot equal!=5 != 4all the typesStrong equal===5 === 5all the typesStrong not equal!==5 !== 4all the typesGreater than&gt;5 &gt; 4int, floatLess than&lt;5 &lt; 4int, floatGreater or equal&gt;=5 &gt;= 4int, floatLess or equal&lt;=5 &lt;= 4int, floatAll the available syntax in html/text file
------------------------------------------

[](#all-the-available-syntax-in-htmltext-file)

#### Variable

[](#variable)

```

{{ $guest_name }}
```

```

The title of the page
```

#### If statements

[](#if-statements)

```

    {{ if true }}
        PHP is awesome programming language
    {{ end }}

```

```

    This package is cool

```

#### If/Else statements

[](#ifelse-statements)

```

    {{ if $likes_bread }}
        I like bread
    {{ else }}
        I don't really like bread
    {{ end }}

```

```

    {{ if $late }}It's late{{ else }}It's not late{{ end }}

```

#### If/Else-If/Else statements

[](#ifelse-ifelse-statements)

> Similar to PHP, you can write `elseif` or `else if` in the same way.

```

    {{ if $likes_bread }}
        I like bread
    {{ else if $likes_cake }}
        I like cake
    {{ elseif $likes_pizza }}
        I like pizza
    {{ else }}
        I don't really like anything
    {{ end }}

```

```

    I like {{ if $likes_bread }}bread{{ else if $likes_cake }}cake{{ else }}just water{{ end }}

```

#### Ternary operator

[](#ternary-operator)

[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".

```

    Title

```

```

    {{ 23 === 23 ? 'Main title' : 'Secondary' }}

```

```

    {{ $has_apple ? $with_apple : $without_apple }}

```

#### Loops

[](#loops)

Loop 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.

```

    {{ loop 0, 5 }}
        Hello world {{ $index }}
    {{ end }}

```

```

```

```

    {{ loop $from, $to }}
        Hello world {{ $index }}
    {{ end }}

```

#### Assigning statements

[](#assigning-statements)

You 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 }}`.

```
{{ $age = 33 }}
```

Getting started
---------------

[](#getting-started)

```
composer require serhii/goodbye-html
```

Contribute
----------

[](#contribute)

### With a Container Engine

[](#with-a-container-engine)

#### Build an Image

[](#build-an-image)

To build an image, navigate to the root of project and run this command.

With Podman:

```
podman-compose build
```

With Docker:

```
docker compose build
```

#### Run the Container

[](#run-the-container)

To run the container, navigate to the root of project and run this command.

With Podman:

```
podman-compose run --rm app
```

With Docker:

```
docker compose run --rm app
```

#### Destroy the Container

[](#destroy-the-container)

You can cleanup after working on a project by destroying things like networks with this command.

With Podman:

```
podman-compose down
```

With Docker:

```
docker compose down
```

###  Health Score

49

—

FairBetter than 95% of packages

Maintenance73

Regular maintenance activity

Popularity17

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity81

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~77 days

Recently: every ~97 days

Total

30

Last Release

169d ago

Major Versions

1.6.3 → 2.02023-11-11

PHP version history (4 changes)v1.0PHP ^7.2

v1.4PHP ^7.1

1.6.1PHP ^7.1|^8.0

2.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/492847fa1c01ef11bfb489695d1d8553d4729f59efce19b34b8ed4b0f3598fae?d=identicon)[SerhiiCho](/maintainers/SerhiiCho)

---

Top Contributors

[![SerhiiCho](https://avatars.githubusercontent.com/u/35465417?v=4)](https://github.com/SerhiiCho "SerhiiCho (488 commits)")

---

Tags

htmlhtml-filesparserphpphp-stringshortcodestatementswordpressparserlibraryhtml

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/serhii-goodbye-html/health.svg)

```
[![Health](https://phpackages.com/badges/serhii-goodbye-html/health.svg)](https://phpackages.com/packages/serhii-goodbye-html)
```

###  Alternatives

[thunderer/shortcode

Advanced shortcode (BBCode) parser and engine for PHP

3892.6M44](/packages/thunderer-shortcode)[dimabdc/php-fast-simple-html-dom-parser

PHP Fast Simple HTML DOM parser.

9352.6k](/packages/dimabdc-php-fast-simple-html-dom-parser)[jbroadway/slimdown

A simple regex-based Markdown parser.

357.7k](/packages/jbroadway-slimdown)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
