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

Demo Block Extension Laravel Package

anomaly/demo_block-extension

A demo block extension for the Anomaly CMS that provides a sample block type showing how to build, register, and render custom blocks in Streams-powered pages. A handy reference for developers creating their own block extensions.

View on GitHub
Deep Wiki
Context7

Getting Started

Prerequisites. You need a Streams Platform / PyroCMS application with the anomaly/blocks-module installed and enabled. This package is an extension for the Blocks module — it does nothing on its own and won't register a block type unless the Blocks module is present.

Install (from source, not Packagist). Since this is a demo repo, add it as a VCS repository rather than assuming a Packagist entry:

"repositories": [
  { "type": "vcs", "url": "https://github.com/anomalylabs/demo_block-extension" }
]

Then install:

composer require anomaly/demo_block-extension
php artisan addon:install anomaly/demo_block-extension

If you'd rather not touch vendor/, clone into your project's addons/ directory, add a path repository, and run composer dump-autoload.

Where to look first. Open these three files in order:

  1. src/DemoBlockExtension.php — the whole addon lives here. Note the class extends the Blocks module's BlockExtension and defines the $view, the addon $slug, and often a form() method describing the fields the block exposes.
  2. resources/views/ — the Blade file the block renders through. This is where the field values become markup.
  3. resources/lang/en/addon.php — the name/description strings shown in the Blocks admin UI.

First use case: use it as a scaffold. Don't treat this as a feature. Copy the directory into your own addon path, rename the namespace, slug, and view namespace, and you have a working custom block type in about ten minutes. It's the canonical starting point for "my client needs a testimonial/CTA/pricing block."

Implementation Patterns

Copy-and-rename is the intended workflow. Everything is keyed off a small set of strings that must agree:

Thing Example value
Composer name anomaly/demo_block-extension
Addon slug anomaly/demo_block-extension
PSR-4 namespace Anomaly\DemoBlockExtension\
Extension class DemoBlockExtension
Directory demo_block-extension/
View namespace anomaly.extension.demo_block::...

Change all six together or the addon silently fails to appear.

Defining fields on the block. Most of your day-to-day work happens in the extension's form() method, using Streams field types (text, textarea, select, image, relationship, repeater, etc.):

protected function form(FormBuilder $builder)
{
    $builder->setFields([
        'heading' => ['type' => 'text', 'required' => true],
        'body'    => ['type' => 'textarea'],
        'image'   => ['type' => 'files'],
    ]);
}

Then in the view, read them off the block:

<h2>{{ $block->heading }}</h2>
{!! $block->body !!}

Transform in the extension, render in the view. If the raw field data is awkward (a files relation, an array from a repeater, a select key that needs a label), compute a clean value in block()/the extension class rather than looping inside Blade. Keeps the template readable and testable.

Reuse across areas. Once installed, one block type can be placed in multiple block groups (header, footer, sidebar) via the Blocks admin. There's no per-page code to touch — content editors compose pages. That's the main integration win.

Localize labels. Add field.php and button.php to resources/lang/en/ alongside addon.php, so labels in the admin form come from translations rather than hardcoded strings. It's cheap now, painful to retrofit.

Compose with other addons. Blocks are often paired with the pages and types modules — a block type used in a page type's layout area is the most common pattern in real builds.

Gotchas and Tips

  • A single stale namespace kills everything. If the block doesn't show up in the admin, check the PSR-4 namespace against the directory and slug first — mismatch is the number-one cause. Run composer dump-autoload and php artisan addon:reinstall anomaly/demo_block-extension after any composer/namespace change.
  • Caches lie. Streams caches the addon manifest. Debug by clearing in this order: php artisan cache:clear, php artisan view:clear, php artisan addon:reinstall <slug>. A "view not found" error almost always means a stale view namespace, not a missing file.
  • Directory name = slug with a dash. demo_block-extension on disk, demo_block in the view namespace, demo_block-extension in composer. The extension slug uses the underscore form; the addon slug uses the dash form.
  • View namespace syntax. anomaly.extension.demo_block::viewname — the :: separator is required. Dropping it resolves against the app, not the addon.
  • Don't edit inside vendor/. Composer will overwrite it. Clone/copy into addons/ and register a path repository.
  • Extensions aren't modules. No migrations, no service provider routes by default. If you need persistence beyond block field values, you want a module or a custom field type, not a block extension.
  • It's a demo, not a dependency. No tests, no semver tags, zero dependents. Pin to a commit if you fork it, and expect to own the code entirely after copying.
  • Check compatibility. Old PyroCMS 2.x vs. modern Streams Platform differ in base classes (BlockExtension location) and in the admin UI registration. Read the composer.json constraints before assuming an older tutorial applies.
  • Extension points worth knowing. The extension class is the seam: override the view, add a form(), or hook block() to post-process data. Anything beyond that — custom front-end rendering logic, API output — belongs in your theme or a dedicated presenter, keeping the block dumb.
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.
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk