Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Formatter Laravel Package

phug/formatter

A formatting extension for Phug, the PHP Pug template engine. It pretty-prints and normalizes Pug source with configurable options, helping keep templates readable and consistent in Laravel and PHP projects.

View on GitHub
Deep Wiki
Context7

Getting Started

phug/formatter is the compile-time backend of the Phug stack (Pug/Jade for PHP). It is not a standalone HTML pretty-printer: it takes the AST produced by phug/parser (node classes live in phug/ast) and emits the PHP template code that the renderer later executes. Everything that determines what a tag actually looks like in the compiled file — attribute merging, boolean-attribute collapsing, escaping, self-closing rules, and indentation — lives here. The 2 stars / 0 dependents numbers simply reflect that nobody requires it directly; it arrives transitively through phug/phug.

Install the stack, not the leaf:

composer require phug/phug     # pulls formatter + ast + parser + compiler + lexer + renderer
# only if you are building a custom pipeline:
composer require phug/formatter

Read these four places first, in order:

Path Why
src/Phug/Formatter.php Entry point, option handling, format registry
src/Phug/Formatter/Format/ One class per node kind (TagFormat, AttributeFormat, TextFormat, …)
src/Phug/Formatter/Element/ Intermediate elements the formats consume
src/Phug/Formatter/Extension/ The sanctioned way to hook in without forking

The first thing most developers ever do with this package is flip pretty:

$renderer = new \Phug\Renderer([
    'pretty'    => true,
    'cache_dir' => __DIR__.'/cache',
]);

echo $renderer->render('div.card: p Hello');

Then set pretty => false, re-render, and diff. Read the generated file in cache_dir side by side with the diff — that is the fastest way to build a mental model of what the formatter is responsible for.

Method names below track the 1.x line. The package is small; if a call is missing in your version, grep for it in src/ before assuming the approach is wrong.

Implementation Patterns

Configure through the renderer, never by hand-instantiating the formatter. The compiler builds it internally and passes options down. Injecting your own is possible ($compiler->setFormatter(...) or the formatter option) but you inherit the wiring — only do it when you need a subclass or extra extensions.

Two-stage debugging. Stop between stages to localise bugs:

$ast  = $renderer->getCompiler()->getParser()->parse($pug);  // structure wrong? formatter is innocent
$php  = $renderer->getCompiler()->compile($pug);             // bad PHP here? it is the formatter

If the PHP looks right but the page is wrong, you are chasing a compiler/renderer bug.

Customising output: extend a Format, register it for an Element. This is the core extension pattern and the reason the package is split into Format and Element namespaces.

use Phug\Formatter\Format\TagFormat;
use Phug\Formatter\Element\TagElement;

class VoidTagXmlFormat extends TagFormat
{
    // open the parent first: the hook may be handleTag(), __invoke(), or a trait method
    protected function handleTag(TagElement $element)
    {
        $code = parent::handleTag($element);

        // post-process the generated PHP string, e.g. force <br /> instead of <br>
        return $code;
    }
}

$formatter->setFormat(TagElement::class, VoidTagXmlFormat::class);

Prefer a Formatter extension over a global subclass. Extensions are composable and are how the built-in attributes module plugs in. Mirror any class in src/Phug/Formatter/Extension/ — same getOptions() / format registration shape — then attach it via the renderer's addExtension(). This keeps you upgrade-safe.

Attribute semantics are the highest-traffic customisation. class accepts arrays and merges with static classes; null/false values drop the attribute; true collapses to a boolean attribute; &attributes($array) splats and lets later values win. If your markup differs from expectation, fix the attribute element/format, not the templates.

Escaping is decided here, not at runtime. #{...} vs !{...} and the pattern / pattern_escape options control the echo statement the formatter writes. When output is double-escaped or raw when it shouldn't be, look at those options before touching template code.

Test compiled output, not rendered output. Golden-file tests over compile() catch formatter regressions precisely and keep failures readable.

Gotchas and Tips

  • Lock the whole Phug family together. phug/ast, phug/parser, phug/compiler, and phug/formatter move in lockstep and share internal element contracts. Require phug/phug:^1.x and let Composer co-install; never mix major versions.
  • Cache invalidation is on you. Changing pretty or any formatter option does not invalidate previously compiled templates in cache_dir. Clear it (or the framework's view cache) after every option change or upgrade — this accounts for a large share of "the option does nothing" reports.
  • pretty mangles inline content. Newlines get inserted between inline elements and around text, which visibly breaks <pre>, <textarea>, and a > span layouts. Keep pretty off in production and test with your real templates, not a hello-world.
  • Indentation characters. Output indentation derives from the formatter options, and the pug-source indentation keys (indent_char, indent_size) are a separate concern. grep -n indent src/Phug/Formatter.php to confirm the exact key for your version before filing a bug.
  • &attributes ordering surprises. Merge order is "later wins", which means a splat placed before an explicit attribute will not override it. Reorder, don't patch the formatter.
  • Debug via the compiled PHP. Dump the file from cache_dir; if it reads correctly, your problem is downstream. Re-compile after edits — stale cache will lie to you.
  • Extension points, in order of preference: options → extensions → events (see src/Phug/Formatter/Event/ for the formatting/stringify hooks) → subclass a Format → vendor patch.
  • This is not a general HTML formatter. Feeding arbitrary HTML or Markdown through it is a category error; it only understands Pug AST nodes.
  • Two stars means you are the QA. Pin exact versions in composer.lock, wrap every customisation in regression tests, and prefer composition (extensions, event hooks) over forking so you can take upstream fixes.
  • MIT licensed — forking and shipping a patched copy is fine; preserve the copyright notice.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels