---
# System prepended metadata

title: Template render kata

---

**Kata notes**
* State machine
* Data-structures
* Render from bottom to top
* Could be outside-in or inside-out
* Testing doubles
* SOLID
* Object calisthenics

Based on my past experience with:
* https://labs.habitissimo.com/2018/11/06/web-components-en-php-i-que-es-un-componente/
* https://labs.habitissimo.com/2019/08/08/webcomponents-en-php-ii-navegadores/

---

# Template render kata

## Business rules
 We are trying to build our own small Web Component to HTML render or as we could call it our template system, because we want to create our own web page using it.

The thing it's that we want to create components that we could reuse on all of our website.

 Our first Web Components are:
 - Logo
 - Nav
 - NavLink
 - TopNav
 - Content
 - Article
 - ArticleTitle
 - ArticleContent
 - Footer

## Other important rules
* The Web Components can contain other Web Components.
* The Web Components will have a default state
* The Web Components could have attributes that will be render also on the template
* If we try to load a Web Component that does not exist we should throw an exception and stop the execution.

# What are web components
They are tags that we will use to reuse the code that we do not want to duplicate for instance:
to make a difference bettwen an HTML tag and a Web Component we start the tag with a mayus.

The Web Component Tags can be self closed or not. HTML tags can and will coexist with 

The logo would be web component would be:
```html
<Logo />
```
And it would render to:

```html
<a href="https://www.yourweb.com/" title="my awesome web" class="navbar-brand">
    <img src="https://via.placeholder.com/150" alt="this is my personal and awesome website">
</a>
```

As you may see, if we do not provide any attribute to the component this will have some default values, this values should be set on the template. But if any of this attributes changes the component will change them on the HTML that it will render, for example:


The logo would be web component with attributes
```html
<Logo title="a random title" class="no-class" src="https://via.placeholder.com/50"/>
```
And it would render to:

```html
<a href="https://www.yourweb.com/" title="a random title" class="no-class">
    <img src="https://via.placeholder.com/50" alt="this is my personal and awesome website">
</a>
```

This is a small example of how this template system works.

# Web Component to HTML render
**Logo component**:
From
```html
<Logo />
```
To
```html
<a href="https://www.yourweb.com/" title="my awesome web" class="navbar-brand">
    <img src="https://via.placeholder.com/150" alt="this is my personal and awesome website">
</a>
```

**Nav component**:
From
```html
<Nav></Nav>
```
To
```html
<nav class="navbar navbar-default">
    <ul class="nav navbar-nav">
    </ul>
</nav>
```

**NavLink component**:
From
```html
<NavLink href="#page1"></NavLink>
```
To
```html
<li><a href="#page1">Page 1</a></li>
```

**Content component**:
From
```html
<Content></Content>
```
To
```html
<main></main>
```

**Footer component**:
From
```html
<Footer></Footer>
```
To
```html
<footer class="main-footer"></footer>
```

**Article component**:
From
```html
<Article></Article>
```
To
```html
<article class="article"></article>
```

**ArticleTitle component**:
From
```html
<ArticleTitle></ArticleTitle>
```
To
```html
<h2 class="article-title"></h2>
```

**ArticleContent component**:
From
```html
<ArticleContent></ArticleContent>
```
To
```html
<p class="article-content"></p>
```

## Complex example

**Web Components**
```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>About me</title>
</head>
<body>
  <TopNav>
    <Logo />
    <Nav>
      <NavLink href="#page1">Page 1</NavLink>
      <NavLink href="#page1">Page 2</NavLink>
      <NavLink href="#page3" target="_blank">Page 3</NavLink>
    </Nav>
  </TopNav>
  <Content alt="About me">
    <Article title="Page 1" id="page1">
      <ArticleTitle>Page 1</ArticleTitle>
      <ArticleContent><p>1 Lorem ipsum dolor sit amet, consectetur.</p></ArticleContent>
    </Article>
    <Article title="Page 2" id="page2">
      <ArticleTitle>Page 2</ArticleTitle>
      <ArticleContent><p>2 Lorem ipsum dolor sit amet, consectetur.</p></ArticleContent>
    </Article>
    <Article title="Page 3" id="page3">
      <ArticleTitle>Page 3</ArticleTitle>
      <ArticleContent>
        <p>3 Lorem ipsum dolor sit amet, consectetur.</p>
      </ArticleContent>
    </Article>
  </Content>
  <Footer>
    <Nav>
      <NavLink href="#page1">Page 1</NavLink>
      <NavLink href="#page1">Page 2</NavLink>
      <NavLink href="#page3" target="_blank">Page 3</NavLink>
    </Nav>
  </Footer>
</body>
</html>
```

**Rendered HTML**
```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>About me</title>
</head>
<body>
  <section class="top-bar">
    <a href="https://www.yourweb.com/" title="my awesome web" class="navbar-brand">
      <img src="https://via.placeholder.com/150" alt="this is my personal and awesome website">
    </a>
    <nav class="navbar navbar-default">
      <ul class="nav navbar-nav">
        <li><a href="#page1">Page 1</a></li>
        <li><a href="#page2">Page 2</a></li>
        <li><a href="#page3" target="_blank">Page 3</a></li>
      </ul>
    </nav>
  </section>
  <main alt="About me">
    <article title="Page 1" id="page1">
      <h2 class="article-title">Page 1</h2>
      <p class="article-content">1 Lorem ipsum dolor sit amet, consectetur, Lorem ipsum dolor sit amet, consectetur.</p>
    </article>
    <article title="Page 2" id="page2">
      <h2 class="article-title">Page 2</h2>
      <p class="article-content">2 Lorem ipsum dolor sit amet, consectetur, Lorem ipsum dolor sit amet, consectetur.</p>
    </article>
    <article title="Page 1" id="page1">
      <h2 class="article-title">Page 1</h2>
      <p class="article-content">3 Lorem ipsum dolor sit amet, consectetur, Lorem ipsum dolor sit amet, consectetur.</p>
    </article>
  </main>
  <footer class="main-footer">
    <nav class="navbar navbar-default">
      <ul class="nav navbar-nav">
        <li><a href="#page1">Page 1</a></li>
        <li><a href="#page2">Page 2</a></li>
        <li><a href="#page3" target="_blank">Page 3</a></li>
      </ul>
    </nav>
  </footer>
</body>
</html>
```


# Possible collaborators
You could create as many collaborators as you'd like some of them may be:
- Token
- Tokenizer
- WebComponent
- TemplateFinder / TemplateRepository
- Render
- Parser


**Remember to follow SOLID and Object calisthenics**

# Technical requiraments
- The render has to be fast because is going to be use on each request before responding the user.
- We also have to be aware of the memory usage.

# What can I practice with this kata
- Outside-in
- Working with collaborators
- Baby steps
- Object Calisthenics
- Test doubles
- Load test / Benchmarking tool
- State machine
- Data-structures
- Design patterns
    - Null Object
    - Builders
    - Factory
    - Could use Repository