Serverside is back baby

Live templates in pure python with Hypergen

Rune Kaagaard & Jeppe Tuxen

1 Hypergen

2 About us

  • Rune Kaagaard - CTO@Prescriba
  • Jeppe Tuxen - Developer@Prescriba
  • Prescriba / onebright : Mental Healthcare
  • Django for about 12 years since version 1.2
  • The Case System (Sagssystemet)

3 The Game Plan

  • Our journey towards liveviews
  • Hypergen - a liveview framework for Django
  • We will build an example app in Hypergen together
  • QA

4 Our journey towards liveviews

4.1 From pure serverside rendering

  • Django: A serverside rendering web framework
  • Models, Views, renders HTML through django template language - easy peasy
  • Request-Response cycle
  • Rendered HTML is stateless
  • One source of truth
  • We love it - simple to code, simple to maintain
  • Old school?
  • More dynamic views - single page apps?

4.2 Over jQuery - partially client-side rendered

  • jQuery - fetch partial state through ajax.
  • Procedurally regenerate part of the DOM
  • Mixing state into DOM elements
  • DOM would get out of sync with state

4.3 Going React - full blown client-side rendering

  • React, a Javascript framework for clientside rendering
  • Declarative
  • Everything is rendered from state so not a problem with DOM beeing out of sync
  • Automatic rerender on state changes
  • Great to work with but at the cost of..
  • A lot more frontend Javascript/JSX code
  • Harder to maintain two languages
  • Serialization
  • We can't use djangos ORM in Javascript
  • Webpack
  • Frontend validation and Backend validation which is right?
  • No single source of truth
  • A lot of overhead

4.4 Liveviews - Serverside is back baby

  • Server renders full HTML page
  • Client events triggers callbacks
  • Server sends partial HTML to client
  • Client updates HTML
  • Rinse and repeat
  • We can again define everything at serverlevel
  • No need to maintain expensive frontend
  • One source of truth

5 Hypergen - liveview for Django

  • Main inspiration: Phoenix Liveview - the mother of liveviews based on Elixir
  • Short for HYPertext GENerator
  • A composable template language written in pure python
  • Builtin liveview capabilities
  • Extendable with plugins

6 Hypergen 101 - the crash course

def my_template():
    section(
        div(
            "All html tags can be rendered using python ",
            "functions with the same name", 
            span("Inside a span tag", 
                 class_="my-class")
        )
    )
    
<section>
    <div>
        All html tags can be rendered using simple python 
        functions with the same name,
        <span class="my-class">Inside a span tag</span>
    </div>
</section>

6.1 Tag functions

6.1.1 Children and attributes

p("One", " two", 3, title="Read me!")
<p title="Read me!">One two3</p>

6.1.2 Iterables

p([1, 2, 3], (x for x in range(4,6)))
<p>123456</p>

6.1.3 Id, class and style

p("Hi", id=["foo", 42], 
  class_={"class1", "class2"}, 
  style=dict(background_color="green"))
<p class="class2 class1" 
   style="background-color:green" id="foo-42">Hi</p>

6.1.4 Separator and ending.

p("Hello", "world", sep=" ", end="!")
<p>Hello world!</p>

6.2 Pure Python

  • Conditionals
  • Loops
  • With statements
  • Access djangos ORM

6.3 Composable: Create reusable components

def yes_or_no_component(is_active):
    span("YES" if is_active else "NO")

def row_component(instance):
    # We can use tag functions as context managers
    with tr(class_="green" if instance.is_active else ""):
        td(instance.id)
        td(instance.name)
        td(
            yes_or_no_component(instance.is_active)
        )
 
def _table():
            with table():
        tr(
            th("ID"),
            th("Name"),
            th("Active")
        )
            for instance in SomeDjangoModel.objects.all():
            # Using the previously defined component
            row_component(instance)

        

7 Enough Talk - lets create an app

https://github.com/runekaagaard/hypergen-djangocon-2022