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

Cells Laravel Package

torann/cells

torann/cells is a Laravel package for building reusable view components called cells. It separates presentation from logic, letting you render encapsulated UI pieces, pass data cleanly, and keep Blade templates organized, maintainable, and testable across your application.

View on GitHub
Deep Wiki
Context7

Getting Started

Install via Composer (Laravel 4 only — the package targets illuminate/support ~4.0):

composer require torann/cells

Register the service provider and facade in app/config/app.php:

'providers' => [
    // ...
    'Torann\Cells\CellsServiceProvider',
],

'aliases' => [
    // ...
    'Cell' => 'Torann\Cells\Facades\Cell',
],

Where to look first

  1. Read src/Torann/Cells/Cell.php — this is the abstract base your components extend. Confirm the exact hook method (render(), run(), or similar) before writing anything.
  2. Read src/Torann/Cells/CellsServiceProvider.php — it shows what gets bound into the IoC container and what config gets merged/published.
  3. Check README.md for the exact facade signature and view path conventions; the API surface is small.

First use case: encapsulate a self-contained block of page chrome — a sidebar widget, a breadcrumb trail, a "recently viewed" list — that currently forces you into a controller + partial + view composer. A Cell gives you a class with its own data-fetching logic and its own Blade view, so the markup and the query live together and can be dropped into any template.

namespace App\Cells;

use Torann\Cells\Cell;

class RecentPosts extends Cell
{
    public function render()
    {
        return $this->view('cells.recent-posts', [
            'posts' => \Post::orderBy('created_at', 'desc')->take(5)->get(),
        ]);
    }
}
{{-- app/views/home.blade.php --}}
<div class="sidebar">
    {{ Cell::make('RecentPosts') }}
</div>

Implementation Patterns

Class-per-widget, view-per-class. Keep the namespace convention App\Cells\Foo alongside app/views/cells/foo.blade.php. Register a namespace in the package config (if it exposes one) or rely on Cell::make() resolving fully-qualified names — both styles show up in the source, so pick one and be consistent.

Passing data into a cell. Prefer constructor-style arguments exposed by the facade (Cell::make('Foo', ['limit' => 10])) over reaching into globals. Inside the cell, store them as properties so the view can read them via $this->limit and so sub-renders can reuse them.

Cells calling cells. The strongest pattern is composition: a Dashboard cell whose render() invokes Cell::make('Stats'), Cell::make('RecentOrders'), and returns a view that renders all three. Because each cell is an isolated unit with its own view, you can cache the outer one and let the inner ones be cheap.

Caching. Wrap hot cells with Cache::remember() inside render(), keyed by the cell name plus any arguments that affect output (user id, filters). Laravel 4's cache driver is configured in app/config/cache.php — remember that array is the default and gives you no wins.

Dependency injection. Cells are resolved through the container, so constructor injection works: type-hint a repository or a Request in the constructor and the service provider's binding will supply it. Use this for testable cells; avoid App::make() in the body.

Blade vs raw output. Return the View object from render() and let the caller decide {{ }} vs {!! !!}. If your cell returns a string that must be inserted verbatim, document that clearly — otherwise callers will double-escape or accidentally escape HTML you built intentionally.

Testing. Unit-test a cell by instantiating it with mocked collaborators and asserting the returned view name and data array. This is the main reason to prefer cells over view composers — the logic is in a class you can new up.

Gotchas and Tips

Laravel 4 only. The package's Composer constraints pin illuminate/* to 4.x. It will not install on Laravel 5+ without patching composer.json; upstream never tracked the framework's namespace changes. If you're on a newer app, look at Laravel's own blade components or a maintained successor instead.

Autoloading. Laravel 4 predates PSR-4 defaults in composer.json — the app/ directory is typically under classmap or psr-0. If a new App\Cells\Foo class isn't found, run composer dump-autoload before assuming the package is broken.

Facade not resolving. Two common causes: the alias key must be lowercase-insensitive but exact ('Cell'), and the service provider must appear before anything that reads the alias. php artisan config:cache on L4 does not exist — restart your web server or clear bootstrap/compiled.php instead.

View path resolution. $this->view('cells.foo') resolves through the app's configured view paths. Publish or manually add a package view path if the cell ships its own template; otherwise a "view not found" in production is a path issue, not a code bug.

Nested cells and output buffering. If render() echoes instead of returning a view, nesting breaks silently — Cell::make('A') in a template will produce output at the wrong point in the buffer. Always return from render().

Escaping surprises. A cell that returns a View renders correctly with {{ }}. A cell that returns a string built with e() calls will be double-escaped when the caller uses {{ }}. Decide once per cell and document it.

Performance. Each Cell::make() is a container resolution plus a view render. On list pages with dozens of cells this shows up in profiling. Cache aggressively, or make Cell::make() lazy (only resolve when render() is called) if the facade allows it.

Extension points. The base Cell class is designed to be subclassed, and the service provider is a normal L4 provider — bind your own Cell contract, override the default view namespace, or register a custom resolver in a boot() of your own if you need different class-to-view mapping. Inspect the provider's register()/boot() before assuming behavior; the package is small enough that reading the ~200 lines of source is faster than searching for docs.

Debugging. Use dd(Cell::make('Foo')) in a route closure to confirm the class resolves, then dd($cell->render()) to see the raw view object. If render() returns null, the likely culprit is a missing return or a view path typo.

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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings