UNPKG

4.61 kBMarkdownView Raw
1# Custom tags
2
3Custom tags allow you to break up your application UI into encapsulated, reusable components.
4
5## Your first custom tag
6
7Let's say we have a page with the following content:
8
9_page.marko_
10
11```marko
12<!doctype html>
13<html>
14<body>
15 <h1>Hello World!</h1>
16</body>
17</html>
18```
19
20However, this page is getting pretty complex and unmaintainable. Let's split out the content into a separate component. To do this, we'll create a `components/` folder and inside it a `hello.marko` file:
21
22_components/hello.marko_
23
24```marko
25<h1>Hello World!</h1>
26```
27
28Marko [automatically discovers](#how-tags-are-discovered) `.marko` files under a `components/` directory, so we can now use the `<hello>` tag in our page:
29
30_page.marko_
31
32```marko
33<!doctype html>
34<html>
35<body>
36 <hello/>
37</body>
38</html>
39```
40
41Now this `<hello>` tag can be used multiple times, and even on multiple pages. But what if we don't only want to say hello to the world? Let's pass some attributes.
42
43_page.marko_
44
45```marko
46<!doctype html>
47<html>
48<body>
49 <hello name="World"/>
50</body>
51</html>
52```
53
54The component will receive these attributes as `input`:
55
56_components/hello.marko_
57
58```marko
59<h1>Hello ${input.name}!</h1>
60```
61
62Nice.
63
64## How tags are discovered
65
66Marko discovers components relative to the `.marko` file where a custom tag is used. From this file, Marko walks up directories until it finds a `components/` folder which contains a component matching the name of the custom tag. If it reaches the project root without finding anything, it will then check installed packages for the component.
67
68Let's take a look at an example directory structure to better understand this:
69
70```dir
71components/
72 app-header.marko
73 app-footer.marko
74pages/
75 about/
76 components/
77 team-members.marko
78 page.marko
79 home/
80 components/
81 home-banner.marko
82 page.marko
83```
84
85The file `pages/home/page.marko` can use the following tags:
86
87- `<app-header>`
88- `<app-footer>`
89- `<home-banner>`
90
91And the file `pages/about/page.marko` can use the following tags:
92
93- `<app-header>`
94- `<app-footer>`
95- `<team-members>`
96
97The home page can't see `<team-members>` and the about page can't see `<home-banner>`. By using nested `component/` directories, we've scoped our page-specific components to their respective pages.
98
99## Tag directories
100
101In addition to a Marko template, the children of `components/` can be a directory with an `index.marko` template:
102
103```dir
104components/
105 app-header/
106 index.marko
107 logo.png
108 style.css
109 app-footer/
110 index.marko
111```
112
113Or a directory with a template whose name matches its parent directory:
114
115```dir
116components/
117 app-header/
118 app-header.marko
119 app-header.style.css
120 logo.png
121 app-footer/
122 app-footer.marko
123```
124
125This allows you to create components that have other files associated with them and keep those files together in the directory structure.
126
127> **ProTip:**
128> You can take advantage of nested `components/` directories to create "subcomponents" that are only available to the component that contains them.
129>
130> ```dir
131> components/
132> app-header/
133> components/
134> navigation.marko
135> user-info.marko
136> app-header.marko
137> app-footer/
138> app-footer.marko
139> ```
140
141## Using tags from npm
142
143To use [tags from npm](https://www.npmjs.com/search?q=keywords%3Amarko%20components), ensure that the package is installed and listed in your `package.json` dependencies:
144
145```
146npm install --save @marko/match-media
147```
148
149Marko discover tags from packages defined in your `package.json`, so you can start using them right away:
150
151```marko
152<div>
153 <match-media|{ mobile }| mobile="max-width:30em">
154 <!-- nice -->
155 </match-media>
156</div>
157```
158
159## Publishing tags to npm
160
161We saw above that tags from npm are automatically discovered. In order to make this work, your package must include a [`marko.json`](./marko-json.md) at the root.
162
163_marko.json_
164
165```json
166{
167 "tags-dir": "./dist/components"
168}
169```
170
171This example file tells Marko to expose all components directly under the `dist/components/` directory to the application using your package.
172
173We recommend adding the `marko` and `components` keywords to your `package.json` so others can find your components. Then `npm publish`!
174
175# Macros
176
177The [`<macro>`](./core-tags.md#macro) tag allows you to create custom tags in the same file that they are used in.
178
179```marko
180<macro|{ name }| name="welcome-message">
181 <h1>Hello ${name}!</h1>
182</macro>
183
184<welcome-message name="Patrick"/>
185<welcome-message name="Austin"/>
186```