/'\
/ \
/ \
_ / ..' \_ /\/'\
/ \ / './ \ / \
_/ \ / \ _ / oO \
/'\ / '._'\ / \ / \ / /''\
/ \ / \ / / \ / \ / \_ ..' \
/ \ / \__ / / \ / \__/ \
\/ \ / / \/__ \ \
\ \/ __/ \ \ \
\ / \ \
)))) \__
_________ _______ __ooO_(O o)_Ooo____
| \ \ / | (_) \\===========\===========\
| __ \ \ / | __ | | |
| |__) \ V /| |__) | | |
| |\ / | < ┌┴┐ ┌┴┐
| ___/ | | | \ _ \ \ / |
| | | | | |\ \ | \_| | | \_
| | | | | | \ \ \___/ __ \ `-_
|_______| |_________| |______| |______| / \ ''-. \
____ __ __ ____ _ ___ ___ ____ / / \ \
| \ | | || || | | \ / _|| \ | | | |
| () )| | | | | | |\\\\ \ / |_ | () ) \ \ / /
| || | | | | | ( oo) () || _|| / \ `-..-' /
| () || : | | | | (_) || |_ | \ - -- '-_ _-'
|_____| \__,_||____||____||_____||_____||__|\_| `------'
Addons scaffolder for maximum coding pleasure - -- --------- -- -
This PyroCMS 3 extension once installed becomes your coding companion to scaffold Pyro modules, themes, extensions and stream entities.
Here are some of the thoughts and reasons behind building the builder extension,
From the prospective of a developer, Pyro 3 reduces complexity and introduces simplicity and structure into building large scale web applications with its modular design, Modules, Extension, etc and data structure abstraction (ATD), realized in the Stream Platform,
However, with structure comes repetition and the need to use boilerplate code combined with predefined set of steps to integrate that with your application. Usually this is all covered in the documentation, but who has time for that?
This extension tries to remove some of that tedious work so that the developer can focus on writing business logic of the application. To achieve that, the builder offers a number of commands and provide scaffolders for the different aspects of building a Pyro application,
For examples, once installed, the extension will scaffold a software structure called Entity for every stream migration generated with the make:stream
command. The code generated includes Models
, Repositories
, Table Builders
, Form Builders
, Admin Controllers
, Seeders
to name a few. And with the help of a PHP parser, it will configure the module classes with routes, bindings, language file entries and even seeding and even helper functions.
In your project folder, require the extension with composer
and then install as follows,
composer require websemantics/builder-extension
php artisan extension:install websemantics.extension.builder
The first command to use when developing a Pyro application with the builder extension is make:addon
. The default make:addon
command has been extended to enable template-based code scaffolding.
Use the make:addon
command as per usual, documentation to create modules, themes and other addon types. However, there are two new concepts that this extension introduces,
1- A default template is prescribed for each addon type (if available) that the builder downloads and uses to generate code.
2- Each template come with a schema (a list of variable, for example, vendor
, slug
etc) that the builder uses to scaffold code. These variables have default values but the user will be ask to change their values interactively unless the --defaults
option is used to skip the process.
php artisan make:addon vendor.module.name
The previous command creates a module based on the default module template. The downloaded module template will be cached at storage/streams/default/builder/default-module
.
NOTE: A fields migration file will not be generated as per Pyro 3 default make:addon
command behaviour. The builder extension generates a separate fields migration file for each stream migration instead.
There are two templates to generate a theme addon, an admin and a front-end.
php artisan make:addon vendor.theme.name --force --admin
The --force
option forces the extension to download a fresh copy of the template and --admin
to create an admin theme. Omit --admin
option to create a front-end theme.
The previous uses of make:addon
make assumptions about the template to use when creating the addon (default module, pyrocms-theme etc). This behaviour can be changed by providing an optional template name, default-module
as follows,
php artisan make:addon websemantics.module.name default-module --defaults
The defaults
options disables the user interactive mode and forces the template defaults. This command also supports --shared
and --migrate
options.
A template is like a recipe that the extension uses to scaffold code for an addon type, or any software package for that matter,
php artisan make:addon websemantics.module.name --template
The previous command will create a template for the specified addon type, defaults
and uses vendor
and slug
provided as default values for the template schema. More details about templates and how to use them locally can be found at template-template documentation.
This command will list all available addon templates from the registry,
php artisan builder:list
Result,
____ __ __ ____ _ ___ ___ ____
| \ | | || || | | \ / _|| \
| () )| | | | | | |\\\\ \ / |_ | () )
| || | | | | | ( oo) () || _|| /
| () || : | | | | (_) || |_ | \
|_____| \__,_||____||____||_____||_____||__|\_|
Addons scaffolder for maximum coding pleasure
Builder Commands:
- make:addon Create an addon from a template if avilable
- builder:list List available templates from the registry
- builder:clear Clear cache and locally stored templates
Retrieving a list of available templates
+-------------------+-----------------------------------------------------------------------+---+
| Name | Description | ★ |
+-------------------+-----------------------------------------------------------------------+---+
| default-module | The default module template for Pyro Builder | 2 |
| default-skin | The default skin template for PyroCMS Plus Theme | 0 |
| pyrocms-theme | A customizable release of the official PyroCMS admin theme | 2 |
| starter-theme | A customizable release of PyroCMS started theme | 4 |
| template-template | The default Pyro Builder template for building Pyro Builder templates | 3 |
+-------------------+-----------------------------------------------------------------------+---+
Notice how each template has one star only! :/ Well, you can change that by liking these repos here :)
To clear the builder cache and delete all locally downloaded templates run the following command,
php artisan builder:clear
The builder introduces new abilities to make:stream
command, for example, to specify stream properties and fields,
Using the example provided in Auto-pyro to create a todo module, the following will create a Task
stream and all of it's assignments,
php make:stream 'task:tc(name),name,description:t(anomaly.field_type.textarea),completed:t(anomaly.field_type.boolean)' websemantics.module.todo
Instead of specifying the stream slug
only, make:stream
command now accepts a comma-separated list of fields following the stream slug and properties.
The following is a complete list of options available to use with streams and field. Option values - if applicable - are provided between parentheses (as in the example above),
Property | Shorthand | Inheritable |
---|---|---|
title_column | tc |
◻️ |
type | t |
◻️ |
required | r |
◻️ |
unique | u |
◻️ |
searchable | s |
◻️ |
locked | l |
◻️ |
translatable | trans |
✅ |
trashable | trash |
✅ |
sortable | sor |
✅ |
The Inheritable
column indicates the properties a stream would inherit if one of its fields has it set to true. For example,
# First, generate the module
php artisan make:addon vendor.module.name
# Then generate the stream migration files
php artisan make:stream 'comment:title_column(name),name:trans' vendor.module.name
# This can also be expressed as
php artisan make:stream 'comment:title_column(name),name:translatable(true)' vendor.module.name
# Or as,
php artisan make:stream 'comment:title_column(name):translatable(true),name:type(anomaly.field_type.text):translatable(true)' vendor.module.name
The previous will generate a stream migration as follows,
protected $stream = [
'slug' => 'comment',
'title_column' => 'name',
'translatable' => true
];
protected $assignments = [
'name' => [
'translatable' => true
]
];
If the type
property of a field is not set, the builder extension will assume anomaly.field_type.text
as default.
All environment variables used by the extension are listed here,
Variable | Description | Default |
---|---|---|
BUILDER_REGISTRY | The default Builder Extension registry | pyrocms-templates |
BUILDER_DEFAULT_TEMPLATE | Template of templates to create an addon template | template-template |
BUILDER_DEFAULT_MODULE | Default template for modules | default-module |
BUILDER_DEFAULT_ADMIN | Default template for admin themes | pyrocms-theme |
BUILDER_DEFAULT_FRONT | Default template for front-end themes | starter-theme |
BUILDER_TTL | Time used to cache an API call | 60 minutes |
BUILDER_PATH | Path to the local storage to cache templates | builder |
BUILDER_ARCHIVE_URL | Url to the compressed file of the template repo | url-template |
BUILDER_TMP | Temporary folder to uncompress zip files | folder |
MIGRATION_PADDING | Padding between arrays (key,value) s in migration file |
30 chars |
Configuration file can be found at, ./resources/config/config.php
. Overridden in project .env
file to change the default behaviour.
In addition to scaffolding addons from builder templates, the builder offers generating stream entities from migrations. An Entity is a representation of an Object Type which may correspond with a Stream. For example, a Person, a Company or an Animal can all be represented by Streams and Entities.
The code generated for an entity includes an Entity Model
and Repository
, Plugin
, Seeder
, Contracts
, Table Builder
and Form Builder
.
Please read the following section for a better understanding of this process.
The source code of this example is available here. The idea is to build a module with the least amount of effort and experience how the builder extension does its work,
- Create and install a new PyroCMS project and name it
blogger
,
# first, create a fresh pyro project and change folder,
composer create-project pyrocms/pyrocms --prefer-dist blogger
cd blogger
# install from the command line,
php artisan install
- Install the builder extension,
composer require websemantics/builder-extension
php artisan extension:install websemantics.extension.builder
- Create a new module,
blog
php artisan make:addon websemantics.module.blog
- Create
posts
stream and its fields,
php artisan make:stream 'posts:tc(title),title:r:u,content:r' websemantics.module.blog
The result,
protected $stream = [
'slug' => 'posts',
'title_column' => 'title'
];
protected $assignments = [
'title' => [
'required' => true,
'unique' => true
],
'content' => [
'required' => true,
]
];
This will also generate a seeder template for this entity (see below),
- Add seeder data to,
blog/addons/default/websemantics/blog-module/resources/seeders/post.php
(singular file name)
['title' => 'Laravel', 'content' => 'PHP framework'],
['title' => 'PyroCMS', 'content' => 'PHP CMS']
The content must be a list of entry values without <?php
. This will be added to the Entity Seeder class when the code is (re)generated. This process will be enhanced in the near future with better code parsing.
- Apply the changes by install/reinstall the module,
php artisan module:reinstall websemantics.module.blog
Check the admin panel to see the new Module in action, url: admin/blog/posts
.
The idea is to have a collection of reusable Pyro 3 addon templates that can be scaffolded from the command line, similar to what vue-cli offers.
For a full list of what's available through the Builder extension, check the registry at, PyroCMS Templates or use builder:list
artisan command.
Once the addon code have been generated and entity files per stream have been created and working correctly with Pyro, you might want to modify and develop the classes individually adding custom code,
The extension provides a configuration options to make your work easy, for example to list the files that you don't want to overwrite accidentally when re-installing a module to regenerating the entity code,
Another example, if you have edited the blog-module/src/Blog/Post/PostModel.php
, make sure to list that in the builder config file, blog-module/resources/config/builder.php
so that the extension will avoid overwriting these files if they exist.
Here's an example,
'avoid_overwrite' => [
'Model.php',
'Repository.php',
'TableColumns.php'
],
Notice how only the last part of the file name (omitted the entity name) is used so that this can be applied globally to all generated entities of the same type,
The Builder extension offers many configuration options to fine-tune and enhance your development experience which can be found at blog-module/resources/config/builder.php
.
- Add a list of namespaces supported,
'namespaces' => [
'blog' => [],
'discussion' => []
]
This indicates to the builder extension the stream namespaces
that your module supports. Add namespaces to this list as appropriate.
- Group entities code under a namespace folder,
When code is generated for an entity, the builder extension saves it under src/{namespace}
by default. This is useful when your module handles streams from different namespaces,
To change this behaviour and store under the module src/
folder directly, set the group
option to false
,
'group' => true,
- To seed after a successful install, set the
seed
option inbuilder.php
,
'seed' => true
Turn on and off with true
/ false
values as needed.
- To generate fields and streams permissions set
permissions
to true,
'permissions' => true
- To generate sitemap, set the stream_slug for the module main stream, for example
pages
stream,
'sitemap' => [ 'stream_slug' => 'pages',
'url_method' => '->getPath()',
'entries_method' => '->accessible()->visible()',
'priority' => 0.5,
'frequency' => 'monthly',
'images' => '[]',
'title' => 'null'
],
The url_method
is used to retrieve the resource path, and entries_method
should return a filtered collection of stream entries.
- Specify your project docblock to be included with the generated classes,
'docblock' =>
' * @link http://yourcompany.com
* @author name, <[email protected]>'
More settings are detailed in the builder.php file.
Once installed, this extension listens mainly to three event types, StreamWasCreated, AssignmentWasCreated and ModuleWasInstalled.
To enable this extension for your current module, create a config file at resources/config/builder.php
and list the namespaces you would like the extension to generate code for. You can listen/generate code to multiple namespaces.
'namespaces' => ['blogger', 'navigation', 'etc']
Here's an example of the builder config file taken from Boxed example module github repo.
Once that's done, create your streams migration files as usual. The extension will kick in when it receives the events listed above,
- For StreamWasCreated event, the extension will generate an entity folder for the stream from the template stored at
builder-extension/resources/assets/entity/code
. The folder map of the entity is as follows:
BlogEntity
|
+-- Contract
| |
| +--- BlogInterface.php
| |
| +--- BlogRepositoryInterface.php
|
|
+-- Form
| |
| +--- BlogFormBuilder.php
|
|
+-- Table
| |
| +--- BlogTableBuilder.php
| |
| +--- BlogTableColumns.php
|
|
+---- BlogModule.php
|
+---- BlogRepository.php
|
+---- BlogSeeder.php
|
+---- BlogPlugin.php
By default, this folder structure would be generated in a subfolder at src
. The name of the subfolder is the namespace of the created stream as explained above.
The extension will then generate a controller per entity at blog-module/src/Http/Controller/Admin/BlogController.php
and modify Module
, ServiceProvider
, Seeder
classes and language files to setup the entity to work correctly with the module.
-
For AssignmentWasCreated event, the extension will modify two files,
BlogTableColumns.php
andBlogFormBuilder.php
and add afield
slug per stream assignment. -
For ModuleWasInstalled event, this will add
routes
andsections
to the module and service provider. It will also seed the module if the builder config file was set accordingly.
To generate screen recordings, follow these steps,
- Install Asciinema and Asciinema 2 Gif
brew install asciinema
brew install asciinema2gif
Record a screencast and convert it to a gif image,
asciinema rec -y -t "title"
asciinema2gif --size small --speed 3 https://asciinema.org/api/asciicasts/{{id}}
The asciinema
command will generate a url to the recording, for example, https://asciinema.org/a/e32g9nqayq1dqb9txd063ez8m
. Replace the {{id}}
in the url provided for asciinema2gif
with the one unique id from asciinema
url, e32g9nqayq1dqb9txd063ez8m
. Read the documentations for more details regarding valid url formats.
Copy the generated file asciicast.gif
from the current directory to the desired location.
Need help or have a question? post a questions at StackOverflow
Please don't use the issue trackers for support/questions.
Well finally, we are more than happy to accept external contributions to the project in the form of feedback, bug reports and even better - pull requests :)
- Auto Pyro, a PyroCMS deploy tool for faster development experience.
- Template Template, The default Pyro Builder template for building Pyro Builder templates.
- Registry,a list of all Pyro Builder available template.
- Awesome PyroCMS, a curated list of PyroCMS addons and resources.
- PyroCMS Cheatsheet, A list of commands and features for PyroCMS 3.
- PyroCMS, an MVC PHP Content Management System built to be easy to use, theme and develop with. It is used by individuals and organizations of all sizes around the world.
MIT license Copyright (c) Web Semantics, Inc.