statamic/cms
Statamic is a flat-first, Laravel + Git powered CMS for building beautiful, easy-to-manage websites. Install this core Composer package into an existing Laravel app, or use the Statamic application repo/CLI for a preconfigured new project.
## Getting Started
### Minimal Setup
1. **Installation**:
```bash
composer require statamic/cms
Ensure you’re using Laravel 9+ and PHP 8.0+.
Publish Config:
php artisan vendor:publish --provider="Statamic\Providers\StatamicServiceProvider"
This generates config/statamic.php and config/statamic/fields.php.
First Use Case:
php artisan statamic:collection blog) and a blueprint (php artisan statamic:blueprint blog/entry).title, body) to the blueprint (resources/blueprints/collections/blog/entry.yaml)./admin./admin (credentials set in .env or config/statamic.php).php artisan statamic:install # For fresh installs
php artisan statamic:blueprint # Scaffold blueprints
php artisan statamic:field # Add custom fields
blog, products) with YAML-based blueprints.
# resources/blueprints/collections/blog/entry.yaml
title: Entry
fields:
- handle: title
field:
type: title
display: Title
- handle: body
field:
type: bard
display: Content
about) via php artisan statamic:singleton about.title, bard (WYSIWYG), assets, relationships, etc.
// In a blueprint or controller
use Statamic\Fields\Field;
$field = new Field('title', 'Title', 'title');
Statamic\Fields\Fieldtype:
namespace App\Fieldtypes;
use Statamic\Fields\Fieldtype;
class CustomField extends Fieldtype {
public function field() {
return new \Statamic\Fields\Field('custom_field', 'Custom Field', 'custom');
}
}
Register in config/statamic/fields.php:
'custom' => \App\Fieldtypes\CustomField::class,
{{ }} for dynamic content in templates (resources/views/).
<h1>{{ title }}</h1>
<div>{{ body }}</div>
@include:
@include('partials/header')
@foreach(collections.blog.entries as entry)
<article>
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
</article>
@endforeach
/admin/assets).{{ asset('filename.jpg') }} or programmatically:
$asset = asset('filename.jpg');
echo $asset->url();
php artisan statamic:preset):
# config/statamic/asset_containers/my_container/presets.yaml
thumbnails:
width: 300
height: 200
fit: crop
relationship fields in blueprints.
fields:
- handle: author
field:
type: relationship
display: Author
collections: [authors]
@set author = entry.author.first()
<p>By {{ author.name }}</p>
config/statamic/nav.yaml:
items:
- url: /blog
title: Blog
icon: blog
nav in Antlers:
@nav
@item('/blog', 'Blog')
@item('/about', 'About')
@endnav
nav:breadcrumbs now works correctly for multi-site setups.fields:
- handle: contact_form
field:
type: form
display: Contact Form
submit_button: Send Message
statamic:form in views:
{{ form('contact') }}
{{ csrf_field() }}
{{ text('name') }}
{{ email('email') }}
{{ submit }}
{{ /form }}
statamic-forms publish command.config/statamic/locales.php:
'locales' => [
'en' => 'English',
'es' => 'Spanish',
],
localized fields in blueprints:
fields:
- handle: title
field:
type: title
localized: true
/api/v1/collections/{handle}/entries.config/statamic.php:
'graphql' => true,
Query entries:
query {
entries(collection: "blog") {
title
body
}
}
resources/views/vendor/statamic/cp/.app/Widgets/ and register in config/statamic.php:
'widgets' => [
\App\Widgets\CustomWidget::class,
],
statamic:extend in service providers:
Statamic::extend(function () {
Statamic::cp()->extend(function ($cp) {
$cp->nav->add('custom', 'Custom', 'custom-icon');
});
});
config/statamic.php:
'blueprints' => [
'path' => 'custom/blueprints/path',
],
Caching Quirks:
php artisan statamic:clear-caches
{{ cache }} in Antlers to control caching:
{{ cache(60) }}
{{ expensive_query }}
{{ /cache }}
Field Validation:
fields:
- handle: email
field:
type: email
validate:
- required
- email
Statamic\Fields\Fieldtype.Asset Permissions:
storage/ and public/ are writable:
chmod -R 775 storage/ public/
php artisan storage:link for public assets.Relationship Loops:
A → B → A). Use lazy loading:
@set entry = entry.relationship.lazy()
Antlers Parsing:
{{ 'raw' | raw }} to avoid parsing:
{{ '{{ title }}' | raw }}
@set for dynamic variables:
@set dynamic_var = 'value'
{{ dynamic_var }}
CP Navigation:
config/statamic.php:
'enforce_trailing_slashes' => false,
How can I help you explore Laravel packages today?