An amazing feature of October is it’s ability to create forms using Yaml files. The data in these files automatically corresponds to the model in the database so the heavy lifting is done in the core of October. We have moved this function to the frontend allowing you to easily create forms and lists without code.
October's docs on:
This plugin is also included into the following bundle
Quick start
Prepare environment
- Install PowerComponents from MarketPlace
-
Include necessary tags to your layout:
initbiz/powercomponents/assets/ui/storm.css {% styles %} jquery initbiz/powercomponents/assets/js/powercomponents.js {% framework extras %} {% scripts %}
For example:
<head> <!-- Add PowerComponent Storm UI --> <link href="{{ ['$/initbiz/powercomponents/assets/ui/storm.css']|theme }}" rel="stylesheet"> <!-- Don't forget about additional styles --> {% styles %} <!-- load jQuery in head section --> <script src="{{ ['@jquery'] |theme }}"></script> </head> ... <!-- load PowerComponents JS, somewhere between jQuery and Framework --> <script src="{{ ['/plugins/initbiz/powercomponents/assets/js/powercomponents.js']|theme}}"> </script> <!-- October's AJAX Framework --> {% framework extras %} <!-- Don't forget about additional scripts --> {% scripts %}
Start with creating your first CRUD
Run php artisan pc:util create crud Initbiz.ExamplePlugin Client
and answer yes
to all questions.
DONE! :)
After running the command you will have:
Created and registered components in Initbiz.ExamplePlugin
plugin:
ClientCreate
ClientUpdate
ClientPreview
ClientList
Created pages in active theme with following URLs:
/clients
- which shows list of clients/clients/create
- which renders the 'create client' form/clients/:id/preview
- which renders the 'preview client' form/clients/:id/update
- which renders the 'update client' form
Feature overview
Artisan commands
PowerComponents registers pc:util
(as Power Components Utility) command with the following parameters:
Create components
create components <pluginCode>.<pluginName> <modelName> # For example: create components October.Test Person
The command creates createPerson
, updatePerson
, previewPerson
and listPerson
components, which are called crud components
in this documentation.
Create sites
create sites <modelName> [urlprefix] # For example: create sites Person
The command creates sites in the active theme that has embedded crud components
the components and optional prefix for URL.
Register component
register component <pluginCode>.<pluginName> <componentCode> # For example: register component October.Test PersonCreate
The command registers ComponentCode
component in plugin's Plugin.php
file.
Note: The command is parsing the Plugin.php
as a text file. It backs up the Plugin.php
file as Plugin.php.bak
before saving the new version of Plugin.php
file in case of messing the syntax or doing something unintentionally.
The supported syntax of the Plugin.php
register methods is for example:
public method registerComponents() { return [ 'Class' => 'ComponentCode', 'Class2' => 'ComponentCode2', ]; }
The command works with empty return [];
and no method as well.
Create CRUD
create crud <pluginCode>.<pluginName> <modelName> [urlprefix] # For example: create crud October.Test Person
The command combines all the foregoing methods, so it:
- Creates crud components and registers them in the plugin
- Creates crud sites with those components embedded
Note: The create crud
command will ask you if you want to create a plugin and model if they do not exist.
Developing components
Controllers differ from components. As a consequence, we cannot treat a component as a controller and give it the power to render lists and forms in one class as it is done in the backend.
In the frontend, we have to use one component for one purpose. As a consequence there are two classes that extend ComponentBase class:
- ListComponentBase
- FormComponentBase
Their major task is to implement AJAX handlers for the components and they implement all methods that are required by OctoberCMS.
Example, minimal component
Take a look at the minimal component configuration that renders the form:
PersonCreate.php
:
<?php namespace October\Test\Components; use Initbiz\PowerComponents\Classes\FormComponentBase; class PersonCreate extends FormComponentBase { public function componentDetails() { return [ 'name' => 'PersonCreate Component', 'description' => 'Component rendering create form for Person' ]; } }
personcreate/config_form.yaml
:
modelClass: October\Test\Models\Person form: fields: name: label: Name commentAbove: Text field, required. Given name in the first box, preferred name in the second box. is_married: label: Married type: dropdown emptyOption: Unknown options: '0': No '1': Yes
personcreate/default.htm
:
<h2>Create person</h2> {{ form_open() }} {{ pcrender('form', attribute(pcViewBag, __SELF__.alias) ) }} {{ form_close() }}
Right now all fields of the form are defined in config_form.yaml
file exactly the same way as in backend and normal HTML in default.htm
with pcrender
twig
method.
For list the pcrender
method in .htm
file should be invoked as follows:
{{ pcrender('list', attribute(pcViewBag, __SELF__.alias) ) }}
Overriding views
You can override every view, or its part by creating a file with the same name as the view you want to override. Check the name of the partial you want to override in /plugins/initbiz/powercomponents/frontendwidgets
or /plugins/initbiz/powercomponents/frontendformwidgets
directories. For example, if you want to override the whole list or form, then override _list.htm
or _form.htm
partial.
- If you want to override view in a component, then create the partial file in component's views directory.
- If you want to override view theme wide, then create
pcviews
directory in theme's root directory and then create the partial file in it.
Of course, files defined in component have higher priority than those defined in the theme.
Note: sometimes overriding views need to take time because of the cache. To see the change faster you can change something (even for a second) in parent's view to reload.
While working with the views, the first thing to understand is that in component (using Twig) you are running a method that requests views using the AJAX framework. Then the server is rendering partials and responses to the AJAX framework, which updates the partial.
As a consequence, the partials rendered by the server are written in PHP (like those in the backend), not Twig. Views written in PHP is a good idea in this case because those will be edited by developers rather than end-users. You have to remember only one rule while writing views in PHP: Avoid logic in views. There should be only if
s, for
s, foreach
s and echo
s.
Integrations
PowerComponents can be integrated with other plugins.
Cumulus
If you do not know what Cumulus
is then visit this page.
Using the CumulusIntegrator
trait in your component your lists will be by default filtered by cluster using the cluter_id
field in database and forms will be fed with the field containing cluster's id, and it will check if the user can view, add or update records that are not in the current cluster.
This way, every model wrapped by the PowerComponents will be available only for the cluster that the user is currently in (for example one cluster will not be able to read or update clients of the second cluster).
Features list
Lists
- Rendering list of records with the search box, update the URL in the table, checkboxes, "Create" and "Delete selected" buttons
- Sorting list
- Searching records
- Deleting records
- List pagination
- Overriding views in theme and in component
Forms
- Rendering create, preview and update forms with appropriate buttons
- Saving and updating models
Form widgets
- Datepicker
- Colorpicker
- Relation (dropdown and checkboxlist)
- Repeater
Integrations
- Cumulus integration verifying user access to data and filtering lists using cluster's slug from URL
Console commands
create components Initbiz.ExamplePlugin Model
- creating crud components for Modelcreate sites Model [urlprefix]
- creating sites in active theme with crud components embeddedregister component Initbiz.ExamplePlugin ComponentCode
- registering component in plugin registration filecreate crud Initbiz.ExamplePlugin Model [urlprefix]
- combining all the foregoing
Future plans
- Test, test, test, and test (stable still waiting) with better automatic tests
- Simplify the code (too much responsibility of classes)
- Make simpler
pcrender
method (without those 'options' and 'SELF.id' things) - Merge some PoweComponents traits with October's core and remove them from the plugin (remove the second group of traits)
- Console command to automatically create YAML files using model properties
- Run first AJAX request earlier in page load cycle (for faster page loading), or even move it to the lower level (render of page or something)
Translations
Remember that translations of plugin are not translations of your components. Translations of plugin mostly mean the translation of the inspector's properties, it's description, name and so on.
Labels in forms and column names are defined in your yaml
file because they are not related to PowerComponents itself.
When it comes to texts on buttons, they are defined in PowerComponents lang
directory. Right now there are only two languages supported: English and Polish, so if you want to have your language available on the marketplace, then please send us your translation. We cannot guarantee you full support of your language (we are just developers ;)).
PowerComponents's assets (CSSs, JSs)
Storm UI used in PowerComponents is a smaller version of OctoberCMS's Storm UI. I was doing my best to compile the file the way it will not mess your themes CSS, but I cannot guarantee it will be the case.
While developing themes try to avoid classes that can collide with those defined in OctoberCMS's Storm UI and if you find collisions that should not be present, let me know.
-
Mihai Tatomir
Found the plugin useful on 17 Feb, 2021
Nice job! A very helpful plugin. Is there a way to make dependent fields works? Thanks!
-
inIT author
Replied on 18 Feb, 2021
Thanks :)
Sure, they should work out of the box. If something's wrong, open a new support topic in the plugin's support page.
-
Jim Red
Found the plugin useful on 28 Nov, 2020
Amazing plugin! Totally worth it. :)
Only two short remarks:
1.)
In case you would like to generate PowerComponent's CRUD components into a plugin that was originally created by Rainlab's Builder plugin, then you will need to remove the following part from the modified Plugin.php file:public function registerComponents() { }
PowerComponent's artisan command won't remove/override this part automatically for you!
2.)
You should put these line into your layout:<script src="{{ ['$/initbiz/powercomponents/assets/js/powercomponents.js']|theme}}"> </script>
..instead of:
<script src="{{ ['/plugins/initbiz/powercomponents/assets/js/powercomponents.js']|theme}}"> </script>
If you copy sample code from documentation then probably you will face this problem.
-
Semen Pinigin
Found the plugin useful on 6 Apr, 2020
Excellent. Very helpful with creating frontend dashboard.
-
inIT author
Replied on 6 Apr, 2020
Thank you very much :)
-
Rolands Zeltins
Found the plugin useful on 14 Mar, 2019
The plugin works out of the box, just do what is asked in documentation and done!
Really good!
-
inIT author
Replied on 14 Mar, 2019
Thanks for your kind words! :)
-
Ernesto Bustos
Found the plugin useful on 26 Nov, 2018
It's work.. great plugin!
-
inIT author
Replied on 24 Jun, 2019
Thank you :)
-
1.0.33 |
Fix searchbox May 06, 2020 |
---|---|
1.0.32 |
Update stubs Mar 18, 2020 |
1.0.31 |
Fix pc:util for creating pages Oct 03, 2019 |
1.0.30 |
Fix typo Oct 02, 2019 |
1.0.29 |
Fix list pagination Oct 01, 2019 |
1.0.28 |
Small fixes, NL translation added Jun 03, 2019 |
1.0.27 |
Minor fixes Jun 03, 2019 |
1.0.26 |
Added delete button in default update record view Jan 14, 2019 |
1.0.25 |
Fixed fileupload widget Dec 07, 2018 |
1.0.24 |
!!! Cumulus integrator methods changed from user to cluster, added Dynamic Form widget Dec 07, 2018 |
1.0.23 |
Updated to the newest version of OctoberCMS Oct 09, 2018 |
1.0.22 |
Date picked loading css fixed Oct 09, 2018 |
1.0.21 |
Fix mirroring public assets using october:mirror command Sep 17, 2018 |
1.0.20 |
Added useful overrides Sep 14, 2018 |
1.0.19 |
Removed spaces from dropdown preview Sep 11, 2018 |
1.0.18 |
Small typo fix Aug 10, 2018 |
1.0.17 |
Fixed overriding of PC loader Aug 02, 2018 |
1.0.16 |
Current values of form can be set from post Jul 31, 2018 |
1.0.15 |
Preview page url added to page Jul 20, 2018 |
1.0.14 |
Added two extension methods Jul 20, 2018 |
1.0.13 |
Small syntax in views fix Jul 03, 2018 |
1.0.12 |
Lighten PC Storm UI Jun 28, 2018 |
1.0.11 |
!!! Including bootstrap.js twice fixed. You have to include bootstrap.js on your own as described in docs. Jun 20, 2018 |
1.0.10 |
Sorting lists and default value from model class fixed Jun 12, 2018 |
1.0.9 |
!!! Sometimes viewBag was not visible in onRun method. pcViewBag was introduced. Jun 10, 2018 |
1.0.8 |
!!! Changed pcrender function. Moved componentId to componentAlias. See upgrade guide. Jun 07, 2018 |
1.0.7 |
Changed cluster_id to cluster_slug in CumulusIntegrator trait Jun 07, 2018 |
1.0.6 |
Fixed overriding views in components and theme directory May 23, 2018 |
1.0.5 |
Added translations to loader. Now it is probably fully translatable May 23, 2018 |
1.0.4 |
Fixed translations and overriding views May 22, 2018 |
1.0.3 |
Fixed loading localized JavaScripts May 22, 2018 |
1.0.2 |
Minor fixes May 18, 2018 |
1.0.1 |
Initialize plugin. May 16, 2018 |
1.0.9
Because of the problem with visibility of viewBag in some components I decided to add pcViewBag
container. As a consequence pcrender
changed again, but right now it only is changing viewBag
to pcViewBag
in views files.
1.0.8
In this version componentId
has been changed to componentAlias
in components' views. It affected the pcrender
method as well. So to upgrade you have to:
- Change every
componentId
in your views tocomponentAlias
- Change
pcrender
method in component view as follows:
For form
{{ pcrender('form', attribute(viewBag, __SELF__.alias) ) }}
For list
{{ pcrender('list', attribute(viewBag, __SELF__.alias) ) }}