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

Xhtml Formatter Laravel Package

machy8/xhtml-formatter

A lightweight PHP/Laravel package for formatting and pretty-printing HTML/XHTML output. Clean up markup, normalize indentation, and produce well-formed, readable documents—ideal for Blade views, emails, and generated content.

View on GitHub
Deep Wiki
Context7

Getting Started

Install via Composer and confirm it resolves on your PHP version before writing any code:

composer require machy8/xhtml-formatter

The package exposes a small formatter API. The first file to open in vendor/machy8/xhtml-formatter is the Formatter class (and the README) — it is the entire public surface, so there is little to discover beyond its constructor options and the format() method. A typical first call looks like this:

use Machy8\XHTMLFormatter\Formatter;

$formatter = new Formatter();
$pretty = $formatter->format('<div><p>Hello</p><p>World</p></div>');

Your first real use case is almost always "make compiled Blade output or a stored HTML snippet readable" — either for debugging rendered views, for diffing HTML in tests, or for pretty-printing stored email/newsletter templates. Start by running it against one of your actual templates and eyeballing the result before trusting it on a whitespace-sensitive page.

Because the package is lightweight and unmaintained since 2017, treat the README/example folder as the source of truth, pin the version in composer.json, and verify it loads under your PHP version immediately. If it fails on PHP 8+, stop here and evaluate a maintained alternative (e.g. tidy) before investing further.

Implementation Patterns

Wrap it behind a service, never call it inline. Bind a thin service that owns the Formatter instance so you can swap it later:

// app/Services/HtmlFormatter.php
namespace App\Services;

use Machy8\XHTMLFormatter\Formatter;

class HtmlFormatter
{
    public function __construct(private Formatter $formatter) {}

    public function pretty(string $html): string
    {
        return $this->formatter->format($html);
    }
}

Register it as a singleton in a service provider and inject the interface where needed.

Debugging rendered views. A Blade directive or a local-only helper is the highest-value day-to-day use:

Blade::directive('pretty', fn ($expr) => "<?php echo app(\\App\\Services\\HtmlFormatter::class)->pretty($expr); ?>");

Then in a local view: @pretty($someRenderedHtml).

Formatting stored fragments / email templates. Run it in an artisan command that reads HTML from the DB (or from resources/views/mail), formats, and writes back — keep this out of the request path.

// app/Console/Commands/FormatTemplates.php
foreach (Template::cursor() as $tpl) {
    $tpl->update(['body' => $formatter->pretty($tpl->body)]);
}

Test assertions. If you assert against rendered HTML in feature tests, formatting both the expected and actual output with the same formatter makes assertions readable and diff-friendly. Add a helper to your base TestCase.

Fragments vs. full documents. Feed it complete documents (with <!DOCTYPE>) when you need correct structure, and discrete fragments when formatting partials. Keep the two paths in separate methods on your service so you don't accidentally reflow a full page through a fragment-oriented code path.

Pipeline placement. Use it in build/CI steps (post-processing compiled assets or generated docs) rather than in per-request middleware. If you must format responses, restrict it to local/staging environments and only for text/html responses.

Gotchas and Tips

  • Last release was 2017. Expect no PHP 8.x fixes. Run a quick smoke test (format('<div><span>x</span></div>')) on your target PHP version before adopting. If it errors on modern PHP, do not patch vendor/ — fork or pick another tool.
  • Whitespace-sensitive elements. Verify <pre>, <textarea>, <code>, and inline elements (<a>, <span>, <strong>) survive a round-trip unchanged. Reformatters that introduce newlines around inline tags can change visual rendering. Always diff formatted vs. original in a browser for your key templates.
  • Formatter ≠ validator. It beautifies; it does not guarantee well-formed markup. If input is malformed, output may be surprising. Normalize with DOMDocument/tidy first if you need structural guarantees.
  • Encoding. Non-ASCII content and inline <script>/<style> blocks are common failure points. Confirm UTF-8 content and that scripts/styles are passed through untouched; if they are reformatted, pre-strip or skip those regions.
  • Performance. It is a string/token-based formatter, so it is cheap per call but not free. Never run it on every response in production — cache the formatted result if you must serve formatted HTML.
  • Configuration quirks. Options are passed to the formatter/constructor; there is no Laravel config file. Create your own config/html_formatter.php and map it into the constructor so settings live with the rest of your app config.
  • Extension points are minimal. There is no plugin system — customization is limited to constructor options. If you need custom indentation rules per tag, plan to subclass or fork rather than expect hooks.
  • Keep it out of critical-path rendering. Formatting is presentation-only. If it throws, your page should still render — wrap the service in a try/catch that returns the original HTML on failure.
  • Lock it down. Add a composer.json note (or a test) documenting the pinned version and the PHP versions you have verified, so a future composer update doesn't silently swap in an untested state.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle