Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
72cc3f9
Initial documentation of framework rewrite
bennothommo Jan 6, 2022
e59f4a7
Snowboard documentation
bennothommo Jan 10, 2022
8ca881a
Update snowboard-introduction.md
LukeTowers Jan 10, 2022
a9eb0ae
Update snowboard-introduction.md
LukeTowers Jan 10, 2022
c2e0563
Update snowboard-introduction.md
LukeTowers Jan 10, 2022
cd1b1c9
Update snowboard-introduction.md
LukeTowers Jan 10, 2022
22de01c
WIP
LukeTowers Jan 10, 2022
596794f
Finalise JS request docs, minor tweaks
bennothommo Jan 12, 2022
b0767e1
Add data attributes documentation
bennothommo Jan 12, 2022
f15bc7a
Merge branch 'main' into wip/framework-rewrite
bennothommo Jan 15, 2022
1e2bd73
WIP other pages
bennothommo Jan 16, 2022
24a7389
Merge branch 'main' into wip/framework-rewrite
bennothommo Jan 16, 2022
f031e6d
Tweak extras content
bennothommo Jan 16, 2022
01c26ca
Add fetch options API
bennothommo Jan 19, 2022
382630c
Added documentation for the Snowboard utilities
LukeTowers Jan 19, 2022
3020a89
WIP
LukeTowers Jan 19, 2022
7c0160e
styling
LukeTowers Jan 19, 2022
4640093
Reorganizing
LukeTowers Jan 19, 2022
2b1a10a
Tweaks
LukeTowers Jan 19, 2022
7dc6be9
wip
LukeTowers Jan 19, 2022
61152c2
Snowboard Request docs improvements
LukeTowers Jan 21, 2022
04f23ba
More WIP on Snowboard docs
LukeTowers Jan 21, 2022
7daf2b3
TOC fix
LukeTowers Jan 21, 2022
0894c8b
WIP Snowboard plugin development
bennothommo Jan 28, 2022
22f76d7
Add Mix command documentation
bennothommo Feb 7, 2022
2a8c24b
Add Mix to docs nav
bennothommo Feb 7, 2022
628e8bc
Merge branch 'main' into wip/framework-rewrite
LukeTowers Feb 8, 2022
5dfe1d4
front-end -> frontend
LukeTowers Feb 8, 2022
c11ac2f
Document automatic registration for mix packages
LukeTowers Feb 11, 2022
fbfa184
Correct dependency -> dependecies to reflect what the properties actu…
LukeTowers Feb 11, 2022
2c3c3b2
Document use of path symbols in winter.mix.js
LukeTowers Feb 12, 2022
a849b79
Small grammar tweaks
bennothommo Feb 13, 2022
2fb7c39
WIP plugin development docs
bennothommo Feb 15, 2022
ad42699
Update console-asset-compilation.md
LukeTowers Feb 15, 2022
adebee8
Add examples of cookie manipulation
bennothommo Feb 15, 2022
9726447
Merge branch 'wip/framework-rewrite' of github.com:wintercms/docs int…
bennothommo Feb 15, 2022
e471f64
Add semicolons
bennothommo Feb 15, 2022
c0dfb04
Update snowboard-utilities.md
LukeTowers Feb 15, 2022
06c5cfd
Update snowboard-plugin-development.md
LukeTowers Feb 15, 2022
ea7125c
Update snowboard-plugin-development.md
LukeTowers Feb 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions config/toc-docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ Plugins:
ajax/javascript-api: "JavaScript API"
ajax/extras: "Extra Features"

Snowboard:
icon: "icon-bolt"
pages:
snowboard/introduction: "Introduction"
snowboard/migration-guide: "Migration Guide"
snowboard/handlers: "Serverside Event Handlers"
snowboard/request: "AJAX Requests (JavaScript API)"
snowboard/data-attributes: "AJAX Requests (Data Attributes API)"
snowboard/extras: "Extra Features"
snowboard/utilities: "Utilities"
snowboard/plugin-development: "Plugin Development"

Database:
icon: "icon-hdd"
pages:
Expand Down Expand Up @@ -113,6 +125,7 @@ Console:
console/setup-maintenance: "Setup & Maintenance"
console/plugin-management: "Plugin Management"
console/theme-management: "Theme Management"
console/asset-compilation: "Asset Compilation (Mix)"
console/scaffolding: "Scaffolding"
console/utilities: "Utilities"

Expand Down
203 changes: 203 additions & 0 deletions console-asset-compilation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
# Asset Compilation (Mix)

