chore(markdown): Updated plugin guide for v3
This commit is contained in:
parent
d7442b9bc4
commit
cac698027c
15 changed files with 195 additions and 348 deletions
|
@ -1,65 +0,0 @@
|
||||||
---
|
|
||||||
title: Conditionally loading build-time plugins
|
|
||||||
order: 30
|
|
||||||
---
|
|
||||||
|
|
||||||
You can choose to load your build-time plugin conditionally based on run-time data.
|
|
||||||
|
|
||||||
To do so, you need to create a `condition` method that will determine whether the
|
|
||||||
plugin will be loaded. This method receives the complete settings object and should
|
|
||||||
return `true` if the plugin is to be loaded, and `false` if it should not be loaded.
|
|
||||||
|
|
||||||
```js
|
|
||||||
const condition = settings => {
|
|
||||||
if (settings) {
|
|
||||||
// Remember, settings contains:
|
|
||||||
// settings.options => The user's options
|
|
||||||
// settings.measurements => The measurements
|
|
||||||
return true // Load the plugin
|
|
||||||
}
|
|
||||||
else return false // Do not load the plugin
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
You pass your plugin and condition method as a third parameter to the Design constructor
|
|
||||||
with the `plugin` and `condition` keys respectively.
|
|
||||||
|
|
||||||
Let's look at a complete example to illustrate this:
|
|
||||||
|
|
||||||
```js
|
|
||||||
import freesewing from '@freesewing/core'
|
|
||||||
import plugins from '@freesewing/plugin-bundle'
|
|
||||||
import myConditionalPlugin from '@freesewing/plugin-bust'
|
|
||||||
|
|
||||||
const myConditionalPluginCheck = (settings = false) =>
|
|
||||||
settings &&
|
|
||||||
settings.options &&
|
|
||||||
settings.options.draftForHighBust &&
|
|
||||||
settings.measurements.highBust
|
|
||||||
? true
|
|
||||||
: false
|
|
||||||
|
|
||||||
const Pattern = new freesewing.Design(
|
|
||||||
config,
|
|
||||||
plugins,
|
|
||||||
{
|
|
||||||
plugin: myConditionalPlugin,
|
|
||||||
condition: myConditionalPluginCheck
|
|
||||||
}
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
Our condition method will return `true` only if the following conditions are met:
|
|
||||||
|
|
||||||
- A `settings` object is passed into the method
|
|
||||||
- `settings.options` is _truthy_
|
|
||||||
- `settings.options.draftForHighBust` is _truthy_
|
|
||||||
- `settings.options.measurements.highBust` is _truthy_
|
|
||||||
|
|
||||||
This is a real-world example from our Teagan pattern. A t-shirt pattern that can be
|
|
||||||
drafted to the high bust (rather than the full chest circumference) if the user
|
|
||||||
choses so.
|
|
||||||
|
|
||||||
But that feat is handled auto-magically by `plugin-bust` which is a build-time plugin.
|
|
||||||
So whether to load this plugin or not hinges on the user settings, which is why we
|
|
||||||
load this plugin conditionally.
|
|
|
@ -1,25 +1,23 @@
|
||||||
---
|
---
|
||||||
title: Plugin guide
|
title: Plugin guide
|
||||||
order: 400
|
|
||||||
icons:
|
|
||||||
- logo
|
|
||||||
- plugin
|
|
||||||
for: developers
|
|
||||||
about: |
|
|
||||||
This guide shows you everything you need to know to understand plugins in FreeSewing, and create your own.
|
|
||||||
goals:
|
|
||||||
- Know about build-time plugins vs run-time plugins
|
|
||||||
- Understanding plugin structure
|
|
||||||
- Hooks and how to use them
|
|
||||||
- Using hooks without a plugin
|
|
||||||
- Using macros
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Plugins allow you to extend FreeSewing.
|
Plugins allow you to extend FreeSewing with new features and functionality.
|
||||||
|
A FreeSewing plugin can extend FreeSewing in 3 different ways:
|
||||||
|
|
||||||
We have [a list of available plugins](/reference/plugins/), but
|
- It can [provide macros](/guides/plugins/macros), which are a way to automate a number of steps into a
|
||||||
|
single command.
|
||||||
|
- It can [hook into the pattern](/guides/plugins/hooks), which allows you to manipulate the pattern or
|
||||||
|
interact with it at various stages of it's lifecycle.
|
||||||
|
- It can [provide store methods](/guides/plugins/store), which allows you to add new ways to handle data
|
||||||
|
in the pattern, including providing a custom logger.
|
||||||
|
|
||||||
|
We have [a list of plugins](/reference/plugins/) that we maintain, but
|
||||||
if you can't find what you're looking for, you can write your own plugin.
|
if you can't find what you're looking for, you can write your own plugin.
|
||||||
|
|
||||||
We'll cover the following topics in this guide:
|
If you plan on doing that, or if you would like to understand how plugins work,
|
||||||
|
this guide is for you.
|
||||||
|
|
||||||
|
We'll cover the following topics:
|
||||||
|
|
||||||
<ReadMore list />
|
<ReadMore list />
|
||||||
|
|
|
@ -1,20 +1,53 @@
|
||||||
---
|
---
|
||||||
title: Hooks
|
title: Lifecycle hook methods
|
||||||
order: 60
|
order: 110
|
||||||
---
|
---
|
||||||
|
|
||||||
A **hook** is a lifecycle event. The available hooks are:
|
FreeSewing plugins can provide hooks, which is a way to hook into the pattern's
|
||||||
|
lifecycle.
|
||||||
|
|
||||||
- [preRender](/reference/hooks/prerender/): Called at the start of [`Pattern.render()`](/reference/api/pattern/render)
|
## Signature
|
||||||
- [postRender](/reference/hooks/postrender/): Called at the end of [`Pattern.render()`](/reference/api/pattern/render)
|
|
||||||
- [insertText](/reference/hooks/inserttext/): Called when inserting text
|
|
||||||
- [preDraft](/reference/hooks/predraft/): Called at the start of [`Pattern.draft()`](/reference/api/pattern/draft)
|
|
||||||
- [postDraft](/reference/hooks/postdraft/): Called at the end of [`Pattern.draft()`](/reference/api/pattern/draft)
|
|
||||||
- [preSample](/reference/hooks/presample/): Called at the start of [`Pattern.sample()`](/reference/api/pattern/sample)
|
|
||||||
- [postSample](/reference/hooks/postsample/): Called at the end of [`Pattern.sample()`](/reference/api/pattern/sample)
|
|
||||||
|
|
||||||
You can register a method for a hook. When the hook is triggered, your method will be
|
To provide one or more hooks, your plugin should have a `hooks` property that
|
||||||
called. It will receive two parameters:
|
is an object where the keys are the lifecycle hook name, and the value holds a
|
||||||
|
method. When the lifecycle hook is triggered, your method will be called.
|
||||||
|
|
||||||
- An object relevant to the hook. See the [hooks API reference](/reference/hooks/) for details.
|
```mjs
|
||||||
|
const myPlugin = {
|
||||||
|
name: 'example',
|
||||||
|
version: '0.0.1',
|
||||||
|
hooks: {
|
||||||
|
hookName: function (obj, data = {}) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to attach multiple methods to the same lifecycle hook, you can pass
|
||||||
|
them as an array:
|
||||||
|
|
||||||
|
```mjs
|
||||||
|
const myPlugin = {
|
||||||
|
name: 'example',
|
||||||
|
version: '0.0.1',
|
||||||
|
hooks: {
|
||||||
|
hookName: [
|
||||||
|
function one (obj, data = {}) { },
|
||||||
|
function two (obj, data = {}) { }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Arguments
|
||||||
|
|
||||||
|
All lifecycle methods will receive two parameters:
|
||||||
|
|
||||||
|
- An object relevant to the lifecycle hook. See the [hooks API reference](/reference/hooks/) for details.
|
||||||
- Data passed when the hook was registered (optional)
|
- Data passed when the hook was registered (optional)
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
Refer to the [hooks API reference](/reference/hooks/) for a list of all
|
||||||
|
available lifecycle hooks.
|
||||||
|
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
---
|
|
||||||
title: Loading build-time plugins
|
|
||||||
order: 20
|
|
||||||
---
|
|
||||||
|
|
||||||
Build-time plugins are loaded at build time, by passing them to
|
|
||||||
the [`freesewing.Design`](/reference/api/design) constructor:
|
|
||||||
|
|
||||||
```js
|
|
||||||
import freesewing from "@freesewing/core"
|
|
||||||
import plugins from "@freesewing/plugin-bundle"
|
|
||||||
import config from "../config"
|
|
||||||
|
|
||||||
const Pattern = new freesewing.Design(config, plugins)
|
|
||||||
```
|
|
||||||
|
|
||||||
If you have multiple plugins to load, you can pass them as an array:
|
|
||||||
|
|
||||||
```js
|
|
||||||
import freesewing from "@freesewing/core"
|
|
||||||
import plugins from "@freesewing/plugin-bundle"
|
|
||||||
import gorePlugin from "@freesewing/plugin-gore"
|
|
||||||
import config from "../config"
|
|
||||||
|
|
||||||
const Pattern = new freesewing.Design(config, [plugins, gorePlugin] )
|
|
||||||
```
|
|
|
@ -1,24 +0,0 @@
|
||||||
---
|
|
||||||
title: Loading run-time plugins
|
|
||||||
order: 40
|
|
||||||
---
|
|
||||||
|
|
||||||
Run-time plugin are loaded at run time, by passing them to the `use` method of
|
|
||||||
an instatiated pattern. That method is chainable, so if you have multiple plugins
|
|
||||||
you can just chain them together:
|
|
||||||
|
|
||||||
```js
|
|
||||||
import Aaron from "@freesewing/aaron";
|
|
||||||
import theme from "@freesewing/plugin-theme";
|
|
||||||
import i18n from "@freesewing/plugin-i18n";
|
|
||||||
|
|
||||||
const myAaron = new Aaron()
|
|
||||||
.use(theme)
|
|
||||||
.use(i18n)
|
|
||||||
```
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
|
|
||||||
Plugins that use only hooks are typically run-time plugins
|
|
||||||
|
|
||||||
</Tip>
|
|
12
markdown/dev/guides/plugins/loading/en.md
Normal file
12
markdown/dev/guides/plugins/loading/en.md
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
title: Loading plugins
|
||||||
|
order: 140
|
||||||
|
---
|
||||||
|
|
||||||
|
Plugins can be loaded at build time and added to the desig. Or at run time and added to an instantiated pattern.
|
||||||
|
|
||||||
|
To load a plugin at build time, it should be added to [the `plugins` key of the part configuration](/reference/api/part/config/plugins).
|
||||||
|
|
||||||
|
To load a plugin at run time, it should be loaded with a call to [`Pattern.use()`](/reference/api/pattern/use).
|
||||||
|
|
||||||
|
Please refer to the relevant documentation for more details.
|
|
@ -1,58 +1,37 @@
|
||||||
---
|
---
|
||||||
title: Macros
|
title: Macro methods
|
||||||
order: 90
|
order: 120
|
||||||
---
|
---
|
||||||
|
|
||||||
Plugin structure for macros is similar, with a few changes:
|
FreeSewing plugins can provide macros, which is a way to automate multiple
|
||||||
|
steps into a single command.
|
||||||
|
|
||||||
- Rather than the hook name, you provide the macro name (that you choose yourself)
|
## Signature
|
||||||
- The context (`this`) of a macro method is **always** a [Part](/reference/api/part) object.
|
|
||||||
|
|
||||||
Apart from these, the structure is very similar:
|
To provide one or more macros, your plugin should have a `macros` property that
|
||||||
|
is an object where the keys are the macro name, and the value holds a method to
|
||||||
|
run when the macro is executed.
|
||||||
|
|
||||||
```js
|
```mjs
|
||||||
import {name, version} from '../package.json';
|
const myPlugin = {
|
||||||
|
name: 'example',
|
||||||
export default {
|
version: '0.0.1',
|
||||||
name,
|
|
||||||
version,
|
|
||||||
macros: {
|
macros: {
|
||||||
box: function(so) {
|
example: function(so, { log }) {
|
||||||
this.points.boxTopLeft = so.anchor;
|
log.info('Running the example macro')
|
||||||
this.points.boxTopRight = so.anchor.shift(0, so.size);
|
}
|
||||||
this.points.boxBottomRight = this.points.boxTopRight.shift(-90, so.size);
|
}
|
||||||
this.points.boxBottomLeft = new this.Point(so.anchor.x, this.points.boxBottomRight.y);
|
|
||||||
|
|
||||||
this.paths.box = new this.Path()
|
|
||||||
.move(this.points.boxTopLeft)
|
|
||||||
.line(this.points.boxTopRight)
|
|
||||||
.line(this.points.boxBottomRight)
|
|
||||||
.line(this.points.boxBottomLeft)
|
|
||||||
.close()
|
|
||||||
.attr('class', 'box');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Did you figure out what this plugin does?
|
## Arguments
|
||||||
It provides a `box` macro that draws a box on our pattern in a given location with a give size.
|
|
||||||
|
|
||||||
We can use it like this:
|
All macros receive two arguments:
|
||||||
|
|
||||||
```js
|
- `so`: A plain object holding configuration object passed to the macro
|
||||||
points.boxAnchor = new Point(100, 100);
|
- `props`: The same object as passed to the Part.draft()` method that you can destructure
|
||||||
macro('box', {
|
|
||||||
anchor: points.boxAnchor
|
|
||||||
size: 25
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
Obviously, you can expect to learn how to call a macro in its documentation,
|
|
||||||
rather than have to comb through its code.
|
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
|
|
||||||
###### Macros take only 1 argument
|
###### Macros take only 1 argument
|
||||||
|
|
||||||
When writing a macro, keep in mind that all information that needs to be passed
|
When writing a macro, keep in mind that all information that needs to be passed
|
||||||
|
@ -61,3 +40,7 @@ to a macro needs to be contained in a single argument.
|
||||||
Typically, you use a single plain object to configure the macro.
|
Typically, you use a single plain object to configure the macro.
|
||||||
|
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
Macros do not need to return anything. If they do, it will be ignored.
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
---
|
|
||||||
title: Plugin structure
|
|
||||||
order: 50
|
|
||||||
---
|
|
||||||
|
|
||||||
Plugins can do two things:
|
|
||||||
|
|
||||||
- They can use hooks
|
|
||||||
- They can provide macros
|
|
||||||
|
|
||||||
Your plugin should export an object with the following structure:
|
|
||||||
|
|
||||||
```js
|
|
||||||
{
|
|
||||||
name: 'myPlugin',
|
|
||||||
version: '1.0.0',
|
|
||||||
hooks: {},
|
|
||||||
macros: {}
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
The `name` and `version` attributes are self-explanatory.
|
|
||||||
The [hooks](/guides/plugins/hooks/) and [macros](/guides/plugins/macros/) sections
|
|
||||||
explain the `hooks` and `macros` properties.
|
|
56
markdown/dev/guides/plugins/store/en.md
Normal file
56
markdown/dev/guides/plugins/store/en.md
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
---
|
||||||
|
title: Store methods
|
||||||
|
order: 130
|
||||||
|
---
|
||||||
|
|
||||||
|
FreeSewing plugins can provide store methods, which facilitate data handling
|
||||||
|
within a pattern.
|
||||||
|
|
||||||
|
## Signature
|
||||||
|
|
||||||
|
To provide one or more store methods, your plugin should have a `macros` property that
|
||||||
|
is an array where each member is itself an array with two members:
|
||||||
|
|
||||||
|
- The first member holds the key to attach the method to (in dot notation)
|
||||||
|
- The second member holds the method to attach
|
||||||
|
|
||||||
|
```mjs
|
||||||
|
const myPlugin = {
|
||||||
|
name: 'example',
|
||||||
|
version: '0.0.1',
|
||||||
|
store: [
|
||||||
|
[
|
||||||
|
'log.panic',
|
||||||
|
function(store, ...params) {
|
||||||
|
store.setIfUnset('logs.panic', new Array())
|
||||||
|
store.push(...params)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Arguments
|
||||||
|
|
||||||
|
All store methods receive at least two arguments:
|
||||||
|
|
||||||
|
- `store`: The store object itself
|
||||||
|
- `...params`: All additional plugins that were passed to the store method
|
||||||
|
|
||||||
|
## Overwriting store methods
|
||||||
|
|
||||||
|
You are allowed to overwrite existing store methods.
|
||||||
|
As it happens, this is how you should implement a custom logging solution, but overwriting the logging methods under the store's `log` key,
|
||||||
|
|
||||||
|
However, the following methods cannot be overwritten:
|
||||||
|
|
||||||
|
- `extend`
|
||||||
|
- `get`
|
||||||
|
- `push`
|
||||||
|
- `set`
|
||||||
|
- `setIfUnset`
|
||||||
|
- `unset`
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
Store methods do not need to return anything. If they do, it will be ignored.
|
25
markdown/dev/guides/plugins/structure/en.md
Normal file
25
markdown/dev/guides/plugins/structure/en.md
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
title: Plugin structure
|
||||||
|
order: 100
|
||||||
|
---
|
||||||
|
|
||||||
|
A FreeSewing plugin is a plain object with the following structure:
|
||||||
|
|
||||||
|
```mjs
|
||||||
|
Object plugin = {
|
||||||
|
String name,
|
||||||
|
String version,
|
||||||
|
Object hooks,
|
||||||
|
Object macros,
|
||||||
|
Array store,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
A plugin **must** have the `name` and `version` properties.
|
||||||
|
The other properties are optional, and they map to the three different functionalities macros can provide:
|
||||||
|
|
||||||
|
- `hooks`: Holds an object with lifecycle hooks the plugin wants to hook into
|
||||||
|
- `macros`: Holds and object with macros the plugin provides
|
||||||
|
- `store`: Holds and Array with store methods the plugin provides.
|
||||||
|
|
||||||
|
Click on the links above for more details on the structure of these properties.
|
|
@ -1,36 +0,0 @@
|
||||||
---
|
|
||||||
title: Types of plugins
|
|
||||||
order: 10
|
|
||||||
---
|
|
||||||
|
|
||||||
Plugins come in two flavours:
|
|
||||||
|
|
||||||
- [Build-time plugins](#build-time-plugins)
|
|
||||||
- [Run-time plugins](#run-time-plugins)
|
|
||||||
|
|
||||||
When writing a plugin, ask yourself whether it's a run-time or a build-time plugin.
|
|
||||||
And if the answer is both, please split them into two plugins.
|
|
||||||
|
|
||||||
## Build-time plugins
|
|
||||||
|
|
||||||
A plugin is a build-time plugin if it is required by the pattern at build-time.
|
|
||||||
In other words, the plugin is a dependency for the pattern, and if it's missing
|
|
||||||
the pattern won't load.
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
|
|
||||||
Our [plugin bundle](/reference/plugins/bundle/) bundles build-time plugins that are used in many patterns.
|
|
||||||
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
<Note>Plugins that provide a macro are typically build-time plugins</Note>
|
|
||||||
|
|
||||||
## Run-time plugins
|
|
||||||
|
|
||||||
A plugin is a run-time plugin if it can be added after instantiating your pattern.
|
|
||||||
Think of it as a plugin to be used in the front-end.
|
|
||||||
|
|
||||||
Run-time plugins are not a dependecy of the pattern. They just _add something_ to it.
|
|
||||||
|
|
||||||
Our [theme plugin](/reference/plugins/theme/) is a good example of a run-time plugin.
|
|
||||||
If it's missing, your pattern will still work, it just won't look pretty.
|
|
|
@ -1,26 +0,0 @@
|
||||||
---
|
|
||||||
title: Using hooks more than once
|
|
||||||
order: 80
|
|
||||||
---
|
|
||||||
|
|
||||||
What if you want to attach more than one method to a hook?
|
|
||||||
You could spread them over separate plugins, but there's a better way.
|
|
||||||
|
|
||||||
Rather than assigning a method to your hook, assign an array of methods like this:
|
|
||||||
|
|
||||||
```js
|
|
||||||
import myCoolMethod from './method-a';
|
|
||||||
import myEvenCoolerMethod from './method-b';
|
|
||||||
import {name, version} from '../package.json';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name,
|
|
||||||
version,
|
|
||||||
hooks: {
|
|
||||||
preRender: [
|
|
||||||
myCoolMethod,
|
|
||||||
myEvenCoolerMethod
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -1,19 +0,0 @@
|
||||||
---
|
|
||||||
title: Using hooks without a plugin
|
|
||||||
order: 85
|
|
||||||
---
|
|
||||||
|
|
||||||
You can attach a method to a hook at run-time without the need for a plugin
|
|
||||||
using the [Pattern.on()](/reference/api/pattern/on) method.
|
|
||||||
|
|
||||||
The method takes the hook name as its first argument, and the hook method as its second.
|
|
||||||
|
|
||||||
Below is an example:
|
|
||||||
|
|
||||||
```js
|
|
||||||
pattern.on('preRender', function(svg) {
|
|
||||||
svg.style += "svg { background: yellow;}";
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
Congratulations, you've just made your pattern yellow.
|
|
|
@ -1,58 +0,0 @@
|
||||||
---
|
|
||||||
title: Using hooks
|
|
||||||
order: 70
|
|
||||||
---
|
|
||||||
|
|
||||||
For each hook, your plugin should provide a method that takes the relevant data
|
|
||||||
as its first argument. If data was passed when the hook was loaded, you will receive
|
|
||||||
that as the second object.
|
|
||||||
|
|
||||||
Remember that:
|
|
||||||
|
|
||||||
- The `insertText` hook will receive a locale and string and you should return a string.
|
|
||||||
- All other hooks receive an object. You don't need to return anything, but rather modify the object you receive.
|
|
||||||
|
|
||||||
Let's look at an example:
|
|
||||||
|
|
||||||
```js
|
|
||||||
import myStyle from './style';
|
|
||||||
import myDefs from './defs';
|
|
||||||
import {name, version} from '../package.json';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name,
|
|
||||||
version,
|
|
||||||
hooks: {
|
|
||||||
preRender: function(svg) {
|
|
||||||
if (svg.attributes.get("freesewing:plugin-"+name) === false) {
|
|
||||||
svg.style += myStyle;
|
|
||||||
svg.defs += myDefs;
|
|
||||||
svg.attributes.add("freesewing:plugin-"+name, version);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
insertText: function(text) {
|
|
||||||
return text.toUpperCase();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
This is a complete plugin, ready to be published on NPM. It uses two hooks:
|
|
||||||
|
|
||||||
- `preRender` : We add some style and defs to our SVG
|
|
||||||
- `insertText` : We transfer all text to UPPERCASE
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
|
|
||||||
###### Note that we avoid running our hook twice
|
|
||||||
|
|
||||||
As you can see, the last thing we do in the `preRender` hook is set an attribute on
|
|
||||||
the SVG tag with the name and version of our plugin.
|
|
||||||
|
|
||||||
We check for this attribute when the `preRender` hook runs, thereby avoiding that
|
|
||||||
our styles and defs will be added twice.
|
|
||||||
|
|
||||||
It is good practice to wrap you hook methods in a call like this, because you have
|
|
||||||
no guarantee the user won't render your pattern more than once.
|
|
||||||
|
|
||||||
</Note>
|
|
|
@ -47,6 +47,24 @@ The following packages have been removed in v3:
|
||||||
- **@freesewing/plugin-export-dxf**: DXF is kinda garbage, you deserve better
|
- **@freesewing/plugin-export-dxf**: DXF is kinda garbage, you deserve better
|
||||||
- **@freesewing/plugin-validate**
|
- **@freesewing/plugin-validate**
|
||||||
|
|
||||||
|
### API changes
|
||||||
|
|
||||||
|
#### Use log instead of raise
|
||||||
|
|
||||||
|
The `raise` object that held methods for logging has been replaced by log:
|
||||||
|
|
||||||
|
```mjs
|
||||||
|
// strikeout-start
|
||||||
|
raise.warning('This raise object no longer exists')
|
||||||
|
// strikeout-end
|
||||||
|
// highlight-start
|
||||||
|
raise.info('Use the log object instead')
|
||||||
|
// highlight-end
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that `log` can be destructured in your draft method.
|
||||||
|
Refer to [the `Store.log` documentation](/reference/api/store/log) for all details.
|
||||||
|
|
||||||
## Migrating designs
|
## Migrating designs
|
||||||
|
|
||||||
### Design configuration
|
### Design configuration
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue