Skip to content

Commit 42fa034

Browse files
Update readme
1 parent 8fedbcc commit 42fa034

File tree

4 files changed

+85
-75
lines changed

4 files changed

+85
-75
lines changed

readme.md

+57-59
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ Create the component:
2626

2727
``` html
2828
<!-- src/button.html -->
29-
<button class="btn btn-primary">
30-
<slot></slot>
29+
<button type="button" class="btn">
30+
<yield></yield>
3131
</button>
3232
```
3333

@@ -37,7 +37,7 @@ Use the component:
3737
<!-- src/index.html -->
3838
<html>
3939
<body>
40-
<x-button>Submit</x-button>
40+
<x-button type="submit" class="btn-primary">Submit</x-button>
4141
</body>
4242
</html>
4343
```
@@ -62,42 +62,65 @@ Result:
6262
<!-- dist/index.html -->
6363
<html>
6464
<body>
65-
<button class="btn btn-primary">Submit</button>
65+
<button type="submit" class="btn btn-primary">Submit</button>
6666
</body>
6767
</html>
6868
```
6969

70+
You may ask yourself many questions about this basic examples, and you will find most if not all answers in this readme. In case is missing something, feel free to ask via discussions.
71+
72+
But I want to explain a few things now.
73+
74+
First you may notice that our `src/button.html` component has a `type` and `class` attribute, and when we use the component in `src/index.html` we add type and class attribute. The result is that `type` is override, and `class` is merged.
75+
76+
By default `class` and `style` attributes are merged, while all others attribute are override. You can also override class and style attribute by prepending `override:` to the class attribute. Example:
77+
78+
```html
79+
<x-button override:class="btn-custom">Submit</x-button>
80+
81+
<!-- Output -->
82+
<button type="button" class="btn-custom">Submit</button>
83+
```
84+
85+
All attributes you pass to the component will be added to the first root element of your component, and only if they are not defined as `props` via `<script props>`. More details on this later.
86+
87+
Second you may notice a `<yield>` tag.
88+
89+
This is where your content will be injected.
90+
91+
In next section you can find all available options and then more examples.
92+
7093
## Options
7194

72-
| Option | Default | Description |
73-
|:------------------------:|:-------------------------:|:---------------------------------------------------------------------------------------------------------------|
74-
| **root** | `'./'` | String value as root path for components lookup. |
75-
| **roots** | `''` | Array of additional multi roots path from `options.root`. |
76-
| **namespaces** | `[]` | Array of namespace's root path, fallback path and custom path for override. |
77-
| **namespaceSeparator** | `::` | String value for namespace separator to be used with tag name. Example `<x-namespace::button>` |
78-
| **namespaceFallback** | `false` | Boolean value for use fallback path to defined roots in `options.roots`. |
79-
| **fileExtension** | `html` | String value for file extension of the components used for retrieve x-tag file. |
80-
| **tagPrefix** | `x-` | String for tag prefix. |
81-
| **tagRegExp** | `new RegExp('^x-'), 'i')` | Object for regex used to match x-tag. Set only `options.tagPrefix` to keep default. |
82-
| **slotTagName** | `slot` | String value for slot tag name. |
83-
| **fallbackSlotTagName** | `false` | Boolean or string value used to support posthtml-modules slot. Set to true to use `<content>` or set a string. |
84-
| **tagName** | `component` | String value for component tag. |
85-
| **tagNames** | `[]` | Array of additional component tag. Useful if you are migrating from extend and modules. |
86-
| **attribute** | `src` | String value for component attribute for set path. |
87-
| **attributes** | `[]` | Array of additional component path to be used for migrating from extend and modules. |
88-
| **expressions** | `{}` | Object to configure `posthtml-expressions`. You can pre-set locals or customize the delimiters for example. |
89-
| **plugins** | `[]` | PostHTML plugins to apply for every parsed components. |
90-
| **encoding** | `utf8` | String value for the encoding of the component. |
91-
| **scriptLocalAttribute** | `props` | String value for set custom attribute parsed by the plugin to retrieve locals in the components. |
92-
| **matcher** | `[]` | Array of object used to match the tags. Useful if you are migrating from extend and modules. |
93-
| **strict** | `true` | Boolean value for enable or disable throw an exception. |
95+
| Option | Default | Description |
96+
|:----------------------:|:----------------------------:|:------------------------------------------------------------------------------------------------------------|
97+
| **root** | `'./'` | String value as root path for components lookup. |
98+
| **roots** | `['']` | Array of additional multi roots path from `options.root`. |
99+
| **tagPrefix** | `x-` | String for tag prefix. |
100+
| **tag** | `false` | String or boolean value for component tag. Use this with `options.attribute`. Boolean only false. |
101+
| **attribute** | `src` | String value for component attribute for set path. |
102+
| **namespaces** | `[]` | Array of namespace's root path, fallback path and custom path for override. |
103+
| **namespaceSeparator** | `::` | String value for namespace separator to be used with tag name. Example `<x-namespace::button>` |
104+
| **namespaceFallback** | `false` | Boolean value for use fallback path to defined roots in `options.roots`. |
105+
| **fileExtension** | `html` | String value for file extension of the components used for retrieve x-tag file. |
106+
| **yield** | `yield` | String value for `<yield>` tag name. Where main content of component is injected. |
107+
| **slot** | `slot` | String value for `<slot>` tag name. |
108+
| **fill** | `fill` | String value for `<fill>` tag name. |
109+
| **push** | `push` | String value for `<push>` tag name. |
110+
| **stack** | `stack` | String value for `<stack>` tag name. |
111+
| **localsAttr** | `props` | String value used in `<script props>` parsed by the plugin to retrieve locals in the components. |
112+
| **expressions** | `{}` | Object to configure `posthtml-expressions`. You can pre-set locals or customize the delimiters for example. |
113+
| **plugins** | `[]` | PostHTML plugins to apply for every parsed components. |
114+
| **matcher** | `[{tag: options.tagPrefix}]` | Array of object used to match the tags. |
115+
| **attrsParserRules** | `{}` | Additional rules for attributes parser plugin. |
116+
| **strict** | `true` | Boolean value for enable or disable throw an exception. |
94117