- [Introduction](#introduction)
- [Requirements](#requirements)
- [Registering a package](#registering-packages)
- [Automatic registration](#automatic-registration)
- [Registering plugin packages](#registering-plugins)
- [Registering theme packages](#registering-themes)
- [Mix configuration](#mix-configuration)
- [Examples](#examples)
- [Commands](#commands)
- [Install Node dependencies](#mix-install)
- [List registered Mix packages](#mix-list)
- [Compile a Mix package](#mix-compile)
- [Watch a Mix package](#mix-watch)

<a name="introduction"></a>
## Introduction

Winter brings first-class support for handling Node-based compilation for frontend assets through the Mix commands. The comamnds use the [Laravel Mix](https://laravel-mix.com/) wrapper, a user-friendly and simple interface for setting up compilation of multiple types of frontend assets through Webpack and various libraries.

<a name="requirements"></a>
### Requirements

To take advantage of Mix asset compilation, you must have Node and the Node package manager (NPM) installed in your development environment. This will be dependent on your operating system - please review the [Download NodeJS](https://nodejs.org/en/download/) page for more information on installing Node.

[Laravel Mix](https://laravel-mix.com/) should also be present in the `package.json` file for any packages that will be using it (either in `dependencies` or a `devDependencies`) but if it is not specified in the project's `package.json` file then it can be optionally automatically added when running the [`mix:install`](#mix-install) command.

<a name="registering-packages"></a>
## Registering a package

Registering for asset compilation through Mix is very easy. Automatic registration should meet your needs most of the time, and if not there are several methods available to manually register Mix packages.

<a name="automatic-registration"></a>
### Automatic registration

By default, Winter will scan all available and enabled modules, plugins and themes for the presence of a `winter.mix.js` file under each extension's root folder (i.e. `modules/system/winter.mix.js`, `plugins/myauthor/myplugin/winter.mix.js`, or `themes/mytheme/winter.mix.js`).

If the `winter.mix.js` file is found, it will be automatically registered as a package with an automatically generated package name, and will show up when running the Mix commands. Most of the time, this should be all you need to do in order to get started with Laravel Mix asset compilation in Winter CMS.

<a name="registering-plugins"></a>
### Registering plugins

To register frontend assets to be compiled through Mix in your plugin, simply return an array with the package names as the keys and the package paths relative to the plugin's directory as the values to register from your [`Plugin.php`](../plugin/registration) registration file's `registerMixPackages()` method. See below example.

```php
public function registerMixPackages()
{
return [
'custom-package-name' => 'assets/js/build.mix.js',
];
}
```

<a name="registering-themes"></a>
### Registering themes

Registration of asset compilation of themes is even easier, and can be done by adding a `mix` definition to your [theme information file](../themes/development#theme-information) (`theme.yaml`).

```yaml
name: "Winter CMS Demo"
description: "Demonstrates the basic concepts of the frontend theming."
author: "Winter CMS"
homepage: "https://wintercms.com"
code: "demo"

mix:
<name of package>: winter.mix.js
```

The `mix` definition takes any number of registered packages as a YAML object, with the key being the name of the package as a kebab-case string and the location of your `winter.mix.js` file relative to the theme's root directory.

For example, if you want to register two packages called `demo-theme-style` and `demo-theme-shop` located in the assets folder, you would use the following definition:

```yaml
name: "Winter CMS Demo"
description: "Demonstrates the basic concepts of the frontend theming."
author: "Winter CMS"
homepage: "https://wintercms.com"
code: "demo"

mix:
demo-theme-style: assets/style/winter.mix.js
demo-theme-shop: assets/shop/winter.mix.js
```

<a name="mix-configuration"></a>
## Mix configuration

The Mix configuration file (`winter.mix.js`) is a configuration file that manages the configuration of Laravel Mix itself. In conjunction with the `package.json` file that defines your dependencies, this file defines how Laravel Mix will compile your assets.

You can [review examples](https://laravel-mix.com/docs/6.0/examples) or the [full Mix API](https://laravel-mix.com/docs/6.0/api) at the [Laravel Mix website](https://laravel-mix.com).

Your `winter.mix.js` file must include Mix as a requirement, and must also define the public path to the current directory, as follows:

```js
const mix = require('laravel-mix');

// For assets in the current directory
// mix.setPublicPath(__dirname);

// For assets in a /assets subdirectory
mix.setPublicPath(__dirname + '/assets');

// Your mix configuration below
```

### Paths

When the `winter.mix.js` file is evaluated, regardless of where you ran `mix:compile` from, the working directory is set to the parent directory of the `winter.mix.js` file. That means that any relative paths used in the configuration will be relative to the current directory of the `winter.mix.js` file.

>**NOTE:** Winter's [path symbols](../services/helpers#path-symbols) are also supported in the `winter.mix.js` file.

<a name="examples"></a>
## Examples

Here are some examples of installing common frontend libraries for use with the asset compilation.

### Tailwind CSS

For themes that wish to use Tailwind CSS, include the `tailwindcss`, `postcss` and `autoprefixer` dependencies in your `package.json` file.

```bash
# Inside the project root folder
npm install --save-dev tailwindcss postcss autoprefixer

# Run the Tailwind initialisation
npx taildwindcss init
```

This will create a Tailwind configuration file (`tailwind.config.js`) inside your theme that you may [configure](https://tailwindcss.com/docs/installation) to your specific theme's needs.

Then, add a `winter.mix.js` configuration file that will compile Tailwind as needed:

```js
const mix = require('laravel-mix');
mix.setPublicPath(__dirname);

// Render Tailwind style
mix.postCss('assets/css/base.css', 'assets/css/theme.css', [
require('postcss-import'),
require('tailwindcss'),
]);
```

In the example above, we have a base CSS file that contains the Tailwind styling - `assets/css/base.css` - that will compile to a final compiled CSS file in `assets/css/theme.css`.

Your theme will now be ready for Tailwind CSS development.

<a name="commands"></a>
## Commands

### Install Node dependencies

```bash
php artisan mix:install [-p <package name>] [--npm <path to npm>]
```

The `mix:install` command will install Node dependencies for all registered Mix packages.

This command will add each registered package to the `workspaces.packages` property of your root `package.json` file and then run and display the results of `npm install` from your project root to install all of the dependencies for all of the registered packages at once.

You can optionally provide a `-p` or `--package` flag to install dependencies for one or more packages. To define multiple packages, simply add more `-p` flags to the end of the command.

If the command is run with a `-p` or `--package` flag and the provided package name is not already registered and the name matches a valid module, plugin, or theme package name (modules are prefixed with `module-$moduleDirectory`, themes are prefixed with `theme-$themeDirectory`, and plugins are simply `Author.Plugin`) then a `winter.mix.js` file will be automatically generated for that package and will be included in future runs of any mix commands through the [automatic registration](#automatic-registration) feature.

The `--npm` flag can also be provided if you have a custom path to the `npm` program. If this is not provided, the system will try to guess where `npm` is located.

### List registered Mix packages

```bash
php artisan mix:list
```

The `mix:list` command will list all registered Mix packages found in the Winter installation. This is useful for determining if your plugin or theme is correctly registered.

The command will list all packages, as well as the directory for the asset and the configuration file that has been defined during registration.

### Compile a Mix packages

```bash
php artisan mix:compile [-p <package name>] [-f|--production] [-- <extra build options>]
```

The `mix:compile` command compiles all registered Mix packages, running each package through Laravel Mix for compilation.

By specifying the `-p` flag, you can compile one or more selected packages. To define multiple packages, simply add more `-p` flags to the end of the command.

By default, all packages are built in "development" mode. If you wish to compile in "production" mode, which may include more optimisations for production sites, add the `-f` or `--production` flag to the command.

The command will generate a report of all compiled files and their final size once complete.

If you wish to pass extra options to the Webpack CLI, for special cases of compilation, you can add `--` to the end of the command, followed by [any parameters](https://webpack.js.org/api/cli/) as per the Webpack CLI options.

### Watch a Mix package

```bash
php artisan mix:watch <package> [-f|--production] [-- <extra build options>]
```

The `mix:watch` command is similar to the the `mix:compile` command, except that it remains active and watches for any changes made to files that would be affected by your compilation. When any changes are made, a compile is automatically executed. This is useful for development in allowing you to quickly make changes and review them in your browser.

With this command, only one package can be provided and watched at any one time.
5 changes: 5 additions & 0 deletions console-introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ Command | Description
[`theme:use`](../console/theme-management#theme-use) | Switches Winter to the given theme.
[`theme:remove`](../console/theme-management#theme-install) | Removes a theme.
[`theme:sync`](../console/theme-management#theme-sync) | Synchronises a theme between the filesystem and the database, if you use the [Database Templates](../cms/themes#database-driven-themes) feature.
**Asset compilation (Mix)** |
[`mix:install`](../console/asset-compilation#mix-install) | Install Node dependencies for registered Mix packages.
[`mix:list`](../console/asset-compilation#mix-list) | Lists all registered Mix packages.
[`mix:compile`](../console/asset-compilation#mix-compile) | Compiles one or more Mix packages.
[`mix:watch`](../console/asset-compilation#mix-watch) | Watches changes within a Mix package and automatically compiles the package on any change.
**Scaffolding** |
[`create:theme`](../console/scaffolding#create-theme) | Create a theme.
[`create:plugin`](../console/scaffolding#create-plugin) | Create a plugin.
Expand Down
100 changes: 100 additions & 0 deletions snowboard-data-attributes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# AJAX Requests (Data Attributes API)

- [Introduction](#introduction)
- [Available Data Attributes](#available-attributes)
- [Usage Examples](#usage-examples)

<a name="introduction"></a>
## Introduction

The Data Attributes API is the simpler way of embedding AJAX functionality in your themes and plugins, and removes the need to be experienced with JavaScript. While the [JavaScript API](../snowboard/request) has had numerous changes from the original [AJAX framework](../ajax/introduction), the Data Attributes API has remain largely unchanged, despite being powered by the new Snowboard framework under the hood.

It can be loaded by adding the following tag into your CMS Theme's page or layout:

```twig
{% snowboard request attr %}
```

> **NOTE:** As per the [Migration Guide](../snowboard/migration-guide), arbitrary JavaScript is no longer allowed through the Data Attributes API. Thus, the `data-request-before-update`, `data-request-success`, `data-request-error` and `data-request-complete` attributes are no longer supported. Please use the [JavaScript API](../snowboard/request) if you require this functionality.

<a name="available-attributes"></a>
## Available Data Attributes

Triggering an AJAX request from a valid element is as simple as adding the `data-request` attribute to that element. This generally should be done on a button, link, or form. You can also customize the AJAX request using the following attributes:

<style>
.attributes-table-precessor + table td:first-child,
.attributes-table-precessor + table td:first-child > * { white-space: nowrap; }
</style>
<div class="attributes-table-precessor"></div>

Attribute | Description
--------- | -----------
`data-request` | Specifies the AJAX handler name to target for the request.
`data-request-confirm` | Specifies the confirmation message to present to the user before proceeding with the request. If the user cancels, the request is not sent.
`data-request-redirect` | Specifies a URL to redirect the browser to, if a successful AJAX response is received.
`data-request-url` | Specifies the URL to send the AJAX request to. By default, this will be the current URL.
`data-request-update` | Specifies a list of partials and page elements (CSS selectors) to update on a successful AJAX response. The format is as follows: `partial: selector, partial: selector`. Usage of quotes is required in most cases: `'partial': 'selector'`. If the selector is prepended with an `@` symbol, the content received from the server will be appended to the element. If the selector is prepended with a `^` symbol, the content will be prepended. Otherwise, received content will replace the original content in the element.
`data-request-data` | Specifies additional data to send with the request to the server. The format is as follows: `'var': 'value', 'var2': 'new value'`. You may also specify this same attribute on any parent elements of the triggering element, and this data will be merged with the parent data (with the triggering data taking preference). It will also be merged with any form data, if this request triggers within a form.
`data-request-form` | Specifies the form that the AJAX request will include its data from. If this is unspecified, the closest form will be used, or if the element itself is a form, then this will be used.
`data-request-flash` | Specifies if flash messages will be accepted from the response.
`data-request-files` | Specifies if file data will be included in the request. This will allow any file inputs in the form to work.
`data-browser-validate` | Specifies if the in-built browser validation will be triggered. If present, the request will be cancelled if the browser validation fails.
`data-track-input` | Specifies if an input will trigger an AJAX request anytime the input changes. An optional number can be specified in this attribute, which represents the amount of milliseconds between any change and the AJAX request triggering.


When the `data-request` attribute is specified for an element, the element triggers an AJAX request when a user interacts with it. Depending on the type of element, the request is triggered on the following events:

Element | Event
------------- | -------------
**Forms** | when the form is submitted.
**Links, buttons** | when the element is clicked.
**Text, number, and password fields** | when the text is changed and only if the `data-track-input` attribute is presented.
**Dropdowns, checkboxes, radios** | when the element is selected.

<a name="data-attribute-examples"></a>
## Usage examples

Trigger the `onCalculate` handler when the form is submitted. Update the element with the identifier "result" with the **calcresult** partial:

```html
<form data-request="onCalculate" data-request-update="calcresult: '#result'">
```

Request a confirmation when the Delete button is clicked before the request is sent:

```html
<form ... >
...
<button data-request="onDelete" data-request-confirm="Are you sure?">Delete</button>
```

Redirect to another page after the successful request:

```html
<form data-request="onLogin" data-request-redirect="/admin">
```

Send a POST parameter `mode` with a value `update`:

```html
<form data-request="onUpdate" data-request-data="mode: 'update'">
```

Send a POST parameter `id` with value `7` across multiple elements:

```html
<div data-request-data="id: 7">
<button data-request="onDelete">Delete</button>
<button data-request="onSave">Update</button>
</div>
```

Including [file uploads](../services/request-input#files) with a request:

```html
<form data-request="onSubmit" data-request-files>
<input type="file" name="photo" accept="image/*" />
<button type="submit">Submit</button>
</form>
```
Loading