Giter Club home page Giter Club logo

nate's Introduction

Library

nate

PyPI PyPI - License Build Status

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 or Django templates.

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 installed, run

$ pip install nate

Usage

Import the elements you need.

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

Construct your tree.

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.

table.to_html()  #=> <table><thead>....

Raw text nodes are escaped by default, thus making it difficult to introduce XSS vulnerabilities.

p = P("<script>alert('XSS');</script>")
p.to_html()  #=> <p>&lt;script&gt;alert(&#x27;XSS&#x27;);&lt;/script&gt;</p>

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.

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()  #=> <div class="my-component>...

Examples

nate HTML
Title("Hello World!").to_html()
<title>Hello World!</title>
steaks = ["Rib Eye", "New York Strip", "Porterhouse"]
Ul(map(lambda steak: Li(steak), steaks)).to_html()
<ul>
  <li>Rib Eye</li>
  <li>New York Strip</li>
  <li>Porterhouse</li>
</ul>
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()
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8"/>
        <title>Welcome to nate!</title>
    </head>
    <body>
        <h1>Mission</h1>
        <p class="red">nate is not a template engine.</p>
    </body>
</html>

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 - While written in Ruby, the page.rb library inspired this project.
  • hyperscript - Pure JavaScript alternative to JSX.
  • hyperpython - Python interpretation of hyperscript.
  • XHPy - Extends Python syntax such that XML document fragments become valid Python expressions. Based off XHP, a similar framework for PHP.

License

MIT

nate's People

Contributors

alexandergugel avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.