PHPackages                             cseufert/hamle - 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. [Templating &amp; Views](/categories/templating)
4. /
5. cseufert/hamle

ActiveLibrary[Templating &amp; Views](/categories/templating)

cseufert/hamle
==============

A PHP template engine. HAMLE was inspired by HAML/Jade, however involves less typing, and does not allow php code in a template, but does have logic and function calls.

v3.0.2(2y ago)26.9k↓50%[1 issues](https://github.com/cseufert/hamle/issues)MITPHPPHP &gt;=8.0CI failing

Since Feb 20Pushed 5mo ago2 watchersCompare

[ Source](https://github.com/cseufert/hamle)[ Packagist](https://packagist.org/packages/cseufert/hamle)[ Docs](https://github.com/cseufert/hamle)[ RSS](/packages/cseufert-hamle/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (3)Versions (29)Used By (0)

HAMLE
=====

[](#hamle)

[![Build Status](https://camo.githubusercontent.com/2767119cd67f7a5aa40d2ec639d1efcb5f97a70583def739e8645072312f666d/68747470733a2f2f7472617669732d63692e6f72672f63736575666572742f68616d6c652e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/cseufert/hamle)[![codecov.io](https://camo.githubusercontent.com/7374dfe0a733ddfe61a11cf0c3ad3f07adbd35b93229c286d08e39fe9b790081/687474703a2f2f636f6465636f762e696f2f6769746875622f63736575666572742f68616d6c652f636f7665726167652e7376673f6272616e63683d6d6173746572)](http://codecov.io/github/cseufert/hamle?branch=master)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/784f795bc02645550003f7f93f94f8780d276a2792fd7d641830b591be1a6122/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f63736575666572742f68616d6c652f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/cseufert/hamle/?branch=master)[![Maintainability](https://camo.githubusercontent.com/662148f2e4be24765f0be2ab7e7d0f8849ee4b9be9ee887d0ae9b248f43902db/68747470733a2f2f6170692e636f6465636c696d6174652e636f6d2f76312f6261646765732f34343436643634393766633235383337326630312f6d61696e7461696e6162696c697479)](https://codeclimate.com/github/cseufert/hamle/maintainability)

Requires PHP &gt;= 8.1

### Installation via Composer

[](#installation-via-composer)

```
composer require cseufert/hamle dev-master
```

- [Example Implementation](doc/example.md)

### Enhanced Version of HAML - HAMLE

[](#enhanced-version-of-haml---hamle)

This haml port uses slightly different syntax to the haml standard format. The main idea here is to reduce the number of symbols that are typed. The second issue this port is attempting to address, is to remove native code from the template. The idea here being that your template could be served as html from the server, however where supported, it could be rendered by javascript, with a small json request to retreive the data to fill the template with. The main focus for hamle is not on markup, but on page/document structure, so inline tags are not a consideration at this stage. The focus is on clean, readable markup

- CSS Like Class and ID, with or without element (eg `.myclass`, `P.quote`, `A#home`, `#content.cols.two` )
    - DIVs are assumed if no html tag is specified
    - There is no specific order to the id and class, however the name, if specified must be first
    - Multiple IDs (#one#two) will not be recognized, only one will be used
    - Usage #1 `.one Text` becomes `Text`
    - Usage #2 `span.two Foo` becomes `Foo`
    - Usage #3 `#my.mine.ours` becomes ``
- Indented Structure (Python like), increased indents means inside parent element, decreased implies closing tag

```
html
  body
    div#content
      a[href=/] Home

```

becomes

```

      Home

```

- HTML tags just go straigt in, no symbol required (eg `DIV`, `P`, `A`, etc)
    - Tag attributes are specified in square brackets as url encoded string
    - Escape &amp; with \\&amp;, \] with \\\], etc
    - Usage #1 `a[href=/] Home` outputs `Home`
    - Usage #2 `.button[data-size=$id&class=$tags]` if $id is 10 and tags = 'Ten Submit' output would be ``
    - Usage #3 `a[data-alt=Button \[1\&2\]] Hi` becomes `Hi`
- All variable substitution is PHP like, starts with $ (`$title`, `$text`, `{$[-1]->title}`, etc)
    - Alternative Syntax when in html editor `{$[1]-!title}` or `{$(page.home)-!title}`
    - `{$...}` over `$...` are required when inside a filter block, or accessing a property.
    - Scope History
        - `$[0]` = current model/controller that is in scope
            - Usage #1 `|with $[-1]` - Switch back to last scope
            - Usage #2 `{$[1]->title}` - read value `$title` from initial scope
        - `$[-1]` = Last Scope ; Array array of scopes `$[1]` first scope, `$[-2]` second last scope
    - Named Scopes **(new)**
        - Select item and assign name rather than numeric scope `|with $(page.footer) as footer`
        - Now to use this or its variables, use `$[footer]`
        - Loop through footers with `|each $[footer]`
        - Access HTML attribute on footer `{$[footer]->html}`
    - jQuery like magic `$` function
        - `$({}{@}{#}{.}{^}{:{-}})`
            - `` is a type that hamleSetup-&gt;modelType($type) can find
            - `` is an arbitary id that determines a group type, eg. for differentiating gallery image from header image
            - `` is a unique id, either combined with a type, or globally unique
            - `` are user defined tags that can be used to help find find data
            - `` field to sort on, by default ascending, prefix with - for descending, nothing after for random. If you are wanting to sort by multiple fields, eg sort DESC, and title ASC, then you would do `^-sort^title`.
            - `` Limit results to n
            - `` Number of results to skip before return
            - The only required fields are `` or ``, depending on implementation of modelFind
        - `$(#1024)` opens id = 1024
        - `$(#mine)` opens object with id/alias = mine
        - `$(page#3)` opens page type with id = 3
        - `$(cat)` opens a list of all category objects
        - `$(product.onsale)` opens a list of all products with onsale tag
        - `$(cart#summary)` open summary item from cart
        - `$(#mainmenu > page,cat)` returns list of all children of id = mainmenu that are type pages, and cats
        - `$( > photo, image)` return list of all photos and images who are children of current scope
        - `$( < cat)` returns all parents of type category within the current scope
        - `$(page:1)` return first 1 page from pages
        - `$( > page,cat:3)` return 3 pages or cats (in total) that are children of whats in scope
        - `$(news^postdate)` returns all news posts sorted ascending by postdate
        - `$(news^-postdate)` returns all news posts sorted descending by postdate
        - `$(news^)` returns all news posts sorted in random order
        - `$(news^-postdate^title)` returns all news posts sorted by date (DESC), then title(ASC)
        - `$(link:5-10)` returns links starting at #5 through 10
        - `$(news:4)` return 4 news posts
        - `$(product.featured:4^)` Return 4 randomly selected products with featured tag
        - `$(post:4^postdate)` return first 4 blog posts ordered by postdate
        - `$(post^-postdate:1)` return most recent blog post
- Iterateable model/controller list can use special methods
    - `|with $(#mainmenu > page)` - changes M/C scope to pages under mainmenu, if no results skips section
    - `|each` - iterates through each object in the current scope (set by |with)
    - `|each $(#social > icons)` - iterate through children icons from id = social
    - `|include "block/$type/list.hamle"` - bring another hamle file into the doc, with the current M/C scope
        - Variable substitution is active within the filename
    - `|if $id equals $(view)->id` - include section if this id is the view id
        - `if $title equals a`
        - `if $id notequal 54`
        - `if $tags has sale` - has sale in array
        - `if $title starts Hi`
        - `if $title ends s`
        - `if $title contains Hi` - Contains the string Hi
        - `if $price greater 10`
        - `if $price less 10`
    - `|else` - else for `|with`, and `|if`
    - Future Ideas
        - `|page , ` - eg `|page results,16 $(#gallery > photo)`
            - Special Link Targets: `a!firstpage`; `a!prevpage`; `a!nextpage`; `a!lastpage`;
            - Special Page Features: Page `div!thispage` of `div!pagecount`; `div!pagelinks`;
        - `|recurse $( > menu,page) #3` Recurse up to 3 levels deep using expression provided
        - `if $price less 10 OR $price greater 20`
        - `|unless $title` - if not shortcut, show block if there is no title
        - `|switch $type` - switch based on $type
            - `|case page` - include section if case matches
            - `|default` - include section if none of the cases matches
        - `|iterateend` - iterate until end of list
            - `|iterate 3` - iterate 3 times
            - eg

```
  / Print a table with 3 column of all the products in the current scope (eg category)
  |with $( > products)
    table
      |iterateend
        tr
          |iterate 3
            td
              a[href=$url] $title
                |with $( > photo)
                  img[src=$url]
          |else
            td

```

- Filters
    - `:filtername` - Use filter named filtername to process section)
    - Usage #1 `:javascript alert('Hi {$(user)->name}');`
    - Usage #2 `:css a {color:{$(site)->linkcolor}}`
    - to use `{$` sequence in css/javascript/etc, you just escape the dollar eg. {$
- Comments
    - `// Comment` - not included in output
    - `/ Comment` - included as HTML comment
- `_ This is just plain text`
    - Plain text, can be easily translated
    - `_` is only required when text is the first thing on a new line
    - To escape $ sign, use $
    - use '\_\_' when you do not want to escape any html special chars (ie. you want to include html within your output.
        - eg `__ ` to print html5 doctype
        - This will also not attempt to parse any variables (eg {$title})
    - use `___` when you want unescape html (include variables) This allows rendering variables that contain html to display as html
- Functions
    - `{$title|strtoupper}` runs strtoupper on models title value
    - `{$amount|format_currency("$", $(#prefs)->places)}` Pass arguments to functions

Example
-------

[](#example)

```
html
  body
    .head
      h1 This is my website
      img[src=/img/$imagename.png]
    .content
      .h2 $title
      |with $(#1012 > text)
        ul#mainmenu
          |each
            li.menuitem
              |if {$[1]->id} = $id
                a.highlight[href=$url] $title
              |else
                a[href=$url] $title
              |with $( > text)
                ul.submenu
                  |each
                    li.menuitem
                      |if {$[1]->id} = $id
                        a.highlight[href=$url] $title
                      |else
                        a[href=$url] $title
      .body
        |if $text
          $text
	    |else
          p Nothing to see here. Page ID=$id is emtpy
      .foot
        ul.socialicons
          |each $(#socialmedia > link)
            li.icon
               a[href=$url&class=$code]
                 img[alt=$title] $->child(“img”)->url
        |include "footer_$type.hamle"
        |if $alias != “home”
          a[href=/] Home
        .powered
          $(site)->poweredby

```

Upgrading to Version 3.x
------------------------

[](#upgrading-to-version-3x)

- Hamle constructor no longer requires a model, it is now passed via output
- Strings are now run in memory with no cache file
- Runtime\\Context replaced Hamle\\Run and encompasses the old Hamle\\Setup methods
- Runtime\\Scope is now a instance, no longer accessed via static methods

###  Health Score

42

—

FairBetter than 90% of packages

Maintenance39

Infrequent updates — may be unmaintained

Popularity24

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity79

Established project with proven stability

 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 ~94 days

Recently: every ~150 days

Total

23

Last Release

161d ago

Major Versions

v1.1.0 → v2.0.0-beta32021-04-06

v2.1.2 → v3.0.02024-04-17

PHP version history (4 changes)v1.0.0PHP &gt;=7.0.0

v2.0.0-beta3PHP &gt;=7.4.0

v2.1.0PHP &gt;=8.0

v2.x-devPHP &gt;=8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/cdaa37da429175a647f4b3851a747f5449d34c8eabbd27b4c14eba2cd48607b0?d=identicon)[cseufert](/maintainers/cseufert)

---

Top Contributors

[![cseufert](https://avatars.githubusercontent.com/u/1734519?v=4)](https://github.com/cseufert "cseufert (492 commits)")

---

Tags

htmlmodeltemplatetemplatingcompiledmarkupFormsjadeHAMLHAMLE

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/cseufert-hamle/health.svg)

```
[![Health](https://phpackages.com/badges/cseufert-hamle/health.svg)](https://phpackages.com/packages/cseufert-hamle)
```

###  Alternatives

[phug/phug

Pug (ex-Jade) facade engine for PHP, HTML template engine structured by indentation

67292.2k13](/packages/phug-phug)[pug-php/pug

HAML-like template engine for PHP

393383.2k54](/packages/pug-php-pug)[talesoft/tale-jade

A clean, lightweight and easy-to-use templating engine for PHP based on Jade/Pug

8919.3k5](/packages/talesoft-tale-jade)[shoot/shoot

Shoot aims to make providing data to your templates more manageable

40229.9k2](/packages/shoot-shoot)[talesoft/tale-pug

A clean, lightweight and easy-to-use templating engine for PHP based on Pug, formerly Jade

319.4k3](/packages/talesoft-tale-pug)[lavender/lavender

jade-esque templates for PHP 5.3

175.6k1](/packages/lavender-lavender)

PHPackages © 2026

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