Custom tags allow you to break up your application UI into encapsulated, reusable components.
Let's say we have a page with the following content:
<html><body><h1>Hello World!</h1></body></html>
htmlbodyh1 -- Hello World!
However, 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:
<h1>Hello World!</h1>
h1 -- Hello World!
Marko automatically discovers .marko
files under a components/
directory, so we can now use the <hello>
tag in our page:
<html><body><hello/></body></html>
htmlbodyhello
Now 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.
<html><body><hello name="World"/></body></html>
htmlbodyhello name="World"
The component will receive these attributes as input
:
<h1>Hello !</h1>
h1 -- Hello !
Nice.
Marko 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.
Let's take a look at an example directory structure to better understand this:
components/app-header.markoapp-footer.markopages/about/components/team-members.markopage.markohome/components/home-banner.markopage.marko
The file pages/home/page.marko
can use the following tags:
<app-header>
<app-footer>
<home-banner>
And the file pages/about/page.marko
can use the following tags:
<app-header>
<app-footer>
<team-members>
The 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.
In addition to a Marko template, the children of components/
can be a directory with an index.marko
template:
components/app-header/index.markologo.pngstyle.cssapp-footer/index.marko
Or a directory with a template whose name matches its parent directory:
components/app-header/app-header.markoapp-header.style.csslogo.pngapp-footer/app-footer.marko
This allows you to create components that have other files associated with them and keep those files together in the directory structure.
ProTip: You can take advantage of nested
components/
directories to create "subcomponents" that are only available to the component that contains them.components/app-header/components/navigation.markouser-info.markoapp-header.markoapp-footer/app-footer.marko
To use tags from npm, ensure that the package is installed and listed in your package.json
dependencies:
npm install --save @marko/match-media
Marko discover tags from packages defined in your package.json
, so you can start using them right away:
<div><match-media{ mobile } mobile="max-width:30em"><!-- nice --></match-media></div>
divmatch-media{ mobile } mobile="max-width:30em"<!-- nice -->
We saw above that tags from npm are automatically discovered. In order to make this work, your package must include a marko.json
at the root.
"tags-dir": "./dist/components"
This example file tells Marko to expose all components directly under the dist/components/
directory to the application using your package.
We recommend adding the marko
and components
keywords to your package.json
so others can find your components. Then npm publish
!
The <macro>
tag allows you to create custom tags in the same file that they are used in.
<macro{ name } name="welcome-message"><h1>Hello !</h1></macro><welcome-message name="Patrick"/><welcome-message name="Austin"/>
macro{ name } name="welcome-message"h1 -- Hello !welcome-message name="Patrick"welcome-message name="Austin"
Helpful? You can thank these awesome people! You can also edit this doc if you see any issues or want to improve it.