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

Coilpack Laravel Package

expressionengine/coilpack

Coilpack bridges ExpressionEngine and Laravel, letting you build and extend EE sites with Laravel routing, Blade views, Eloquent models, and Composer packages while preserving ExpressionEngine templates, add-ons, and existing content.

View on GitHub
Deep Wiki
Context7

Getting Started

Coilpack is a bridge package, not a standalone CMS — it assumes you already have a working ExpressionEngine 6+ installation (with its own system/, config/, and MySQL database) and drops Laravel on top of it. The minimum viable setup:

  1. Install into an existing Laravel app

    composer require expressionengine/coilpack
    

    Require at least PHP 8.1 and a Laravel version compatible with the release you pin (check the matrix on Packagist — the package lags Laravel majors by a bit).

  2. Publish the config and point it at EE

    php artisan vendor:publish --tag=coilpack
    

    Then open config/coilpack.php and set the path to your EE install (or rely on the EE_BASE_PATH env var). Coilpack needs to locate EE's system/ directory and read the EE config/database credentials — usually by sharing the same database connection or by letting Coilpack pull EE's database.php. Getting this wrong is the single most common install failure, so validate it first.

  3. Register the service provider (Laravel auto-discovers it in modern versions, but older setups need it manually in config/app.php).

  4. Look here first, in order:

    • config/coilpack.php — routes, template paths, GraphQL toggle, caching.
    • The Coilpack facade — Coilpack::render(), Coilpack::parse(), route registration.
    • The models namespace (ExpressionEngine\Coilpack\Models\Channel\Entry, Channel, Category) — this is where most day-to-day data access happens.
    • The routes key in the config or Coilpack::route() — how you expose EE templates over HTTP.
  5. First useful use case: expose a single EE template through Laravel without touching EE's own router:

    // routes/web.php
    Route::get('/blog', fn () => Coilpack::render('blog/index'));
    

    Or, data-first, pull entries straight into a Blade view:

    $entries = \ExpressionEngine\Coilpack\Models\Channel\Entry::where('channel_id', 2)
        ->orderBy('entry_date', 'desc')
        ->limit(10)
        ->get();
    return view('blog.index', compact('entries'));
    

    Once one template renders, you have the feedback loop you need to explore the rest.

Implementation Patterns

Coilpack gives you two distinct integration styles, and the right choice depends on who owns the content.

1. Template-driven (EE owns the markup). Route a URL to an EE template name and let EE's tag engine render it. Good when designers/content editors manage layouts inside EE's control panel and you just want Laravel's middleware, auth, and HTTP stack in front.

Route::middleware(['web', 'auth'])->get('/account', fn () => Coilpack::render('account/dashboard'));

2. Data-driven (Laravel owns the markup). Use Coilpack's models in controllers/API resources, return JSON or Blade, and treat EE purely as a content store. This is the pattern teams actually lean on for SPA/headless builds.

class PostController {
    public function show(string $urlTitle) {
        $entry = Entry::where('url_title', $urlTitle)->firstOrFail();
        return new PostResource($entry);
    }
}

3. Hybrid: EE tags inside Blade. Coilpack parses EE's {exp:...} syntax, so you can drop tag blocks into Blade views when you want EE's add-on behavior (channel entries loops, plugins, field rendering) without building routes for every template.

{exp:channel:entries channel="news" limit="5"}
   <h2><a href="/news/{url_title}">{title}</a></h2>
{/exp:channel:entries}

This is the sweet spot for migrating a legacy EE site to Laravel incrementally — lift the markup as-is, wrap it in Blade layouts, then refactor the tags into models/controllers over time.

4. GraphQL / headless. Coilpack exposes an optional GraphQL layer (Lighthouse-based) so a decoupled frontend can query channels and entries directly. Enable it in config/coilpack.php, then point your frontend at the endpoint. For a Next/Nuxt/Vue app this is often the fastest path — no PHP models, no Blade, just typed queries against EE content.

5. Cache what renders. Coilpack rendering goes through EE's tag parser, which is not cheap. Wrap template renders in Cache::remember() (keyed on template name + request params), and invalidate on entry saves via a model observer or EE's own cache-clearing. For high-traffic pages this is non-negotiable.

6. Auth and permissions. Laravel's guards don't automatically map to EE members. If you need "logged-in EE member sees X," either bridge EE's member session into Laravel (custom guard reading EE's session table/cookies) or, cleaner for new builds, keep auth in Laravel and treat EE as read-only content.

Gotchas and Tips

  • The EE install is a hard dependency. Coilpack is not a CMS replacement; it reads EE's config, DB, and system/ code. Docker-ize the whole thing together (app code + EE system + shared DB) or CI will break in confusing ways when the system/ path isn't where Coilpack expects.

  • Path/config mismatches are the #1 failure mode. Symptoms: blank renders, "template not found," or database connection errors that don't match your .env. Check config/coilpack.php first, then clear config cache (php artisan config:clear). Coilpack reads EE's own config in addition to Laravel's — a stale config:cache can mask an EE-side change.

  • EE template parsing is slow and easy to double-render. Every {exp:...} block is resolved at runtime. If you're rendering the same template in a loop (e.g., per-item widget), you're paying for parse on each call. Cache aggressively and avoid Coilpack rendering inside pagination loops where a model query would do.

  • Version drift between EE and Coilpack. The package tracks EE majors loosely. Before an EE update, check Coilpack's release notes — a point release on EE can change tag internals and quietly break parsed templates. Pin both expressionengine/coilpack and your EE version in composer.json.

  • Low star count = thin community surface. With ~28 stars, expect to read source rather than search Stack Overflow. The repo itself, vendor/expressionengine/coilpack/src, is the real documentation for models, facades, and the tag parser. Budget an afternoon for source reading on any non-trivial integration.

  • Model behavior isn't Eloquent. Coilpack's Entry, Channel, Category models lean on EE's own query layer. Don't assume relationships, eager loading, or with() behave like Eloquent. Test where/orderBy against real data — some operators and column names come straight from EE's schema (entry_date, url_title, channel_id).

  • Debugging parsed templates. When a tag silently returns nothing: (1) confirm the channel/field names, (2) test the tag inside EE's own control panel to isolate Coilpack from EE, (3) check that the add-on powering the tag is actually installed and enabled in EE — Coilpack doesn't bundle add-ons.

  • Extension points to know:

    • Custom tags via EE's add-on API still work under Coilpack — install the add-on in EE, it gets picked up.
    • GraphQL: extend the schema by registering custom types/resolvers if your content needs computed fields.
    • Middleware on Coilpack routes lets you bolt on Laravel features (rate limiting, auth, CORS) without touching EE.
  • Don't fight the routing model. Coilpack wants to register routes from a config map or via Coilpack::route(). If you find yourself writing many one-off Route::get('/x/{y}') handlers that just call Coilpack::render(), move them into the config-driven route map — it keeps template-to-URL mapping discoverable for editors.

  • Upgrade checklist: bump Coilpack → composer update → publish any new config keys → php artisan config:clear && route:clear → smoke-test one template-driven page and one model query, because those exercise different code paths (parser vs. models) and break independently.

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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core