1. CakePHP with Stimulus.js
1.1 Why Stimulus
- The HTML is not cluttered with script code or vague class names
- It's clear which controllers are used and where (data-controller attribute)
- It's clear where the controller will make changes (data-target attribute)
- It's clear what triggers the controller (data-action attribute)
- The controllers have a life-cycle and are automatically connected and disconnected if the DOM-tree is modified.
1.2 About the demo
What the demo demonstrates:
- Partial page rendering with Stimulus
- The 'partials' are HTML snippets loaded from the server via ajax calls. These snippets are used to modify a part of the page.
- The loaded HTML snippets can contain references to Stimulus controllers. These are automatically connected. If they are removed from the page, they are automatically disconnected. In the demo, the area below the 'number of prizes' is dynamically changed, and it contains another Stimulus controller to instantly copy the prize text. The area contains input fields, and the entered data is kept when the area is updated; or actually the entered data is send to the server and the returned HTML snippet contains these values.
- The PHP code used to generate the HTML snippets, is also used when generating the whole page initially and after form submission. They are CakePHP elements.
- Only a few commands are needed to install and run it locally. The example doesn't use a database
node_modules with zillions of files. The good news is: these are only needed during development, not in production.
- Webpack is used to watch for saved changes in Stimulus controllers and update automatically the stimulus_v1_0.js file. With webpack and a stimulus helper we also don't need to register new controllers.
- I took the css files from the CakePHP Application Skeleton and only made additions to the style.css
What are those hyphens/dashes in the controller names?
- In the HTML /
Example1/index.ctp, indeed the names of the referenced Stimulus controllers contain two dashes. I made subdirectories for common- and page-specific controllers, and / maps to -- in the Stimulus filename to identifier mapping
- The CakePHP SecurityComponent is enabled. This gives a few challanges when used with client script code. The SecurityComponent rejects the submitted form data when fields are dynamically added or removed, hidden field values are changed, or a different form action url is used. Luckily these can selectively be unlocked, and this is happens in the beforeFilter of the Example1Controller.
- Don't bother to make funny remarks in the live demo, because the data is only stored in the session. That's why a src/Form/Example1Form extending App\Form is used; it contains the field definitions and form validation. If you use a database, you won't need this, because then you will have a model. Define the tables (following CakePHP naming conventions) in the database, including primary, foreign and unique keys, and let
cake bake allgenerate all the initial code.
- To support Internet Explorer 11, the Stimulus polyfill is used.
- In the loader_controller the fetch API is used for the ajax calls. To support Internet Explorer 11, the whatwg/fetch polyfill is used.
- The nginx configuration (
config/nginx.conf) for Heroku is made for production use: HTTP traffic is redirected to HTTPS, the browser is instructed to cache static assets, dynamic content is not cached and security headers are set.
- The webpack.config.js uses a CompressionPlugin. This plugin produces stimulus_v1_0.js.gz, a compressed file of stimuls_v1_0.js. The idea is to combine this with the Nginx gzip_static setting, so Nginx doesn't have to compress this at runtime. However the Nginx server on Heroku doesn't contain the ngx_http_gzip_static_module module. On Ubuntu, this is not a problem and the gzip_static setting can be used. The CompressionPlugin is optional, and can be removed if you don't want the gz files.
- Uh... sorry, but I didn't make unit tests.
Fork my github repository for improvements, other examples, or as a starter.
2.1 Install PHP 7 and CakePHP
- Install PHP and enable/install the intl and mbstring extensions
- Download Composer or update
2.2 Clone/Fork this example project
git clone https://github.com/nico-amsterdam/cakephp-stimulus-example1
and install the PHP packages:
2.3 Run CakePHP
You can now either use your machine's webserver to view the default home page, or start up the built-in webserver with:
bin/cake server -p 8765
http://localhost:8765 to see the welcome page.
2.4 Create a new CakePHP project
php composer.phar create-project --prefer-dist cakephp/app [app_name].
If Composer is installed globally, run
composer create-project --prefer-dist cakephp/app myapp
2.5 Install & run Stimulus
2.5.1 Add Stimulus configuration files to an existing CakePHP project
Copy the following files from the example:
index.js to the stimulus directory.
controllers directory inside the
2.5.2 Install NPM
For windows use this command line tool npm-windows-upgrade. Chocolatey installs a very old NPM version.
npm install -g npm@latest
or try the most recent version:
npm install -g npm@next
2.5.3 Install Webpack, Babel, polyfills and Stimulus-starter
Since NPM 5.7.0, install from lock-file only:
package-lock.json and the project run
npm install instead.
Webpack can watch files and recompile whenever they change. Start the webpack watcher with this command:
Write your Stimulus controllers in the
stimulus/controllers directory. You can also use one of the available Stimulus plugins.
I noticed that when
Visual Studio Code is running, the Webpack watcher didn't pick up the changes. In that case, exit
Visual Studio Code when you make changes in the Stimulus controllers.