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

Framework Laravel Package

pollora/framework

Pollora Framework brings Laravel's toolkit to WordPress development, letting you build themes and plugins with Blade templates, Eloquent models, service providers, and familiar Laravel conventions while staying fully compatible with WordPress.

View on GitHub
Deep Wiki
Context7

Getting Started

Pollora is a Laravel framework for WordPress themes. A site is a Laravel application: WordPress boots inside it, blocks, roles, typed meta and assets are declared with PHP attributes and classes, and the framework compiles them into WordPress registrations.

composer require pollora/framework
php artisan vendor:publish   # config/block-bindings.php, roles, meta, assets
php artisan pollora:doctor

Run pollora:doctor first, always. It is the fastest signal that the framework's checks for block bindings, roles and meta are wired correctly, and every release in this line adds or moves one of those checks. As of v13.38.1 it also warns when APP_URL has no scheme and prints the value to write — take that warning seriously rather than editing around it.

Set APP_URL with its scheme (APP_URL=http://pollora.test, https:// in production). A bare host written by hand into .env used to break every Artisan command with Undefined array key "host" and answer /wp-admin/ with a 404; it is now read as http://pollora.test, but https cannot be inferred, so write it out.

Where to look first depends on what you are doing:

  • Day-to-day application code — the core classes: Pollora\BlockBinding\*, Pollora\Role\*, Pollora\Meta\*, Pollora\Asset\*. Class names and namespaces have not changed in v13.36.1, even though the implementations moved to pollora/block-bindings, pollora/roles, pollora/meta and pollora/assets.
  • Laravel-bound pieces — Pollora\{BlockBinding,Role,Meta}\Infrastructure\Laravel. Service providers, commands, the role middleware, the @role directive, the Meta and Asset facades, LaravelMetaValidator, HasRoles, HasTypedMeta.
  • The four sub-packages — the framework requires them, so you get them transitively. Do not add them to require unless you are deliberately using the core standalone (a plugin, a classic theme, a Bedrock site with no Laravel container).

A good first use case is a block binding, because it exercises the most surface at once — attribute discovery, DI into the resolver, the editor script and the preview route:

php artisan pollora:make:binding SiteTitle
php artisan pollora:binding:list

If you develop on Valet or Herd, upgrade to at least v13.38.1 before you debug anything else: earlier patches produced a home-page redirect loop and a 404 on the /cms/wp-admin/ address that pollora:install prints.

Implementation Patterns

Block bindings. Declare a source with #[BlockBinding] and let BlockBindingDiscovery find it. The source method's typed parameters are resolved for you: LaravelMethodInvoker calls through Laravel's container, so you can type-hint any service in the method signature and it arrives. Bind editor-side sources through config/block-bindings.php; the options you list under block-bindings.options are read by the provider and reach OptionSource and the editor data as an array. block-bindings.js ships with the package and is enqueued for you — do not copy it into your theme. Use BindingContext::post() to get the current post and BindingResolved (dispatched through Laravel's dispatcher via LaravelBindingEvents) to hook resolution.

Roles and capabilities. Declare roles as attributed classes; RoleDiscovery feeds RoleRegistry, and RoleCompiler flushes them into WordPress on the appropriate hook. Map post types to capabilities with PostTypeCapabilityMap rather than hand-writing 'edit_posts'-style strings. On the application side everything is Laravel-shaped: $user->can() works through HasRoles, @role and @can work in Blade, and the role middleware (EnsureUserHasRole) guards routes. Never call add_role() yourself — the compiler will fight you.

Typed meta. Register a schema with Meta::schemaFor() / Meta::of(), read and write through MetaRecord, and put HasTypedMeta on the models you want typed access from. Meta::extend() lets you attach extra fields to an existing schema without editing it — this is the intended extension point for plugins and child themes. LaravelMetaValidator plugs into Laravel's validator, so schema rules are ordinary Laravel rules. MetaUiDrivers controls how fields are surfaced to the editor; drivers receive a PSR-11 container.

Assets. The fluent builder is the whole API:

Asset::add('app')
    ->container('theme')
    ->useVite();

ViteManager is Laravel's Vite, so ASSET_URL, a CDN and the application URL keep applying in a normal Pollora site. The release notes are explicit that rendered HTML is unchanged in build and in hot mode — if you are upgrading, diff the markup once in both modes and then trust it. AssetFile::resolveUsing() is the seam if you need a custom file resolver; it must be set by a service provider.

Query. With pollora/query 2.0 you get terminal methods (first(), ids(), count(), exists()) and coverage of every WordPress query class, behind the same three facades. Prefer the terminal methods over get() plus manual array work — they are the part of 2.0 that got the most attention.

Integration tips. Keep custom code against the core classes and the published contracts, not against Infrastructure\Laravel. If you write something that must run without Laravel — a plugin, a mu-plugin, a test — code it against the package contracts (MethodInvokerInterface, BindingEventsInterface, PostFinderInterface, ViteManagerFactory, RuntimeContext, PublicPath) and let the framework supply the Laravel implementations.

Local serving. Pollora decides whether Laravel or WordPress is serving a request by inspecting SCRIPT_FILENAME and the front controller. Valet and Herd route through their own server.php, which includes public/index.php; from v13.38.1 an included front controller counts as Laravel serving the request, and a request for a public/ directory containing an index.php is dispatched to that file. You get the right behaviour with no .htaccess/nginx rules of your own — if you have written workarounds for the self-redirect or the /cms/wp-admin/ 404, delete them so they cannot mask the fix.

Serving in production. The document root must be public/, not the project folder. Pointed at the project folder, Apache, nginx and MAMP serve .env — application key and database password included — and answer the site with a 404. Site Health now reports this: it requests /.env and tells you to move the document root. Treat that Site Health error as a security incident, not a config nit.

Gotchas and Tips

composer update will pull pollora/query 2.0. The constraint is now ^1.0 || ^2.0, so an unpinned update upgrades you. Four things change the result of queries that used to run:

  • where() followed by orWhere() now groups the earlier clauses — (a AND b) OR c instead of what you had before. Audit any query mixing the two; this is the one most likely to silently change a page.
  • DateQuery::inclusive() now actually takes effect.
  • Dates use a 24-hour clock.
  • An invalid fields(), userPermission() or orderBy() direction now throws QueryException instead of being ignored — so previously dead code paths will start failing loudly.

If you need the old behaviour, require pollora/query: ^1.0 in your own composer.json; the framework will honour it. Otherwise read the package's upgrading guide and run your query tests before deploying.

Do not construct the moved classes by hand. AssetEnqueuer no longer resolves its hook services, Vite factory, runtime and logger from the container — they are constructor arguments. AssetManager, MissingBuilds and MissingBuildNotice now take the public directory, logger and project root as arguments. Resolve through the facade or the container. If you have a unit test that does new AssetEnqueuer(...), it is broken; if you have one that lets an AssetEnqueuer outlive the application, note that this release fixes the throw during deferred-enqueue failure reporting.

Closures now receive ContainerInterface. MetaUiDrivers and MetaAccessor::extend() take a PSR-11 container, and a driver closure receives that same object — not the Laravel container type. It is the Laravel container, so $container->make() works, but type-hint Psr\Container\ContainerInterface and do not reach for app() inside these closures if you want the code to survive the package split.

BindingContext::post() is typed as Colt's Post. With Laravel present it returns the framework's Pollora\Models\Post, which extends Colt's; without it, Colt's. Type-hint Colt's Post in binding code: that is the only type that is correct in both worlds.

Naming replaced Str in the core. Role labels without an explicit label now come from Naming::headline(), and data-object property keys from Naming::snake(). The release notes say the output is identical, but if your own tests assert on Str::snake() output or on generated labels, re-run them — that is exactly the kind of "identical" that is identical until it is not.

Labels and names in block bindings moved too. Same Naming story. Check any custom source that relied on Str-derived naming.

APP_URL normalization is convenience, not a policy. A scheme-less value is coerced to http://, which is wrong for any site behind TLS. If pollora:doctor flags it, fix .env rather than relying on the fallback — and remember the normalized value also feeds WP_HOME, WP_SITEURL and the cookie path, so a wrong scheme shows up as cookie and login problems, not only as a broken link.

Debugging entry points, in order: pollora:doctor (cross-cutting — contracts, and now APP_URL scheme), Site Health (.env reachability, web-server document root), pollora:binding:list (what discovery actually found), pollora:meta:* (schemas and audits), pollora:roles:*. pollora:doctor is the fastest way to catch a contract that was bound to the wrong implementation after the split.

When routing misbehaves locally, ask which process resolved the request before you touch Pollora config: Valet/Herd (server.php including the front controller), a public/ directory with its own index.php, or WordPress itself. The v13.38.1 fixes all live in that decision — an infinite redirect to the home URL and a /cms/wp-admin/ 404 on Valet/Herd both came from misclassifying the entry point.

block-bindings.options must be an array in config. The provider reads it and hands it to OptionSource and to the editor data. A collection or a nested object will not make it through.

Extension points worth knowing: AssetFile::resolveUsing() for file resolution; the three asset contracts (ViteManagerFactory, RuntimeContext, PublicPath) if you use pollora/assets without Laravel; Meta::extend() for schema extension; the binding contracts for non-Laravel binders. Everything in Infrastructure\Laravel is a Laravel-flavoured implementation of one of these — treat them as the seams, not the surface.

Upgrade expectation: pages, REST responses and the output of pollora:meta:*, pollora:binding:list, pollora:roles:* and pollora:doctor are unchanged in this release. If any of those differ after upgrading, it is a bug, not a migration — and the query 2.0 changes are the first place to look. v13.38.1 is a fixes-only patch on top of that line: it adds a Site Health check and one pollora:doctor warning, so the only expected new output is on sites whose .env is reachable or whose APP_URL lacks a scheme — both are findings you want, not regressions.

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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo