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

State Field Type Laravel Package

anomaly/state-field_type

A field type for the Anomaly Streams platform that adds a state selector to your forms, letting users choose a US state from a predefined list and save the selection to your stream entries.

View on GitHub
Deep Wiki
Context7

Getting Started

anomaly/state-field_type is a micro-addon for the Streams Platform (PyroCMS 3.x): a single field type that renders a dropdown of US states.

composer require anomaly/state-field_type
php artisan addon:install anomaly.field_type.state

If addon:install can't resolve the slug, check addon.json — the slug usually mirrors the composer name (anomaly.field_type.state) and the namespace follows the same convention.

Look here first, in this order:

  1. addon.json — the type (field_type) and any require block telling you the Streams version it was built against. This is the single best signal of whether it will work in your install.
  2. src/StateFieldType.php — the whole behaviour of the package is essentially $name, $slug, $inputView, getOptions() and getConfig(). Read all of it; it's short.
  3. resources/views/input.twig — confirms whether it renders a plain <select> or wraps a Streams select partial (affects how you style and how it behaves with required).
  4. resources/config/config.php and getConfig() — tells you which per-field options (default state, placeholder, "top options") actually exist.

First use case: add a state field to an existing address/contact stream in the admin (/admin/fields/create), pick the "State" type, assign it to the stream, then confirm the value round-trips on the entry form before writing any code against it. Do this on a scratch stream — with zero dependents and no maintenance signal, you want a failure to be cheap and obvious.

Implementation Patterns

Declaring the field in a migration (preferred over admin clicks, so the field is reproducible):

// streams/addons/{vendor}/{addon}/migrations/2024_01_01_120000_create_addresses_stream.php
public function up()
{
    $this->stream->create(['slug' => 'addresses', 'name' => 'Addresses']);

    $this->stream->addField('state', [
        'type'   => 'anomaly.field_type.state',
        'config' => [
            'required' => true,
            // confirm keys against getConfig() in the source
        ],
    ]);
}

Form builder (when you're building forms in PHP rather than stream-assigned fields):

$builder->add('state', 'anomaly.field_type.state', [
    'label'  => 'State / Province',
    'required' => true,
]);

Reading the value. The entry attribute returns the stored scalar; the field type object is reached via field():

$entry->state;                        // "CA" (or "California" — depends on the addon's storage format)
$entry->field('state')->getValue();   // same value, explicit
{{ entry.state }}                     // Twig

Validate against the same list the dropdown offers, or you'll get values in the DB that the UI can never produce:

$states = $entry->field('state')->getOptions(); // usually abbreviation => name

$request->validate([
    'state' => ['required', Rule::in(array_keys($states))],
]);

This is the pattern worth standardising on: one field type instance, one option list, used for the input, the request rule, and any API serialisation. If getOptions() is public (it almost certainly is), you can inject the field type or a small StateOptions wrapper rather than duplicating a states array.

Table/listing columns are free — the field type's outputView handles display in $builder->column('state'). Override the output view only if you need a badge or a full-name label instead of the stored abbreviation.

Reuse outside Streams (an API resource, a CSV import) is the one place this package stops paying for itself. The dropdown is the only thing it adds; if you need the list in a console command, import a static data set rather than booting a field type.

Gotchas and Tips

  • Zero stars, zero dependents, no release signal. Treat this as an unvetted fork of an idea rather than a maintained dependency. Before committing, diff the composer constraint against your Streams/Pyro version, install it on a throwaway branch, and confirm it registers. If it doesn't, the fallback is trivial: a plain anomaly.field_type.select with the 50 states as options config gives you 95% of the value with zero third-party risk. Keep that as your plan B, not your first move.
  • Storage format is the hidden contract. Abbreviation (CA) vs full name (California) is decided by getOptions() / the input view's value attribute. Check it before anyone enters data; switching later is a data migration, not a config change.
  • Column length. If it stores full names, make sure the underlying column isn't string(2) from an earlier abbreviation-based migration.
  • US-only, hardcoded. No Canadian provinces, no territories toggle, no country-conditional behaviour. For international forms you need your own field type or a select with a chained/conditional option set — don't try to bend this one.
  • Registration problems are almost always cache/addon state, not code. php artisan addon:install anomaly.field_type.state, then php artisan view:clear and php artisan cache:clear. If the type doesn't appear in the field-type dropdown, the addon isn't registered — check addon.json's namespace matches the directory under streams/addons/.
  • Override the views rather than editing vendor code: php artisan addon:publish anomaly.field_type.state, then edit the published Twig. Same for config.php. Anything you patch in vendor/ is lost on the next composer update.
  • Extension point is the field type class, not hooks. If you need province support or a searchable select, subclass StateFieldType, override getOptions() and $inputView, register it in your own addon, and switch the field's type to yours. That keeps the migration history intact.
  • Required validation. Field types often declare their own getRules(). If the dropdown has a placeholder like -- Select -- and the field isn't required, you'll store an empty string rather than null — normalise on save if downstream code uses whereNotNull.
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