qossmic/twig-doc-bundle
qossmic/twig-doc-bundle is a Symfony bundle that scans your Twig templates, extracts annotated documentation comments, and generates browsable HTML docs, helping teams keep template variables, blocks, and includes discoverable.
The package is config-driven: the primary surface area is a published config file where you declare "fake params" (key/value pairs used to generate or seed data). The v0.0.3 release is a small, additive semantic change to how values in that config are interpreted — an empty string ('') is now treated as a sentinel meaning "explicitly NULL".
Minimal steps:
composer require <vendor>/<package>
php artisan vendor:publish --tag=config
NULL, set the value to '' in your config rather than omitting the key.This release is non-breaking for existing users: previously an empty string was presumably passed through or ignored, so the only behavioural change applies to configs that already contain '' values. Audit those before upgrading.
Explicit NULL vs. omission. The core pattern introduced in 0.0.3 is the distinction between "this key is not configured" and "this key is configured to be NULL". Omission still means the package falls back to its default or skips the param; '' now means "deliberately NULL". Use this for nullable foreign keys, deleted_at, optional JSON columns, and any column where NULL is semantically different from 0, '', or a generated value.
Config layering. Keep package defaults untouched and express intent in config/<package>.php (or an environment-specific override). This makes the ''-means-NULL convention greppable and reviewable in diffs.
Seeder and factory integration. A common workflow is to define one param set per fixture scenario (minimal, realistic, edge_cases) and select it in seeders:
$this->seedParams = config('package.params.edge_cases');
Scenarios that need nulls become self-documenting instead of relying on post-generation ->update(['x' => null]) calls.
Testing. Use the explicit-null behaviour to build fixtures that exercise null-handling code paths (null-safe operators, whereNull, nullable casts) without hand-crafting data. Pair with RefreshDatabase and assert against assertDatabaseHas([... 'col' => null]).
Upgrade pattern. Before bumping to 0.0.3, grep your config for => '' or "". Any hit changes meaning. Where you genuinely wanted an empty string, you now need a different representation (see Gotchas).
'' is now a reserved sentinel. If any legitimate param value should be the empty string — e.g. a varchar default, a slug prefix, a CSV field — this release removes your ability to express it via config. Work around it by generating that value in code or wrapping it, and document the convention for your team.
Watch out for env() returning null. Laravel's env() helper converts the string null/empty to null, and an unset variable yields null, not ''. So 'param' => env('FAKE_PARAM', '') will produce null from the env helper and then be coerced by the package — you may end up with NULL when you expected "unset". Test this path explicitly.
isset() lies about nulls. Any code you write that inspects the resolved params must use array_key_exists($key, $params) rather than isset($params[$key]), otherwise explicit nulls look identical to missing keys — exactly the distinction this release exists to create.
Database constraints. Passing NULL into a non-nullable column will surface as an integrity constraint violation at seed time, not at config-validation time. If the package offers no validation, add a small test that generates one row per param set against a migrated schema.
Config caching. After editing the config, run php artisan config:clear (or config:cache again). Stale cached config is the most common reason "the new NULL behaviour isn't working". In CI, always regenerate the cache before running seeders.
Debugging. Dump the merged config (config('package.params')) rather than the raw file — package defaults and app overrides are merged, and it is easy to be surprised by which value won. Compare against the pre-upgrade output to confirm exactly which keys flipped to NULL.
Extension points. If you need richer semantics than "empty string means null", the cleanest route is usually a custom param resolver bound into the container (check the service provider for a bindable interface) or a decorator around the generator, rather than overloading the config convention further.
How can I help you explore Laravel packages today?