-
Notifications
You must be signed in to change notification settings - Fork 554
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
407 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
--- | ||
pageClass: twill-doc | ||
--- | ||
|
||
# Prefill a block editor from a selection of templates | ||
|
||
Objectives: | ||
|
||
- Create a new module with a `template` field | ||
- Prefill the block editor for new items according to the selected template | ||
|
||
Versions used at the time of writing: | ||
|
||
| | Version | | ||
|:-----------|:-------:| | ||
| PHP | 8.0 | | ||
| Laravel | 8.x | | ||
|
||
## Create the new module | ||
|
||
``` | ||
php artisan twill:make:module articles -B | ||
``` | ||
|
||
We'll make sure to enable blocks on the module, everything else is optional. In this example, we won't be using | ||
translations, but they can be added with minor changes. | ||
|
||
|
||
## Update the migration | ||
|
||
We'll add the `template` field to the generated migration: | ||
|
||
<<< @/src/guides/prefill-block-editor-from-template/2021_09_19_131244_create_articles_tables.php{16} | ||
|
||
Then, we'll run the migrations: | ||
``` | ||
php artisan migrate | ||
``` | ||
|
||
and add the module to our `routes/admin.php` and `config/twill-navigation.php`. | ||
|
||
|
||
## Update the model | ||
|
||
In this example, we imagine 3 templates that our authors can choose from: | ||
|
||
- Full Article: an original article on our blog | ||
- Linked Article: a short article to summarize and share interesting articles from other blogs | ||
- Empty: a blank canvas | ||
|
||
|
||
We'll start by adding our new field to the fillables: | ||
|
||
`app/Models/Article.php` | ||
|
||
<<< @/src/guides/prefill-block-editor-from-template/Article.php#fillable{6} | ||
|
||
Then, we'll define some constants for our template options: | ||
|
||
<<< @/src/guides/prefill-block-editor-from-template/Article.php#constants | ||
|
||
We'll add an attribute accessor to get the template name for the currently selected template value: | ||
|
||
<<< @/src/guides/prefill-block-editor-from-template/Article.php#accessor | ||
|
||
This will be useful in our `create.blade.php` view below. | ||
|
||
## Add the `template` field to the create modal | ||
|
||
When running `php artisan twill:make:module`, we get a `form.blade.php` to define the main form for our module. In addition, it's also possible to redefine the fields that are displayed in the create modal, before the form: | ||
|
||
![01-create-modal](./prefill-block-editor-from-template/create-modal.png) | ||
|
||
We'll copy Twill's built-in view from `vendor/area17/twill/views/partials/create.blade.php` into our project, then add our `template` field: | ||
|
||
`resources/views/admin/articles/create.blade.php` | ||
|
||
<<< @/src/guides/prefill-block-editor-from-template/articles_create.blade.php | ||
|
||
## Create some blocks | ||
|
||
``` | ||
php artisan twill:make:block article-header | ||
php artisan twill:make:block article-paragraph | ||
php artisan twill:make:block article-references | ||
php artisan twill:make:block linked-article | ||
``` | ||
|
||
::: details blocks/article-header.blade.php | ||
<<< @/src/guides/prefill-block-editor-from-template/blocks_article-header.blade.php | ||
::: | ||
|
||
::: details blocks/article-paragraph.blade.php | ||
<<< @/src/guides/prefill-block-editor-from-template/blocks_article-paragraph.blade.php | ||
::: | ||
|
||
::: details blocks/article-references.blade.php | ||
<<< @/src/guides/prefill-block-editor-from-template/blocks_article-references.blade.php | ||
::: | ||
|
||
::: details blocks/linked-post.blade.php | ||
<<< @/src/guides/prefill-block-editor-from-template/blocks_linked-post.blade.php | ||
::: | ||
|
||
## Add the editor to our form | ||
|
||
We'll add the block editor field to our form: | ||
|
||
`resources/views/admin/articles/form.blade.php` | ||
|
||
<<< @/src/guides/prefill-block-editor-from-template/articles_form.blade.php{10-12} | ||
|
||
## Prefill the blocks on create | ||
|
||
With this, all that's needed is to initialize the block editor from the selected template. We'll update our model to add the prefill operation: | ||
|
||
`app/Models/Article.php` | ||
|
||
<<< @/src/guides/prefill-block-editor-from-template/Article.php#prefill | ||
|
||
Then, we'll hook into the repository's `afterSave()`: | ||
|
||
<<< @/src/guides/prefill-block-editor-from-template/ArticleRepository.php{22-29} | ||
|
||
The check on `$object->wasRecentlyCreated` ensures the prefill operation will only run when the record is first created. | ||
|
||
## Finished result | ||
|
||
And there we have it Ñ a templating mechanism for our block editor: | ||
|
||
![02-edit-form](./prefill-block-editor-from-template/final.png) |
34 changes: 34 additions & 0 deletions
34
...rc/guides/prefill-block-editor-from-template/2021_09_19_131244_create_articles_tables.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
|
||
use Illuminate\Database\Migrations\Migration; | ||
use Illuminate\Database\Schema\Blueprint; | ||
|
||
class CreateArticlesTables extends Migration | ||
{ | ||
public function up() | ||
{ | ||
Schema::create('articles', function (Blueprint $table) { | ||
createDefaultTableFields($table); | ||
|
||
$table->string('title', 200)->nullable(); | ||
$table->text('description')->nullable(); | ||
$table->integer('position')->unsigned()->nullable(); | ||
$table->text('template')->nullable(); | ||
}); | ||
|
||
Schema::create('article_slugs', function (Blueprint $table) { | ||
createDefaultSlugsTableFields($table, 'article'); | ||
}); | ||
|
||
Schema::create('article_revisions', function (Blueprint $table) { | ||
createDefaultRevisionsTableFields($table, 'article'); | ||
}); | ||
} | ||
|
||
public function down() | ||
{ | ||
Schema::dropIfExists('article_revisions'); | ||
Schema::dropIfExists('article_slugs'); | ||
Schema::dropIfExists('articles'); | ||
} | ||
} |
98 changes: 98 additions & 0 deletions
98
docs/src/guides/prefill-block-editor-from-template/Article.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
<?php | ||
|
||
namespace App\Models; | ||
|
||
use A17\Twill\Models\Behaviors\HasBlocks; | ||
use A17\Twill\Models\Behaviors\HasFiles; | ||
use A17\Twill\Models\Behaviors\HasMedias; | ||
use A17\Twill\Models\Behaviors\HasPosition; | ||
use A17\Twill\Models\Behaviors\HasRevisions; | ||
use A17\Twill\Models\Behaviors\HasSlug; | ||
use A17\Twill\Models\Behaviors\Sortable; | ||
use A17\Twill\Models\Model; | ||
use A17\Twill\Repositories\BlockRepository; | ||
|
||
class Article extends Model implements Sortable | ||
{ | ||
use HasBlocks; | ||
use HasSlug; | ||
use HasMedias; | ||
use HasFiles; | ||
use HasRevisions; | ||
use HasPosition; | ||
|
||
// #region constants | ||
public const DEFAULT_TEMPLATE = 'full_article'; | ||
|
||
public const AVAILABLE_TEMPLATES = [ | ||
[ | ||
'value' => 'full_article', | ||
'label' => 'Full Article', | ||
'block_selection' => ['article-header', 'article-paragraph', 'article-references'], | ||
], | ||
[ | ||
'value' => 'linked_article', | ||
'label' => 'Linked Article', | ||
'block_selection' => ['article-header', 'linked-article'], | ||
], | ||
[ | ||
'value' => 'empty', | ||
'label' => 'Empty', | ||
'block_selection' => [], | ||
], | ||
]; | ||
|
||
// #endregion constants | ||
|
||
public const AVAILABLE_BLOCKS = ['article-header', 'article-paragraph', 'article-references', 'linked-article']; | ||
|
||
// #region fillable | ||
protected $fillable = [ | ||
'published', | ||
'title', | ||
'description', | ||
'position', | ||
'template', | ||
]; | ||
|
||
// #endregion fillable | ||
|
||
public $slugAttributes = [ | ||
'title', | ||
]; | ||
|
||
// #region accessor | ||
public function getTemplateLabelAttribute() | ||
{ | ||
$template = collect(static::AVAILABLE_TEMPLATES)->firstWhere('value', $this->template); | ||
|
||
return $template['label'] ?? ''; | ||
} | ||
|
||
// #endregion accessor | ||
|
||
// #region prefill | ||
public function getTemplateBlockSelectionAttribute() | ||
{ | ||
$template = collect(static::AVAILABLE_TEMPLATES)->firstWhere('value', $this->template); | ||
|
||
return $template['block_selection'] ?? []; | ||
} | ||
|
||
public function prefillBlockSelection() | ||
{ | ||
$i = 1; | ||
|
||
foreach ($this->template_block_selection as $blockType) { | ||
app(BlockRepository::class)->create([ | ||
'blockable_id' => $this->id, | ||
'blockable_type' => static::class, | ||
'position' => $i++, | ||
'content' => '{}', | ||
'type' => $blockType, | ||
]); | ||
} | ||
} | ||
|
||
// #endregion prefill | ||
} |
30 changes: 30 additions & 0 deletions
30
docs/src/guides/prefill-block-editor-from-template/ArticleRepository.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?php | ||
|
||
namespace App\Repositories; | ||
|
||
use A17\Twill\Repositories\Behaviors\HandleBlocks; | ||
use A17\Twill\Repositories\Behaviors\HandleSlugs; | ||
use A17\Twill\Repositories\Behaviors\HandleMedias; | ||
use A17\Twill\Repositories\Behaviors\HandleFiles; | ||
use A17\Twill\Repositories\Behaviors\HandleRevisions; | ||
use A17\Twill\Repositories\ModuleRepository; | ||
use App\Models\Article; | ||
|
||
class ArticleRepository extends ModuleRepository | ||
{ | ||
use HandleBlocks, HandleSlugs, HandleMedias, HandleFiles, HandleRevisions; | ||
|
||
public function __construct(Article $model) | ||
{ | ||
$this->model = $model; | ||
} | ||
|
||
public function afterSave($object, $fields) | ||
{ | ||
parent::afterSave($object, $fields); | ||
|
||
if ($object->wasRecentlyCreated) { | ||
$object->prefillBlockSelection(); | ||
} | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
docs/src/guides/prefill-block-editor-from-template/articles_create.blade.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
@formField('input', [ | ||
'name' => $titleFormKey ?? 'title', | ||
'label' => $titleFormKey === 'title' ? twillTrans('twill::lang.modal.title-field') : ucfirst($titleFormKey), | ||
'required' => true, | ||
'onChange' => 'formatPermalink' | ||
]) | ||
|
||
@if ($item->template ?? false) | ||
{{-- | ||
On update, we show the selected template in a disabled field. | ||
For simplicity, templates cannot be modified once an item has been created. | ||
--}} | ||
|
||
@formField('input', [ | ||
'name' => 'template_label', | ||
'label' => 'Template', | ||
'disabled' => true, | ||
]) | ||
@else | ||
{{-- | ||
On create, we show a select field with all possible templates. | ||
--}} | ||
|
||
@formField('select', [ | ||
'name' => 'template', | ||
'label' => 'Template', | ||
'default' => \App\Models\Article::DEFAULT_TEMPLATE, | ||
'options' => \App\Models\Article::AVAILABLE_TEMPLATES, | ||
]) | ||
@endif | ||
|
||
@if ($permalink ?? true) | ||
@formField('input', [ | ||
'name' => 'slug', | ||
'label' => twillTrans('twill::lang.modal.permalink-field'), | ||
'ref' => 'permalink', | ||
'prefix' => $permalinkPrefix ?? '' | ||
]) | ||
@endif |
13 changes: 13 additions & 0 deletions
13
docs/src/guides/prefill-block-editor-from-template/articles_form.blade.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
@extends('twill::layouts.form') | ||
|
||
@section('contentFields') | ||
@formField('input', [ | ||
'name' => 'description', | ||
'label' => 'Description', | ||
'maxlength' => 100 | ||
]) | ||
|
||
@formField('block_editor', [ | ||
'blocks' => \App\Models\Article::AVAILABLE_BLOCKS, | ||
]) | ||
@stop |
18 changes: 18 additions & 0 deletions
18
docs/src/guides/prefill-block-editor-from-template/blocks_article-header.blade.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
@twillBlockTitle('Article Header') | ||
@twillBlockIcon('text') | ||
@twillBlockGroup('app') | ||
|
||
@formField('input', [ | ||
'name' => 'subtitle', | ||
'label' => 'Subtitle', | ||
]) | ||
|
||
@formField('input', [ | ||
'name' => 'author', | ||
'label' => 'Author', | ||
]) | ||
|
||
@formField('input', [ | ||
'name' => 'reading_time', | ||
'label' => 'Estimated Reading Time', | ||
]) |
10 changes: 10 additions & 0 deletions
10
docs/src/guides/prefill-block-editor-from-template/blocks_article-paragraph.blade.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
@twillBlockTitle('Article Paragraph') | ||
@twillBlockIcon('text') | ||
@twillBlockGroup('app') | ||
|
||
@formField('wysiwyg', [ | ||
'name' => 'text', | ||
'label' => 'Text', | ||
'placeholder' => 'Text', | ||
'toolbarOptions' => ['bold', 'italic', 'link', 'clean'], | ||
]) |
Oops, something went wrong.