Skip to content

Basic Usage

Abdelkarim Mateos Sanchez edited this page Dec 9, 2025 · 1 revision

Basic Usage

Core Concepts

The package is built around four main concepts:

  1. Tokens: Parsed mustache expressions ({{User.name}})
  2. Context: The data source for resolution (models, arrays, objects)
  3. Resolvers: Components that extract values from context
  4. Pipeline: Orchestrates resolution through multiple resolvers

Parsing Templates

Use MustacheParser to extract tokens from templates:

use AichaDigital\MustacheResolver\Core\Parser\MustacheParser;

$parser = new MustacheParser();

// Check if template contains mustaches
if ($parser->hasMustaches('Hello {{User.name}}!')) {
    // Parse to get tokens
    $tokens = $parser->parse('Hello {{User.name}}!');

    foreach ($tokens as $token) {
        echo $token->getRaw();        // "User.name"
        echo $token->getType();       // TokenType::MODEL
        echo $token->getModelName();  // "User"
        echo $token->getFieldPath();  // ["name"]
    }
}

// Extract raw mustache strings
$raw = $parser->extractRaw('{{a}} and {{b}}');
// Result: ['{{a}}', '{{b}}']

Creating Context

Context provides data for resolution:

use AichaDigital\MustacheResolver\Core\Context\ResolutionContext;

// From array
$context = ResolutionContext::fromArray([
    'User' => $userModel,
    'Device' => $deviceModel,
    'settings' => ['theme' => 'dark'],
]);

// Access data
$user = $context->get('User');
$theme = $context->get('settings.theme');

// Check existence
if ($context->has('Device')) {
    // ...
}

Building the Pipeline

Use PipelineBuilder for easy setup:

use AichaDigital\MustacheResolver\Core\Pipeline\PipelineBuilder;

// Default pipeline with all built-in resolvers
$pipeline = PipelineBuilder::default()->build();

// Custom pipeline with specific resolvers
$pipeline = PipelineBuilder::create()
    ->addResolver(new ModelResolver())
    ->addResolver(new RelationResolver())
    ->addResolver(new VariableResolver())
    ->build();

Resolving Tokens

use AichaDigital\MustacheResolver\Core\Parser\MustacheParser;
use AichaDigital\MustacheResolver\Core\Pipeline\PipelineBuilder;
use AichaDigital\MustacheResolver\Core\Context\ResolutionContext;

$parser = new MustacheParser();
$pipeline = PipelineBuilder::default()->build();

$template = 'Hello {{User.name}}, welcome to {{Company.name}}!';
$context = ResolutionContext::fromArray([
    'User' => $user,
    'Company' => $company,
]);

// Parse tokens
$tokens = $parser->parse($template);

// Resolve each token
$result = $template;
foreach ($tokens as $token) {
    $value = $pipeline->resolve($token, $context);
    $result = str_replace('{{' . $token->getRaw() . '}}', $value, $result);
}

echo $result; // "Hello John, welcome to Acme Inc!"

Token Types

The parser automatically classifies tokens:

use AichaDigital\MustacheResolver\Core\Token\TokenType;

$token = Token::fromString('User.department.name');
echo $token->getType(); // TokenType::RELATION

// Available types:
TokenType::MODEL;           // User.name
TokenType::RELATION;        // User.department.name
TokenType::COLLECTION;      // User.posts.*.title
TokenType::VARIABLE;        // $myVariable
TokenType::DYNAMIC_FIELD;   // Device.$config.field
TokenType::NULL_COALESCE;   // User.nickname ?? 'default'
TokenType::FUNCTION;        // now()
TokenType::TABLE;           // users.email
TokenType::COMPOUND;        // USE clause expressions

Handling Resolution Errors

use AichaDigital\MustacheResolver\Exceptions\UnresolvableException;
use AichaDigital\MustacheResolver\Exceptions\ResolutionException;

try {
    $value = $pipeline->resolve($token, $context);
} catch (UnresolvableException $e) {
    // No resolver could handle this token
    $token = $e->getToken();
    $fallback = 'N/A';
} catch (ResolutionException $e) {
    // Resolution failed (e.g., null value, condition not met)
    $message = $e->getMessage();
}

Complete Example

<?php

use AichaDigital\MustacheResolver\Core\Parser\MustacheParser;
use AichaDigital\MustacheResolver\Core\Pipeline\PipelineBuilder;
use AichaDigital\MustacheResolver\Core\Context\ResolutionContext;

class TemplateRenderer
{
    private MustacheParser $parser;
    private ResolutionPipeline $pipeline;

    public function __construct()
    {
        $this->parser = new MustacheParser();
        $this->pipeline = PipelineBuilder::default()->build();
    }

    public function render(string $template, array $data): string
    {
        if (!$this->parser->hasMustaches($template)) {
            return $template;
        }

        $context = ResolutionContext::fromArray($data);
        $tokens = $this->parser->parse($template);

        $result = $template;
        foreach ($tokens as $token) {
            try {
                $value = $this->pipeline->resolve($token, $context);
                $placeholder = '{{' . $token->getRaw() . '}}';
                $result = str_replace($placeholder, (string) $value, $result);
            } catch (\Exception $e) {
                // Keep original placeholder or use fallback
            }
        }

        return $result;
    }
}

// Usage
$renderer = new TemplateRenderer();
$output = $renderer->render(
    'Dear {{User.name}}, your order #{{Order.id}} is {{Order.status}}.',
    [
        'User' => $user,
        'Order' => $order,
    ]
);

Installation | Next: Resolvers

Clone this wiki locally