Add views
This commit is contained in:
parent
167f1d3366
commit
9c77a1b4a8
14
views/about.njk
Normal file
14
views/about.njk
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{% extends 'layouts/base.njk' %}
|
||||||
|
|
||||||
|
{% set title = 'Example App - About us' %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<h1>Very interesting</h1>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<section class="panel">
|
||||||
|
<h2>This is us</h2>
|
||||||
|
<p class="center">And we like wms!</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
2
views/errors/400.njk
Normal file
2
views/errors/400.njk
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{% extends './error.njk' %}
|
||||||
|
{% import 'macros.njk' as macros %}
|
2
views/errors/401.njk
Normal file
2
views/errors/401.njk
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{% extends './error.njk' %}
|
||||||
|
{% import 'macros.njk' as macros %}
|
2
views/errors/403.njk
Normal file
2
views/errors/403.njk
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{% extends './error.njk' %}
|
||||||
|
{% import 'macros.njk' as macros %}
|
2
views/errors/404.njk
Normal file
2
views/errors/404.njk
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{% extends './error.njk' %}
|
||||||
|
{% import 'macros.njk' as macros %}
|
2
views/errors/500.njk
Normal file
2
views/errors/500.njk
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{% extends './error.njk' %}
|
||||||
|
{% import 'macros.njk' as macros %}
|
2
views/errors/503.njk
Normal file
2
views/errors/503.njk
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{% extends './error.njk' %}
|
||||||
|
{% import 'macros.njk' as macros %}
|
36
views/errors/error.njk
Normal file
36
views/errors/error.njk
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
{% extends '../layouts/barebone.njk' %}
|
||||||
|
|
||||||
|
{% set title = error_code + ' - ' + error_message %}
|
||||||
|
|
||||||
|
{% block _stylesheets %}
|
||||||
|
<link rel="stylesheet" href="/css/error.css">
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block _body %}
|
||||||
|
<div class="logo"><a href="/">Example app</a></div>
|
||||||
|
|
||||||
|
<main class="{% block class %}{% endblock %}">
|
||||||
|
{% if flash %}
|
||||||
|
{{ macros.messages(flash) }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="error-code">{{ error_code }}</div>
|
||||||
|
<div class="error-message">{{ error_message }}</div>
|
||||||
|
<div class="error-instructions">{{ error_instructions|safe }}</div>
|
||||||
|
|
||||||
|
<nav>
|
||||||
|
{% if session.previousUrl and session.previousUrl != '/' and session.previousUrl != url %}
|
||||||
|
<a href="{{ session.previousUrl }}" class="button"><i data-feather="arrow-left"></i> Go back</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<a href="/" class="button"><i data-feather="home"></i> Go to homepage</a>
|
||||||
|
</nav>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<div class="contact">
|
||||||
|
Error ID: {{ error_id }}
|
||||||
|
<br>
|
||||||
|
If you think this isn't right, please contact us with the above error ID at
|
||||||
|
<a href="mailto:contact@example.net">contact@example.net</a>.
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
7
views/home.njk
Normal file
7
views/home.njk
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{% extends 'layouts/base.njk' %}
|
||||||
|
|
||||||
|
{% set title = 'Example App - Hello world!' %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<h1>Hello world!</h1>
|
||||||
|
{% endblock %}
|
35
views/layouts/barebone.njk
Normal file
35
views/layouts/barebone.njk
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>{{ title }}</title>
|
||||||
|
|
||||||
|
<link rel="shortcut icon" type="image/png" href="/img/logox1024.png">
|
||||||
|
<link rel="shortcut icon" type="image/png" href="/img/logox128.png">
|
||||||
|
<link rel="shortcut icon" type="image/svg" href="/img/logo.svg">
|
||||||
|
|
||||||
|
{% if description %}
|
||||||
|
<meta name="description" content="{{ description }}">
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if refresh_after %}
|
||||||
|
<meta http-equiv="refresh" content="{{ refresh_after }}">
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% block _stylesheets %}{% endblock %}
|
||||||
|
{% block _scripts %}
|
||||||
|
<script src="/js/app.js" defer></script>
|
||||||
|
{% endblock %}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<header>
|
||||||
|
{% block header %}{% endblock %}
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{% block _body %}{% endblock %}
|
||||||
|
|
||||||
|
<footer>{% block footer %}{% endblock %}</footer>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
40
views/layouts/base.njk
Normal file
40
views/layouts/base.njk
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{% extends './barebone.njk' %}
|
||||||
|
{% import 'macros.njk' as macros %}
|
||||||
|
|
||||||
|
{% block _stylesheets %}
|
||||||
|
{{ super() }}
|
||||||
|
<link rel="stylesheet" href="/css/app.css">
|
||||||
|
{% block stylesheets %}{% endblock %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block _scripts %}
|
||||||
|
{{ super() }}
|
||||||
|
{% block scripts %}{% endblock %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block header %}
|
||||||
|
<a href="/" class="logo"><img src="/img/logo.svg" alt="Logo"> Example app</a>
|
||||||
|
<nav>
|
||||||
|
<ul>
|
||||||
|
<li><a href="{{ route('about') }}"><i data-feather="info"></i> About</a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block _body %}
|
||||||
|
<div class="container">
|
||||||
|
{{ macros.messages(flash) }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
{% if h1 %}
|
||||||
|
<h1>{{ h1 }}</h1>
|
||||||
|
{% endif %}
|
||||||
|
{% if subtitle %}
|
||||||
|
<p>{{ subtitle }}</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% block body %}{% endblock %}
|
||||||
|
</main>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block footer %}Example app v{{ app_version }} - all rights reserved.{% endblock %}
|
136
views/macros.njk
Normal file
136
views/macros.njk
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
{% macro message(type, content, raw=false, discreet=false) %}
|
||||||
|
<div class="message{{ ' message-discreet' if discreet }}" data-type="{{ type }}">
|
||||||
|
<i class="icon"></i>
|
||||||
|
<span class="content">
|
||||||
|
{{ content|safe if raw else content }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro messages(flash) %}
|
||||||
|
{% set flashed = flash() %}
|
||||||
|
{% set display = 0 %}
|
||||||
|
|
||||||
|
{% for type, bag in flashed %}
|
||||||
|
{% if bag|length %}
|
||||||
|
{% set display = 1 %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% if display %}
|
||||||
|
<div class="messages">
|
||||||
|
{% for type, bag in flashed %}
|
||||||
|
{% for content in bag %}
|
||||||
|
{{ message(type, content) }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro csrf(getCSRFToken) %}
|
||||||
|
<input type="hidden" name="csrf" value="{{ getCSRFToken() }}">
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro field(_locals, type, name, value, placeholder, hint, validation_attributes='', extraData='') %}
|
||||||
|
{% set validation = _locals.validation() %}
|
||||||
|
{% set validation = validation[name] if validation[name] or null %}
|
||||||
|
{% set previousFormData = _locals.previousFormData() %}
|
||||||
|
{% set value = previousFormData[name] or value or validation.value or '' %}
|
||||||
|
|
||||||
|
{% if type == 'hidden' %}
|
||||||
|
{% if validation %}
|
||||||
|
{{ message('error', validation.message) }}
|
||||||
|
{% endif %}
|
||||||
|
<input type="hidden" name="{{ name }}" value="{{ value }}">
|
||||||
|
{% else %}
|
||||||
|
<div class="form-field{{ ' inline' if type == 'checkbox' }}">
|
||||||
|
{% if type == 'duration' %}
|
||||||
|
<div class="input-group">
|
||||||
|
{% for f in extraData %}
|
||||||
|
<div class="time-input">
|
||||||
|
{% if previousFormData[name] %}
|
||||||
|
{% set v = value[f] %}
|
||||||
|
{% else %}
|
||||||
|
{% set v = (value % 60) if f == 's' else (((value - value % 60) / 60 % 60) if f == 'm' else ((value - value % 3600) / 3600 if f == 'h')) %}
|
||||||
|
{% endif %}
|
||||||
|
<input type="number" name="{{ name }}[{{ f }}]" id="field-{{ name }}-{{ f }}"
|
||||||
|
value="{{ v }}"
|
||||||
|
min="0" {{ 'max=60' if (f == 's' or f == 'm') }}
|
||||||
|
{{ validation_attributes }}>
|
||||||
|
<label for="field-{{ name }}-{{ f }}">{{ f }}</label>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% elseif type == 'select' %}
|
||||||
|
<select name="{{ name }}" id="field-{{ name }}">
|
||||||
|
{% for option in extraData %}
|
||||||
|
<option value="{{ option }}" {{ 'selected' if value == option }}>{{ option }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<i data-feather="chevron-down"></i>
|
||||||
|
{% else %}
|
||||||
|
<input type="{{ type }}" name="{{ name }}" id="field-{{ name }}"
|
||||||
|
{% if type != 'checkbox' %} value="{{ value }}" {% endif %}
|
||||||
|
{{ 'checked' if (type == 'checkbox' and value == 'on') }}
|
||||||
|
{{ validation_attributes|safe }}>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<label for="field-{{ name }}{{ '-' + extraData[0] if type == 'duration' }}">{{ placeholder }}</label>
|
||||||
|
{% if validation %}
|
||||||
|
<div class="error"><i data-feather="x-circle"></i> {{ validation.message }}</div>
|
||||||
|
{% endif %}
|
||||||
|
{% if hint %}
|
||||||
|
<div class="hint"><i data-feather="info"></i> {{ hint }}</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro websocket(websocketUrl, listener, reconnectOnClose = 1, checkFunction = 0) %}
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
{% if checkFunction %}
|
||||||
|
if (!{{ checkFunction }}()) return;
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
const run = () => {
|
||||||
|
const websocket = new WebSocket('{{ websocketUrl }}');
|
||||||
|
websocket.onopen = (e) => {
|
||||||
|
console.debug('Websocket connected');
|
||||||
|
};
|
||||||
|
websocket.onmessage = (e) => {
|
||||||
|
{{ listener }}(websocket, e);
|
||||||
|
};
|
||||||
|
websocket.onerror = (e) => {
|
||||||
|
console.error('Websocket error', e);
|
||||||
|
};
|
||||||
|
websocket.onclose = (e) => {
|
||||||
|
console.debug('Websocket closed', e.code, e.reason);
|
||||||
|
|
||||||
|
{% if reconnectOnClose %}
|
||||||
|
setTimeout(run, 1000);
|
||||||
|
{% endif %}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
run();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro paginate(pagination, routeName) %}
|
||||||
|
{% if pagination.hasPrevious() or pagination.hasNext() %}
|
||||||
|
<div class="pagination">
|
||||||
|
{% if pagination.hasPrevious() %}
|
||||||
|
<a href="{{ route(routeName, {page: pagination.page - 1}) }}"><i data-feather="chevron-left"></i></a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<span>{{ pagination.page }}</span>
|
||||||
|
|
||||||
|
{% if pagination.hasNext() %}
|
||||||
|
<a href="{{ route(routeName, {page: pagination.page + 1}) }}"><i data-feather="chevron-right"></i></a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
Loading…
Reference in New Issue
Block a user