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

String Template Laravel Package

nicmart/string-template

nicmart/string-template is a fast, lightweight PHP library for rendering templates with a clean, elegant syntax. It supports nested placeholders, variable transformations, custom renderers, and reusable engines—ideal for emails, notifications, and dynamic text generation.

View on GitHub
Deep Wiki
Context7

Getting Started

Install via Composer:

composer require nicmart/string-template

Pin to ^0.1.3 — it's the first tag that runs clean on PHP 8.1/8.2 (see Gotchas). The public surface is tiny: a StringTemplate value object that you construct from a string, then call render() on with an associative array of substitutions.

use Nicmart\StringTemplate\StringTemplate;

$template = new StringTemplate('Hello {name}, your order #{order_id} ships {ship_date}.');
echo $template->render([
    'name'       => 'Ada',
    'order_id'   => 4096,
    'ship_date'  => '2024-06-01',
]);
// Hello Ada, your order #4096 ships 2024-06-01.

Look first at the StringTemplate class itself (it's small — read it end to end before you build abstractions around it) and the test suite, which is the authoritative documentation of edge cases. The first real use case is user‑facing strings that need named holes: emails, notifications, SMS bodies, log messages, and any sprintf call that has crossed the three‑argument threshold and now needs %1$s-style positional gymnastics.

Sanity-check the install on modern PHP before you build on it:

// tinker
var_dump((new \Nicmart\StringTemplate\StringTemplate('{a}'))->render(['a' => 'ok']));
// Should print "ok" with no deprecation notices in storage/logs/laravel.log

Implementation Patterns

Treat templates as data, not code. Store templates in config, a translations table, or a resources/strings/ directory, and resolve the StringTemplate instance from a service or a small helper:

function render_string(string $template, array $params): string
{
    return (new StringTemplate($template))->render($params);
}

Nested lookups for entity data. Instead of flattening your DTOs into user_name, user_email, pass the array and use dot access:

$template = new StringTemplate('Welcome back, {user.profile.first_name}!');
$template->render(['user' => $customer->toArray()]);

This keeps the controller clean and the template readable.

Build a MessageRenderer service for outbound comms. Centralize the pattern once and inject it wherever mail/SMS are sent:

class MessageRenderer
{
    public function __construct(private StringTemplate $template) {}

    public function render(array $context): string
    {
        return $this->template->render($context + $this->defaults());
    }
}

Pre‑merge defaults, don't fight the template. If a placeholder may be missing, supply it from defaults before calling render():

$params = array_merge(['name' => 'there', 'order_id' => '—'], $params);

Cache the parsed template, not just the string. A StringTemplate instance can be rendered repeatedly with different parameters — instantiate it once per request (or cache the instance in a container keyed by the template string) rather than re-parsing on every call.

Compose with translation lookups. Typical i18n flow: __('emails.welcome') → returns the template string → feed into StringTemplate::render() with the user data. This avoids inventing a second translation syntax.

Gotchas and Tips

  • Upgrade to ^0.1.3 on PHP 8.1/8.2. v0.1.3 is a maintenance release whose only change is silencing deprecation notices caused by type changes in PHP 8.1 and 8.2 (PR #19, first-time contributor). No API changes, no new features, no breaking changes — render() behaves identically. If you're on 0.1.2 you'll be emitting deprecation noise into storage/logs/laravel.log on every render, which is exactly the kind of thing that masks a real warning later. Bump the constraint and run composer update nicmart/string-template.
  • No HTML escaping. render() returns exactly what you put in. If the output goes to a browser, run it through e()/htmlspecialchars() at the output layer, or you will ship an injection bug. This is a text templating engine, not an escaper.
  • Missing placeholders are your responsibility. Decide explicitly whether a missing key should throw, be left as {key}, or be replaced with an empty string — then wrap render() in your own helper that enforces that policy, so behaviour is uniform across the app.
  • Brace collisions. Templates containing literal { / } (JSON snippets, CSS, some log lines) will be misinterpreted. Escape by doubling, or — for anything with more than a stray brace — store the sensitive fragment in a parameter and interpolate it as {blob}.
  • Nested access is array/dot based, not method calls. {user.name} works against array keys. You cannot call {user->getName()}; convert objects with toArray()/json_decode(json_encode($obj), true) first.
  • Type coercion is on you. Integers and floats stringify fine, but null, booleans, and arrays will produce surprising output. Normalize scalars at the call site.
  • Performance. Parsing is cheap but not free; the win comes from reuse. For high‑volume paths (logging, per‑row rendering) hoist the StringTemplate construction out of the loop.
  • Don't reach for it for anything structural. No conditionals, loops, or includes. If a template needs if, it's not a string template anymore — use Blade, Twig, or a match in PHP that selects the template string.
  • Maintenance reality check. v0.1.3 (the PHP 8.1/8.2 deprecation fix) is the first release since October 2022 — a single small PR, ~200 stars, and effectively zero dependents. That's a pulse, not a roadmap: expect no features and long gaps. The codebase is small enough to vendor or reimplement in an afternoon if upstream goes quiet again, so pin the version and keep your render() wrapper thin enough to swap the engine out without touching call sites.
  • Extension point. Because the class is small and the license is MIT, the cleanest place to add filters ({name|upper}), escaping modes, or strict‑missing‑key behaviour is a thin subclass or decorator around StringTemplate in your app, not a fork of the package.
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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core