Writing our First Lightning App!
Creating our Templates
A template is what our views render and show to the user. They can be populated programmatically or hard-coded. This is what we’ll use to take a form input from the user and use it on our backend. They are predominately HTML with some Jinja2 / templating code to make it programmatic mixed in. For the purpose of our template, we’ll only make use of this slightly.
To get started, create a new folder called templates
in the lightning_address_payment
folder.
Next in the templates folder, create another folder called lightning_address_payment
inside the templates
folder. We know it’s weird, but that’s just how Django works with the templates.
Let’s start by creating the base HTML file that can be extended to all of our other templates.
Base, Parent, or Skeleton Template
In the lightning_address_payment/templates/lightning_address_payment
directory, create a new file called base.html
.
Here is the base skeleton template file that we will use to extend to our other templates. It’ll make it faster to develop and populate the skeleton template using our block tags. This will overall, speed up development significantly. This skeleton template uses Bootstrap and a couple of the templating code we previously discussed. You can review the documentation here.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}{% endblock %}</title>
<link href="<https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css>" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
</head>
<body>
{% block content %}{% endblock %}
<script src="<https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js>" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
</body>
</html>
This template, which we’ll call base.html
, defines an HTML skeleton document that you might use for a two-column page. It’s the job of “child” templates to fill the empty blocks with content.
Check out the screenshot to see the folder structure with the file.
💡 In this example, the [block](<https://docs.djangoproject.com/en/4.1/ref/templates/builtins/#std-templatetag-block>)
tag defines three blocks that child templates can fill in. All the [block](<https://docs.djangoproject.com/en/4.1/ref/templates/builtins/#std-templatetag-block>)
tag does is to tell the template engine that a child template may override those portions of the template.
Now let’s create the first child template.
Index / Home — Child Template
The home child template will need to contain the following requirements.
- Header
- A form including:
- Input field for the Lightning Address
- Amount input field for the amount of bitcoin we want to send, specified in sats.
It’ll look like the following once we’ve added the title.
{% extends "base.html" %}
{% block title %}Home{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="col">
<h3>Make a Lightning Address Payment</h3>
</div>
</div>
</div>
{% endblock %}
- The
extends
tag is the key here. It tells the template engine that this template “extends” another template. When the template system evaluates this template, first it locates the parent – in this case, “base.html”.
Now let’s add the form.
{% extends "lightning_address_payment/base.html" %}
{% block title %}Home{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="col">
<h3>Make a Lightning Address Payment</h3>
</div>
</div>
<div class="row">
<form action="{% url 'index' %}" method="post">
{% csrf_token %}
<div class="col-4">
<div class="mb-3">
<label class="form-label">Lightning Address</label>
<input type="email" class="form-control" placeholder="name@example.com" name="lnaddress" required>
</div>
</div>
<div class="col-4">
<label class="form-label" name="amount">Amount</label>
<div class="input-group mb-3">
<input type="number" class="form-control" required>
<span class="input-group-text">sats</span>
</div>
</div>
<div class="col-4">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</div>
</div>
{% endblock %}
Awesome! Let’s get our last template setup. It’ll be much easier.
Success — Child Template
All we need for the success page, is a header and a description. Create a new template file called success.html
in the same directory.
{% extends "base.html" %}
{% block title %}Success{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="col">
<h3>Success!</h3>
<p>You just made a Lightning Address payment!</p>
</div>
</div>
</div>
{% endblock %}
Now we’re all setup. We will only need to make one minor change once we have our views and routes setup in the index.html
file.
Modifying our Views
Head back to the lightning_address_payment/views.py
file. Let’s update this file with everything that we need.
Let’s start off simple by rendering our templates in our views. Update your file to now replace the HttpResponse
with a render.
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def index(request):
# return render instead
return render(request, 'lightning_address_payment/index.html')
def success(request):
# return render instead
return render(request, 'lightning_address_payment/success.html')
Let’s run our server and check out the templates! Looking good so far.