Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/alexandergugel/nate

πŸ“ nate makes generating HTML fun.
https://github.com/alexandergugel/nate

html python template template-engine template-engine-html website

Last synced: 3 months ago
JSON representation

πŸ“ nate makes generating HTML fun.

Awesome Lists containing this project

README

        

![Library](https://github.com/alexanderGugel/nate/raw/master/assets/alfons-morales-YLSwjSy7stw-unsplash.jpg)

# nate

[![PyPI](https://img.shields.io/pypi/v/nate)](https://pypi.org/project/nate/) [![PyPI - License](https://img.shields.io/pypi/l/nate)](https://pypi.org/project/nate/) [![Build Status](https://travis-ci.com/alexanderGugel/nate.svg?branch=master)](https://travis-ci.com/alexanderGugel/nate)

**nate** makes generating HTML fun. Rather than forcing you to adopt an entirely different templating language that comes with its own set of quirks, nate is built around a simple, but powerful Python DSL that enables you to easily compose trees of elements that can be translated to well-formed HTML - no more forgotten angle brackets, unbalanced tags, or unescaped user input.

Think of nate as an alternative to [Jinja](https://jinja.palletsprojects.com/en/2.11.x/) or [Django templates](https://docs.djangoproject.com/en/3.1/ref/templates/language/).

## Features

- **Mostly typed** - The API has been designed with type safety in mind: All
function boundaries have type hints to ensure correctness, ease
documentation, and make auto-completion in the IDE of your choice a piece of
cake.
- **No dependencies** - nate does not depend on any third-party libraries.
- **Stable API** - The API itself is stable. No breaking changes are planned.
- **Tiny** - The core library is approximately 500 eLOC, which is tiny and
can be manually audited on a single afternoon.

## Install

With [pip](https://pip.pypa.io/en/stable/installing/) installed, run

```
$ pip install nate
```

## Usage

Import the elements you need.

```python
from nate import Table, Thead, Th, Tr, Tbody, Td
```

Construct your tree.

```python
politicians = [
{"first_name": "Theodor", "last_name": "Heuss", "party": "FDP"},
{"first_name": "Heinrich", "last_name": "LΓΌbke", "party": "CDU"},
{"first_name": "Gustav", "last_name": "Heinemann", "party": "SPD"},
# ...
]

table = Table(
[
Thead(Th([Tr("First Name"), Tr("Last Name"), Tr("Party")])),
Tbody(map(
lambda politician: Tr(
[
Td(politician["first_name"]),
Td(politician["last_name"]),
Td(politician["party"]),
]
),
politicians,
)),
]
)
```

Call `.to_html()` on your root node to serialize your tree to a string of HTML.

```python
table.to_html() #=> ....
```

Raw text nodes are escaped by default, thus making it difficult to introduce [XSS vulnerabilities](https://en.wikipedia.org/wiki/Cross-site_scripting).

```python
p = P("alert('XSS');")
p.to_html() #=>

<script>alert('XSS');</script>


```

### Components

Templating languages tend to come with their own abstractions for building re-usable components. There is no need for those in nate, given that component hierarchies can easily be composed using plain Python functions.

```python
from nate import Div, H1, P, BaseTag

def MyComponent(title: str, description: str) -> BaseTag:
return Div(
children=[
H1(title),
P(description),
],
class_="my-component",
)

component = MyComponent(
title="My title",
description="My description",
)

component.to_html() #=>

```html
Hello World!
```

```python
steaks = ["Rib Eye", "New York Strip", "Porterhouse"]
Ul(map(lambda steak: Li(steak), steaks)).to_html()
```

```html


  • Rib Eye

  • New York Strip

  • Porterhouse


```

```python
Html(
lang="en",
children=[
Head(
children=[
Meta(charset="utf-8"),
Title(children="Welcome to nate!"),
]
),
Body(
children=[
H1("Mission"),
P(
"nate is not a template engine.",
class_="red",
),
],
),
],
).to_html()
```

```html



Welcome to nate!


Mission


nate is not a template engine.


```

## How to contribute

- Keep it simple, don't do anything too crazy. Even folks that don't know Python should be able to understand the code without any issues.
- Design APIs with type-safety in mind.
- If your code slows things down, it won't get merged.
- Avoid introducing new dependencies.
- If you don't want to follow those rules, forking is _encouraged_!
- Ensure new code is covered by corresponding tests.

## Prior works of art

- [lamernews](https://github.com/antirez/lamernews) - While written in Ruby, the [`page.rb`](https://github.com/antirez/lamernews/blob/master/page.rb) library inspired this project.
- [hyperscript](https://github.com/hyperhype/hyperscript) - Pure JavaScript alternative to JSX.
- [hyperpython](https://github.com/ejplatform/hyperpython) - Python interpretation of hyperscript.
- [XHPy](https://pypi.org/project/xhpy/) - Extends Python syntax such that XML document fragments become valid Python expressions. Based off XHP, a similar framework for PHP.

## License

MIT