jacobjoergensen/laravel-paper/laravel-paper-development
Claude Code and agent skill by jacobjoergensen/laravel-paper
- community
Checking that the SKILL.md file is still in the repository.
Build and work with Laravel Paper flat-file Eloquent models, including the #[Driver] and #[ContentPath] attributes, slug-based keys, querying, writing, and relationships.
Install
npx vskill@latest install jacobjoergensen/laravel-paper/laravel-paper-developmentSKILL.md
Laravel Paper Development
Laravel Paper adds a flat-file driver to Eloquent. Markdown, JSON, and YAML files in a content directory become queryable, writable Eloquent models, configured with PHP 8 attributes and the Paper trait instead of a database connection or migration.
When to use this skill
Use this skill when a model uses the JacobJoergensen\LaravelPaper\Paper trait, or when adding, querying, or writing the flat files that back those models.
For underlying Eloquent and Laravel behavior, use Boost's search-docs tool. This skill only covers what Paper does differently.
Defining a model
A Paper model extends Model, uses the Paper trait, and declares its format and content directory with two attributes.
markdownfrontmatter becomes attributes, the body is exposed ascontent.jsonandyamltop-level keys become attributes.yamlreads.yamland.yml.#[Driver]defaults tomarkdown,#[ContentPath]defaults tocontent.
The slug is the primary key
The filename without its extension is the slug, and the slug is the primary key. There is no auto-incrementing id.
To change a slug, rename the file. For a public URL that differs from the filename, add a frontmatter field (e.g. permalink) and route on that instead of the slug.
Querying
Query Paper models with the standard Eloquent query API.
where and orWhere take an array of conditions, combined with and. With orWhere the or applies to the whole array, so orWhere([['a', 1], ['b', 2]]) needs both to match.
Paper adds whereContains for array-field membership. It matches rows where the array attribute includes the given value:
Local query scopes work, including ones declared with Laravel's #[Scope] attribute. The scope receives Paper's query builder, so type-hint PaperQueryBuilder, not Eloquent's Builder:
Global scopes work through addGlobalScope and #[ScopedBy], and cover find and route model binding too. A scope is a Closure taking PaperQueryBuilder or a class implementing ScopeContract. Eloquent's Scope is ignored. An or in the query cannot widen past a scope, unlike in Eloquent.
#[CollectedBy] is also respected, so queries return your model's custom collection.
Large result sets
A query lists every file and builds a model per record it checks, parsing only files changed since they were cached. Prefer lazy over get, and simplePaginate over paginate on a filtered query, since counting the matches is what costs.
Route model binding
{post} binds on the slug, {post:title} on any frontmatter field. Scoped child bindings resolve through the parent's hasManyPaper relation, named after the plural of the parameter.
Aggregates
count, min, max, sum, avg, and the average alias work on the model and the query builder. They read through casts and ignore orderBy/limit/offset, like SQL.
sum and avg skip null, missing, and non-numeric values. min and max skip only null and compare the rest with PHP's rules, so a column mixing numbers and text can return the text.
countBy counts a column's distinct values into a collection, flattening array fields like tags.
Casts
Eloquent casts work as usual. array, json, object, and collection read and write native YAML or JSON structures rather than encoded strings, so files stay hand-editable.
Writing
Save and delete go through the standard Eloquent API and fire the usual model events; loading a record fires retrieved.
create, firstOrCreate, and updateOrCreate work from an attribute array. Like any Eloquent model, these use mass assignment, so set $fillable (or $guarded = []) on the model. The array must include the slug, since it is the key:
Bulk update writes each matching file in a loop. Model events fire per record, $fillable does not apply, and it is not a single atomic operation:
Timestamps
Paper models have no timestamps unless you add #[Timestamps], which exposes the file's modification time as updated_at.
updated_at comes from the file's mtime and is never written to frontmatter. created_at is not derived; set it as a frontmatter field if you need it. A Git checkout resets mtimes to deploy time, so use #[Timestamps] for content edited in place and keep a frontmatter date for Git-deployed content.
Relationships
Use belongsToPaper and hasManyPaper, and call them as methods, not properties.
Foreign keys default to {model}_slug (e.g. author_slug); pass a second argument to override.
Validation
Use PaperRule with Laravel's validator:
Custom drivers
markdown, json, and yaml are registered by default. To support another format, implement DriverContract (extensions, parse, serialize) and register it in a service provider's boot method, then point a model at it with #[Driver('toml')].
parse takes the file path and returns the attributes. serialize returns the file contents.
Order extensions() deliberately. New records are written with the first one, and when a slug exists under several, the first one wins.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingresources/boost/skills/laravel-paper-development/SKILL.md
Popularity
- Repository stars
- 102
- Repository forks
- 1
- 7-day trend score
- 23
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/jacobjoergensen/laravel-paper/laravel-paper-development)