Browse Source

Start porting stuff from Django templates to Jinja2 - I've only done the lemonauth templates so far, and the layout is missing some meta stuff (hoping to reduce how much of that is needed) but it works

pull/1/head
Danielle McLean 4 years ago
parent
commit
b59962a119
Signed by: 00dani GPG Key ID: 8EB789DDF3ABD240
  1. 1
      Pipfile
  2. 16
      Pipfile.lock
  3. 74
      lemonauth/jinja2/lemonauth/indie.html
  4. 61
      lemonauth/jinja2/lemonauth/login.html
  5. 21
      lemoncurry/jinja2.py
  6. 67
      lemoncurry/jinja2/lemoncurry/layout.html
  7. 8
      lemoncurry/settings/base.py

1
Pipfile

@ -46,6 +46,7 @@ gevent = "*"
django-extensions = "*"
python-magic = "*"
pyup-django = "*"
"jinja2" = "*"
[dev-packages]
ptpython = "*"

16
Pipfile.lock

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "7e1c8e47e62347ea8efb99864ab1630c617caf37856b1a339057556f9aa202f7"
"sha256": "a0fb5f4752579f5f354d4b55ffcf07ed67d716895e6f52b954c576b4424acaf5"
},
"pipfile-spec": 6,
"requires": {
@ -391,6 +391,14 @@
],
"version": "==0.6.0"
},
"jinja2": {
"hashes": [
"sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd",
"sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4"
],
"index": "pypi",
"version": "==2.10"
},
"lxml": {
"hashes": [
"sha256:01c45df6d90497c20aa2a07789a41941f9a1029faa30bf725fc7f6d515b1afe9",
@ -432,6 +440,12 @@
"index": "pypi",
"version": "==2.6.11"
},
"markupsafe": {
"hashes": [
"sha256:a6be69091dac236ea9c6bc7d012beab42010fa914c459791d627dad4910eb665"
],
"version": "==1.0"
},
"mf2py": {
"hashes": [
"sha256:9231bc1317dd5d01973b78a60e52ecd76dd84089c132540e799e4a62aeff3436",

74
lemonauth/jinja2/lemonauth/indie.html

@ -0,0 +1,74 @@
{% extends 'lemoncurry/layout.html' %}
{% block styles %}
<link rel="stylesheet" type="text/stylus" href="{{ static('lemonauth/css/indie.styl') }}">
{% endblock %}
{% block main %}
<div class="container">
<form class="card" method="post" action="{{ url('lemonauth:indie_approve') }}">
<h4 class="card-header h-x-app">
{% if app %}
<img class="u-logo p-name" src="{{ app.logo[0] }}" alt="{{ app.name[0] }}">
sign in to {{ app.name[0] }} (<a class="u-url code" href="{{ params.client_id }}">{{ params.client_id }}</a>)?
{% else %}
sign in to <a class="u-url p-name code" href="{{ params.client_id }}">{{ params.client_id }}</a>?
{% endif %}
{% if verified %}
<span data-tooltip data-tippy-theme="dark success" data-tippy-html="#verified-success">
<i class="fas fa-check-circle verified-success"></i>
</span>
{% else %}
<span data-tooltip data-tippy-theme="dark warning" data-tippy-html="#verified-warning">
<i class="fas fa-question-circle verified-warning"></i>
</span>
{% endif %}
</h4>
<div class="card-body">
<p class="card-text">do you want to confirm your identity, <a class="code" href="{{ me }}">{{ me }}</a>, with this app?</p>
{% if params.response_type == 'code' %}
<p class="card-text">additionally, this app is requesting the following <i>scopes</i> - you can edit the scopes that will be granted to the app, if you wish</p>
<div class="card-text form-group">
{% for scope in scopes %}
<div class="form-check">
<input class="form-check-input" id="scopes-{{ scope }}" name="scope" type="checkbox" checked value="{{ scope }}" />
<label class="form-check-label" for="scopes-{{ scope }}">{{ scope }}</label>
</div>
{% endfor %}
</div>
{% endif %}
<p class="card-text"><small>you will be redirected to <a class="code" href="{{ redirect_uri }}">{{ redirect_uri }}</a> after authorising this app</small></p>
</div>
<div class="card-footer">
<button class="btn btn-success" type="submit">
<i class="fas fa-check"></i>
approve
</button>
</div>
{{ csrf_input }}
<input type="hidden" name="me" value="{{ me }}">
<input type="hidden" name="client_id" value="{{ params.client_id }}">
<input type="hidden" name="redirect_uri" value="{{ redirect_uri }}">
{% if params.state %}
<input type="hidden" name="state" value="{{ params.state }}">
{% endif %}
<input type="hidden" name="response_type" value="{{ params.response_type }}">
</form>
</div>
<div id="verified-success" hidden>
this client has been <strong>verified</strong> using <code>{{ '<link rel="redirect_uri">' | escape }}</code> - they are who they claim to be!
</div>
<div id="verified-warning" hidden>
this client could <strong>not</strong> be verified using <code>{{ '<link rel="redirect_uri">' | escape }}</code> - check the redirect uri carefully yourself!
</div>
{% endblock %}
{% block foot %}
<script type="text/javascript">
tippy('[data-tippy-theme]', {arrow: true});
</script>
{% endblock %}

61
lemonauth/jinja2/lemonauth/login.html

@ -0,0 +1,61 @@
{% extends 'lemoncurry/layout.html' %}
{% block styles %}
<link rel="stylesheet" type="text/stylus" href="{{ static('lemonauth/css/login.styl') }}">
{% endblock %}
{% block main %}
<div class="container">
{% if form.errors %}
<p class="alert alert-danger">
<strong>uh oh!</strong> your login details didn't match, please try again
</p>
{% elif next %}
{% if request.user.is_authenticated %}
<p class="alert alert-warning">
<strong>hang on!</strong> your account doesn't have access to this page :( to proceed, please log in to an account that does have access!
</p>
{% else %}
<p class="alert alert-warning">
<strong>oops!</strong> please log in to see this page
</p>
{% endif %}
{% endif %}
<form class="card" method="post" action="{{ url('lemonauth:login') }}">
<div class="card-body">
<div class="form-group">
<label for="{{ form.username.id_for_label }}">username</label>
<input class="form-control" type="text" autocomplete="username" required id="{{ form.username.auto_id }}" name="{{ form.username.name }}" value="{{ form.username.value() or '' }}">
</div>
<div class="form-group">
<label for="{{ form.password.id_for_label }}">password</label>
<input class="form-control" type="password" autocomplete="current-password" required id="{{ form.password.auto_id }}" name="{{ form.password.name }}">
</div>
<div class="form-group">
<label for="{{ form.otp_token.id_for_label }}">otp token</label>
<input class="form-control" type="text" required id="{{ form.otp_token.auto_id }}" name="{{ form.otp_token.name }}">
</div>
<div class="form-group form-check">
<input class="form-check-input" type="checkbox" id="{{ form.otp_trust_agent.auto_id }}" name="{{ form.otp_trust_agent.name }}">
<label for="{{ form.otp_trust_agent.id_for_label }}" class="form-check-label">
remember this browser (don't tick this on a public computer!)
</label>
</div>
</div>
<div class="card-footer">
<button class="btn btn-primary" type="submit">
<i class="fas fa-sign-in-alt" aria-hidden="true"></i>
log in
</button>
</div>
{{ csrf_input }}
<input type="hidden" name="next" value="{{ next }}">
</form>
</div>
{% endblock %}

21
lemoncurry/jinja2.py

@ -0,0 +1,21 @@
from django.contrib.staticfiles.storage import staticfiles_storage
from django.urls import reverse
from jinja2 import Environment
from compressor.contrib.jinja2ext import CompressorExtension
from .utils import load_package_json
def environment(**options):
env = Environment(
extensions=[CompressorExtension],
trim_blocks=True,
lstrip_blocks=True,
**options
)
env.globals.update({
'package': load_package_json(),
'static': staticfiles_storage.url,
'url': reverse,
})
return env

67
lemoncurry/jinja2/lemoncurry/layout.html

@ -0,0 +1,67 @@
<!doctype html>
<html{% block html_attr %} dir="ltr" lang="en"{% endblock %}>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title class="p-name">{% if title %}{{ title }} ~ {% endif %}{{ request.site.name }}</title>
<link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css"
integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/monokai.min.css"
integrity="sha384-bHqbpRh/XW+phptvH9nQvMKHwPH1ZbOxpIeAB2D2OIEL4Ni7aZzZgMFpsRra+v1g" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="https://unpkg.com/openwebicons@1.4.3/css/openwebicons.min.css"
integrity="sha384-Ljk0G9f8GyEhAzrdHNkQc89A/Kpq+sy09gejdAPyMyTDnPe4aDfS/ppZ/rDGM0Y9" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="https://unpkg.com/tippy.js@2.5.2/dist/tippy.css"
integrity="sha384-JsezPuW/bNd38848K5/8rIEbB+23QGQ8faCF8xEmjFT3i1qujgGiewfYevzMO3J1" crossorigin="anonymous">
{% compress css %}
<link rel="stylesheet" type="text/stylus" href="{{ static('lemoncurry/css/layout.styl') }}">
{% block styles %}{% endblock %}
{% endcompress %}
<script type="text/javascript" defer src="https://use.fontawesome.com/releases/v5.0.13/js/all.js"
integrity="sha384-xymdQtn1n3lH2wcu0qhcdaOpQwyoarkgLVxC/wZ5q7h9gHtxICrpcaSUfygqZGOe" crossorigin="anonymous"></script>
</head>
<body{% block body_attr %}{% endblock %}>
<header>
<nav class="navbar navbar-expand-md navbar-dark">
<a class="navbar-brand" ref="home" href="{{ url('home:index') }}">{{ request.site.name }}</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar"
aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbar">
</div>
</nav>
</header>
<main>
{% block main %}
{% endblock %}
</main>
<footer>
<p>all content licensed under <a rel="license" href="https://creativecommons.org/licenses/by-sa/4.0/">cc by-sa 4.0</a></p>
<p>powered by <a rel="code-repository" href="{{ package.repository }}/tree/v{{ package.version }}">{{ package.name }} {{ package.version }}</a></p>
</footer>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" crossorigin="anonymous"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" crossorigin="anonymous"
integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" crossorigin="anonymous"
integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js" crossorigin="anonymous"
integrity="sha384-ZeLYJ2PNSQjvogWP559CDAf02Qb8FE5OyQicqtz/+UhZutbrwyr87Be7NPH/RgyC"></script>
<script src="https://unpkg.com/tippy.js@2.5.2/dist/tippy.standalone.min.js" crossorigin="anonymous"
integrity="sha384-VEMCz3fC5atUNN+ezSHq2AZIBciT3aWGEZsStnW58gtO9PYb3wenWsYNoxLTbi/M"></script>
{% compress js %}
<script type="text/javascript">
hljs.initHighlightingOnLoad();
</script>
{% block foot %}
{% endblock %}
{% endcompress %}
</body>
</html>

8
lemoncurry/settings/base.py

@ -124,9 +124,15 @@ ROOT_URLCONF = 'lemoncurry.urls'
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.jinja2.Jinja2',
'APP_DIRS': True,
'OPTIONS': {
'environment': 'lemoncurry.jinja2.environment',
},
},
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [

Loading…
Cancel
Save