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

Symfony Carve Laravel Package

markup-carve/symfony-carve

Symfony bundle for Carve, a modern extensible markup language. Parse and render Carve documents in your apps with service container integration, Twig support, configurable options, and cached compilation for fast, flexible markup processing.

View on GitHub
Deep Wiki
Context7

Getting Started

This release (0.1.5) makes file-backed template rendering possible for the first time, so the first thing to check is whether your use case is "render a string I already have" (the existing render() path, unchanged) or "render a template that lives on disk with {% include %} support."

Start here:

  1. Install / upgrade

    composer require markup-carve/symfony-carve:^0.1.5
    

    This pulls carve-php ^0.1.9 (required for the include pass) and psr/log at runtime for the optional warning logger.

  2. Decide on the file-backed mode. It is strictly opt-in. render() and the Twig-style filters still take anonymous strings and never read files — nothing changes for existing callers. To enable file rendering you must configure an absolute include_root and then call CarveRenderer::renderFile() or renderFileWithReport().

  3. First use case — a template that includes partials:

    // config/carve.php (or wherever the package config lives)
    return [
        'include_root' => base_path('resources/carve'),
        'logger'       => 'carve', // optional; any PSR-3 logger
    ];
    
    $html = $renderer->renderFile('pages/home.carve');
    
  4. Read the report if you cache. renderFileWithReport() returns the rendered output plus the resolved and attempted include targets. That list is the intended cache key input — see the patterns below.

If you are only rendering strings passed in from the database or a Blade variable, you can ignore this release entirely and stay on the render() API.

Implementation Patterns

Anonymous string rendering (unchanged). Keep using render() and the Twig-style filters for user-authored or DB-stored templates. This path is safe by construction — it cannot reach the filesystem.

File-backed rendering with a fixed root. Set include_root to an absolute path in config (ideally base_path(...) so it is deployment-independent), then renderFile('relative/path.carve'). Treat the root as the security boundary: the resolver operates inside it and the report tells you exactly what was resolved.

Cache-keying with the report. The report is the main integration win. A typical pattern:

$report = $renderer->renderFileWithReport('pages/home.carve');

$key = 'carve:'.hash('xxh128', implode('|', $report->includedTargets()));

return Cache::remember($key, $ttl, fn () => $report->output());

Because the report carries attempted targets as well as resolved ones, a template that conditionally includes a partial will invalidate cleanly when the branch flips — you don't get a stale cache pointing at the old graph. Persist the target list (or a hash of it) alongside the cached HTML so a later request can invalidate on template mtime.

Wiring the warning logger. Add psr/log-compatible logging on the container and pass it to the renderer. Warnings are emitted for include-resolution problems; note that resolver details are deliberately omitted from logger output (see gotchas), so use the report — not the logs — for anything you need to act on programmatically.

Service-container usage in Laravel. Bind a configured singleton so include_root and the logger are resolved once:

$this->app->singleton(CarveRenderer::class, fn ($app) => new CarveRenderer(
    includeRoot: config('carve.include_root'),
    logger: $app->make(LoggerInterface::class),
));

Testing. Use renderFileWithReport() in tests and assert on the included-target list; that gives you regression coverage on the include graph without snapshotting whole HTML pages.

Gotchas and Tips

  • The feature is opt-in by design — and by security. Do not set include_root to your project root or base_path() wholesale. Point it at a dedicated templates directory. There is no evidence in these notes of path-traversal hardening beyond "stays inside the root," so keep the root narrow.

  • Absolute path required. include_root must be absolute. A relative path is the most likely silent misconfiguration; assert it in a config test or a service-provider boot check.

  • render() never reads files — even with include_root set. Setting the config does not change render()'s behaviour. If your file templates are not including, you probably called render() instead of renderFile().

  • Logs are less useful than the report. Warnings reaching the logger intentionally omit resolver details. Don't build monitoring that parses log lines for paths; use renderFileWithReport() and inspect resolved/attempted targets directly.

  • Report objects cost more than plain rendering. renderFile() skips the report; use it on the hot path once your cache key strategy is settled, and reserve renderFileWithReport() for cache population and tests.

  • Version coupling. The include pass needs carve-php ^0.1.9. If you have a locked older carve-php, composer update markup-carve/symfony-carve alone may not lift it — check composer show carve-php after upgrading.

  • New runtime dependency. psr/log is now required at runtime. It is already present in most Laravel apps, but if you use a minimal or non-standard container, verify it is installed rather than assumed.

  • Namespace mismatch to watch for. The changelog and package name reference the Symfony integration (symfony-carve). If you are consuming it inside Laravel, keep your own thin adapter/service-provider wrapper rather than relying on framework auto-discovery for configuration; that insulation also makes future upstream moves cheaper.

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