PHPackages                             rlnks/php-mail-tree-builder - 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. [API Development](/categories/api)
4. /
5. rlnks/php-mail-tree-builder

ActiveLibrary[API Development](/categories/api)

rlnks/php-mail-tree-builder
===========================

Framework-agnostic PSR-7/PSR-15 API handler for the php-mail-tree visual builder

v0.1.1(3w ago)02↓100%MITPHPPHP &gt;=8.2

Since May 13Pushed 3w agoCompare

[ Source](https://github.com/rlnks/php-mail-tree-builder)[ Packagist](https://packagist.org/packages/rlnks/php-mail-tree-builder)[ RSS](/packages/rlnks-php-mail-tree-builder/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (5)Versions (3)Used By (0)

rlnks/php-mail-tree-builder
===========================

[](#rlnksphp-mail-tree-builder)

Framework-agnostic PSR-7/PSR-15 API handler for the [php-mail-tree](https://github.com/rlnks/php-mail-tree) visual builder.

Installation
------------

[](#installation)

```
composer require rlnks/php-mail-tree-builder
```

Requires PHP 8.2+ and a PSR-7/PSR-17 implementation (e.g. `nyholm/psr7`).

---

Endpoints
---------

[](#endpoints)

MethodPathDescription`POST``{prefix}/render/node`Render a single node → HTML snippet`POST``{prefix}/render/document`Render the full email → complete HTML`GET``{prefix}/document`List saved documents`POST``{prefix}/document`Create a new document`GET``{prefix}/document/{id}`Load a document`PUT``{prefix}/document/{id}`Save / update a document`DELETE``{prefix}/document/{id}`Delete a document---

Quick start
-----------

[](#quick-start)

```
use Nyholm\Psr7\Factory\Psr17Factory;
use Rlnks\MailTreeBuilder\BuilderConfig;
use Rlnks\MailTreeBuilder\BuilderHandler;

$factory = new Psr17Factory();

$handler = new BuilderHandler(
    config: new BuilderConfig(
        pathPrefix:  '/builder',
        corsOrigins: ['http://localhost:3000'],
        storage:     new MyStorage(),   // implements StorageInterface
    ),
    responseFactory: $factory,
);

// Slim 4
$app->any('/builder/{path:.*}', $handler);

// Vanilla PHP
$request  = $factory->createServerRequest($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']);
$response = $handler->handle($request);
http_response_code($response->getStatusCode());
foreach ($response->getHeaders() as $name => $values) {
    header($name . ': ' . implode(', ', $values));
}
echo $response->getBody();
```

---

`POST /render/node`
-------------------

[](#post-rendernode)

Render a single node from a JSON tree node + StyleSheet config. The builder calls this whenever a node is added or modified, caching the HTML for canvas assembly.

```
{
  "sheet": {
    "primaryColor": "#003366",
    "fontFamily": "Poppins, Arial, sans-serif",
    "containerWidth": 600,
    "webFonts": [{ "url": "https://fonts.googleapis.com/…", "name": "Poppins" }],
    "styles": {
      "hero": { "container": { "background-color": "#003366" } }
    }
  },
  "node": {
    "type": "Container",
    "_tag": "Section",
    "style": { "container": { "background-color": "#ffffff" } },
    "hidden": false,
    "children": { "body": { "type": "Column", "children": {} } }
  }
}
```

Response: `{ "html": "…" }`

---

`POST /render/document`
-----------------------

[](#post-renderdocument)

Render the full email. Used for the Preview button. Returns the complete `` string.

```
{
  "sheet": { "…": "…" },
  "tree": { "type": "EmailDocument", "…": "…" },
  "locale": "fr",
  "translations": {
    "hero_title": { "fr": "Bienvenue!", "en": "Welcome!" }
  }
}
```

Response: `{ "html": "…" }`

---

Storage
-------

[](#storage)

Implement `StorageInterface` to persist documents in your preferred backend:

```
use Rlnks\MailTreeBuilder\StorageInterface;

class DatabaseStorage implements StorageInterface
{
    public function save(?string $id, array $document): string
    {
        $id ??= uniqid('doc_', true);
        DB::table('builder_documents')->upsert(['id' => $id, 'data' => json_encode($document)], ['id']);
        return $id;
    }

    public function load(string $id): array
    {
        $row = DB::table('builder_documents')->find($id)
            ?? throw new \RuntimeException("Document {$id} not found.");
        return json_decode($row->data, true);
    }

    public function delete(string $id): void
    {
        DB::table('builder_documents')->delete($id);
    }

    public function list(): array
    {
        return DB::table('builder_documents')
            ->select('id', 'updated_at')
            ->orderByDesc('updated_at')
            ->get()
            ->toArray();
    }
}
```

---

License
-------

[](#license)

MIT

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance94

Actively maintained with recent releases

Popularity3

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity37

Early-stage or recently created project

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

Total

2

Last Release

27d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/245694487?v=4)[philippegagnon-sys](/maintainers/philippegagnon-sys)[@philippegagnon-sys](https://github.com/philippegagnon-sys)

---

Top Contributors

[![philippegagnon-sys](https://avatars.githubusercontent.com/u/245694487?v=4)](https://github.com/philippegagnon-sys "philippegagnon-sys (3 commits)")

### Embed Badge

![Health badge](/badges/rlnks-php-mail-tree-builder/health.svg)

```
[![Health](https://phpackages.com/badges/rlnks-php-mail-tree-builder/health.svg)](https://phpackages.com/packages/rlnks-php-mail-tree-builder)
```

###  Alternatives

[cakephp/cakephp

The CakePHP framework

8.8k19.1M1.7k](/packages/cakephp-cakephp)[guzzlehttp/psr7

PSR-7 message implementation that also provides common utility methods

7.9k1.1B3.7k](/packages/guzzlehttp-psr7)[thecodingmachine/graphqlite

Write your GraphQL queries in simple to write controllers (using webonyx/graphql-php).

5723.2M40](/packages/thecodingmachine-graphqlite)[tempest/framework

The PHP framework that gets out of your way.

2.2k31.1k11](/packages/tempest-framework)[typo3/cms

TYPO3 CMS is a free open source Content Management Framework initially created by Kasper Skaarhoj and licensed under GNU/GPL.

1.2k1.9M122](/packages/typo3-cms)[telnyx/telnyx-php

Official Telnyx PHP SDK — APIs for Voice, SMS, MMS, WhatsApp, Fax, SIP Trunking, Wireless IoT, Call Control, and more. Build global communications on Telnyx's private carrier-grade network.

35729.6k2](/packages/telnyx-telnyx-php)

PHPackages © 2026

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