95118
## Features
96119

97120
### Tag names and x-tags
98121

99122
You can use the components in multiple ways, or also a combination of them.
100-
Like with `posthtml-extend` and `posthtml-modules` you can define a tag name or multiples tag name in combination with an attribute name or multiple attributes name for set the path to the components.
123+
Like with `posthtml-extend` and `posthtml-modules` you can define a tag name in combination with an attribute name for set the path of the components.
101124

102125
For example for the same button component `src/button.html` in the basic example we can define the tag name and attribute name and then use it in this way:
103126

@@ -120,34 +143,6 @@ require('posthtml')(require('posthtml-components')({ root: './src', tagName: 'co
120143
.then(/* ... */)
121144
```
122145

123-
We can also set multiple tag names by passing an array of component name and an array of attribute name, this is useful if you need to migrate from `posthtml-extend` and `posthtml-modules` where you are using different tag name.
124-
125-
Init PostHTML with multiple tag names and attributes:
126-
127-
``` html
128-
<!-- src/index.html -->
129-
<html>
130-
<body>
131-
<extends src="button.html">Submit</extends>
132-
<module href="button.html">Submit</module>
133-
</body>
134-
</html>
135-
```
136-
137-
```js
138-
// index.js
139-
140-
const options = {
141-
root: './src',
142-
tagNames: ['extends', 'module'],
143-
attributes: ['src', 'href']
144-
};
145-
146-
require('posthtml')(require('posthtml-components')(options))
147-
.process(/* ... */)
148-
.then(/* ... */)
149-
```
150-
151146
If you need more control over how to match the tags, you can pass directly an array of matcher or single object via `options.matcher` like shown in below example:
152147

153148
```js
@@ -198,7 +193,7 @@ If your components are in a subfolder then you can use `dot` to access it, examp
198193
<x-forms.button>Submit</x-forms.button>
199194
```
200195

201-
If your components are in a sub-folder with multiple files, then for avoid to type the main file you can use `index.html` without specify it.
196+
If your components are in a sub-folder with multiple files, then for avoid typing the main file you can use `index.html` without specify it.
202197
Please see below example to understand better.
203198

204199
``` html
@@ -244,11 +239,13 @@ With namespaces you can define a top level root path to your components like sho
244239

245240
### Slots
246241

242+
### Stacks
243+
247244
### Props
248245

249-
### Matcher
246+
### Attributes
250247

251-
## Migration from posthtml-extend and posthtml-modules
248+
## Migration
252249

253250
## Contributing
254251

@@ -265,4 +262,5 @@ See [PostHTML Guidelines](https://github.com/posthtml/posthtml/tree/master/docs)
265262

266263
## Credits
267264

268-
Thanks to all PostHTML contributors and especially to `posthtml-extend` and `posthtml-modules` contributors, as part of code are ~~stolen~~ borrowed from these plugins.
265+
Thanks to all PostHTML contributors and especially to `posthtml-extend` and `posthtml-modules` contributors, as part of code are ~~stolen~~ inspired from these plugins.
266+
Huge thanks also to Laravel Blade template engine!

src/index.js

+16-4
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ module.exports = (options = {}) => tree => {
2525
options.root = path.resolve(options.root || './');
2626
options.roots = options.roots || [''];
2727
options.tagPrefix = options.tagPrefix || 'x-';
28+
options.tag = options.tag || false;
29+
options.attribute = options.attribute || 'src';
2830
options.namespaces = options.namespaces || [];
2931
options.namespaceSeparator = options.namespaceSeparator || '::';
3032
options.namespaceFallback = options.namespaceFallback || false;
3133
options.fileExtension = options.fileExtension || 'html';
32-
options.tag = options.tag || 'component';
33-
options.attribute = options.attribute || 'src';
3434
options.yield = options.yield || 'yield';
3535
options.slot = options.slot || 'slot';
3636
options.fill = options.fill || 'fill';
@@ -39,12 +39,24 @@ module.exports = (options = {}) => tree => {
3939
options.localsAttr = options.localsAttr || 'props';
4040
options.expressions = options.expressions || {};
4141
options.plugins = options.plugins || [];
42-
options.strict = typeof options.strict === 'undefined' ? true : options.strict;
4342
options.attrsParserRules = options.attrsParserRules || {};
43+
options.strict = typeof options.strict === 'undefined' ? true : options.strict;
44+
4445
options.slot = new RegExp(`^${options.slot}:`, 'i');
4546
options.fill = new RegExp(`^${options.fill}:`, 'i');
4647
options.tagPrefix = new RegExp(`^${options.tagPrefix}`, 'i');
47-
options.matcher = options.matcher || [{tag: options.tag}, {tag: options.tagPrefix}];
48+
49+
if (!Array.isArray(options.matcher)) {
50+
options.matcher = [];
51+
if (options.tagPrefix) {
52+
options.matcher.push({tag: options.tagPrefix});
53+
}
54+
55+
if (options.tag) {
56+
options.matcher.push({tag: options.tag});
57+
}
58+
}
59+
4860
options.roots = Array.isArray(options.roots) ? options.roots : [options.roots];
4961
options.roots.forEach((root, index) => {
5062
options.roots[index] = path.join(options.root, root);

test/test-locals.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ test('Must process layout with locals', async t => {
99
const actual = `<component src="layouts/base-locals.html" locals='{ "title": "My Page" }'><div>Content</div><slot:footer>Footer</slot:footer></component>`;
1010
const expected = `<html><head><title>My Page</title></head><body><main><div>Content</div></main><footer>Footer</footer></body></html>`;
1111

12-
const html = await posthtml([plugin({root: './test/templates'})]).process(actual).then(result => clean(result.html));
12+
const html = await posthtml([plugin({root: './test/templates', tag: 'component'})]).process(actual).then(result => clean(result.html));
1313

1414
t.is(html, expected);
1515
});
@@ -18,7 +18,7 @@ test('Must process attributes as locals', async t => {
1818
const actual = `<component src="components/component-locals.html" title="My Component Title" body="Content"><slot:body prepend><span>Body</span></slot:body></component>`;
1919
const expected = `<div><h1>My Component Title</h1></div><div><span>Body</span>Content</div>`;
2020

21-
const html = await posthtml([plugin({root: './test/templates'})]).process(actual).then(result => clean(result.html));
21+
const html = await posthtml([plugin({root: './test/templates', tag: 'component'})]).process(actual).then(result => clean(result.html));
2222

2323
t.is(html, expected);
2424
});
@@ -27,7 +27,7 @@ test('Must process default attributes and map attributes not locals to first nod
2727
const actual = `<component src="components/component-mapped-attributes.html" title="My Title" class="bg-light p-2" style="display: flex; font-size: 20px"></component>`;
2828
const expected = `<div class="text-dark m-3 bg-light p-2" style="display: flex; font-size: 20px">My Title Default body</div>`;
2929

30-
const html = await posthtml([plugin({root: './test/templates'})]).process(actual).then(result => clean(result.html));
30+
const html = await posthtml([plugin({root: './test/templates', tag: 'component'})]).process(actual).then(result => clean(result.html));
3131

3232
t.is(html, expected);
3333
});
@@ -41,7 +41,7 @@ test('Must process component with locals as JSON and string', async t => {
4141
merge:locals='{ "items": ["first item", "second item"] }'></component>`;
4242
const expected = `<div><div>Computed is true</div><div><h1>Custom title from JSON and String</h1></div><div><span>another item</span><span>yet another</span><span>first item</span><span>second item</span></div><div><span>title: This is default main title</span><span>subtitle: This is default subtitle</span><span>suptitle: This is custom suptitle</span></div></div>`;
4343

44-
const html = await posthtml([plugin({root: './test/templates'})]).process(actual).then(result => clean(result.html));
44+
const html = await posthtml([plugin({root: './test/templates', tag: 'component'})]).process(actual).then(result => clean(result.html));
4545

4646
t.is(html, expected);
4747
});

0 commit comments

Comments
 (0)