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

Statamic Position Fieldtype Laravel Package

rias/statamic-position-fieldtype

A Statamic addon that adds a Position fieldtype for selecting and storing position values in the control panel. It integrates with Statamic’s fieldtype system to give editors a simple way to define positions in their content.

View on GitHub
Deep Wiki
Context7

Getting Started

The addon is deliberately small: a Statamic fieldtype that stores a numeric position so editors can control ordering of entries/terms by hand instead of relying on dates or titles. Treat it as a convenience wrapper around an integer field, not as a full drag-and-drop ordering system.

  1. Check compatibility before installing. The last tagged release is 2020-08-20, which predates Statamic 3.x's Vite move. Open composer.json on GitHub and look at the statamic/cms constraint — if it caps at ^3.0 or ^2.0, budget time for a fork.
  2. Install:
    composer require rias/statamic-position-fieldtype
    
    Statamic 3+ auto-discovers the service provider; on older versions add it to config/app.php providers.
  3. Look here first in the repo:
    • src/ServiceProvider.php — registers the fieldtype handle (that string is what you put in your blueprint).
    • src/Fieldtypes/*.php — component(), preProcess()/process(), and any rules().
    • resources/js/components/*.vue — the CP UI; this is where a Vue 2 → Vue 3 port would be needed.
    • Any config/ or resources/views/ — often absent in addons this size.
  4. First use case — manual ordering of blog posts:
    # resources/blueprints/collections/blog_post.yaml
    position:
      type: position
      display: Position
      instructions: Lower numbers appear first.
      default: 0
    
    Then render ordered:
    {{ collection:blog_post sort="position" }}
      ...
    {{ /collection:blog_post }}
    
    If the fieldtype name differs in the service provider, use that handle instead of position.

Implementation Patterns

Ordering by position everywhere. The fieldtype itself does nothing until you sort by it. Use sort="position" in Antlers, or in PHP:

Entry::query()
    ->where('collection', 'blog_post')
    ->orderBy('position')
    ->orderBy('title')
    ->get();

Tie-breaking is mandatory in practice. Two entries with position: 0 (the default) will fall back to insertion/mtime order, which looks random to editors. Always chain a secondary sort (position|title, or a second orderBy).

Pair it with explicit ordering in the blueprint. Put the field in a sidebar tab and set instructions describing the direction (ascending vs descending). A position field without guidance is a support ticket generator.

Bulk reordering workflow. For anything longer than ~20 items, a single number field is painful. Two patterns that work:

  • Add a simple CP action/route that takes an array of IDs and writes sequential positions (10, 20, 30… in steps of 10). Steps of ten leave room for manual inserts without renumbering everything.
  • If you need real drag-and-drop, skip this addon and build a custom listing view or use a dedicated ordering addon — you'll end up writing the same PHP anyway.

Scoping positions. Positions are per-entry, so a single position handle in a shared blueprint across collections shares a number space. If you have a "featured" section and a "regular" section, either use two fields (featured_position, position) or scope your query with a where on a category/flag and only then sort.

Multi-site. Position lives on the entry, so it's shared across sites unless you localize the field. If editors need per-locale ordering, mark the field as localizable in the blueprint and verify how the addon's process() handles localization before relying on it.

API / GraphQL output. The stored value is a scalar; if you expose it via GraphQL or the REST API, cast it to int in an augmentation or in your transformer so clients don't receive "10" and sort lexicographically.

Gotchas and Tips

The maintenance risk is the headline. One star, zero dependents, last release August 2020. Read the source before adopting — it's likely under 200 lines, which makes forking trivial and also makes the addon replaceable. If the Vue component fails to load under a modern CP build, porting it is a couple of hours, not days.

Stache/YAML casts numbers to strings. Sorting "2" after "10" is the classic symptom. Cast on read:

->sortBy(fn ($entry) => (int) $entry->get('position'))

or normalize in process() in your fork.

Nulls and zeros sort unpredictably. Depending on the driver, NULL may come first or last. Always backfill existing content (php please command or a one-off Stache update) after adding the field, rather than trusting the default: to apply retroactively — it doesn't for existing entries.

Cache invalidation. Statamic's collection/Stache cache will happily serve stale ordering after a bulk reorder. Run php please stache:refresh (and clear any response cache) when testing reorder logic; otherwise you'll debug code that was already correct.

Validate uniqueness server-side if it matters. The fieldtype won't stop two entries claiming position 5. If your layout breaks on duplicates, add a validation rule or normalize positions in a save hook.

Watch the component registration. If the fieldtype renders as a plain text input in the CP, the JS asset isn't loading — check the published assets / vendor:publish and the browser console for a missing Fieldtype.vue chunk. This is the most common failure mode after a Statamic upgrade.

Extension points are limited, which is fine. There's no meaningful config surface here. The realistic extension path is: fork, keep the PHP class, replace the Vue component with a numeric input plus up/down buttons, and add a rules() method returning ['integer', 'min:0']. At this package's size, the fork is cheaper than working around it.

Debugging ordering issues. Log the raw Stache file (storage/statamic/stache/...yaml) to see what was actually saved — it separates "the fieldtype saved the wrong value" from "my query sorts wrong", which are the only two failure categories this addon has.

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.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package