hacking
|
|
@ -31,6 +31,7 @@
|
||||||
postInstall = oldAttrs.postInstall + ''
|
postInstall = oldAttrs.postInstall + ''
|
||||||
rm -r $out/${pkgs.python3.sitePackages}/froide_govplan/templates
|
rm -r $out/${pkgs.python3.sitePackages}/froide_govplan/templates
|
||||||
ln -sf /var/lib/froide-govplan/templates $out/${pkgs.python3.sitePackages}/froide_govplan/templates
|
ln -sf /var/lib/froide-govplan/templates $out/${pkgs.python3.sitePackages}/froide_govplan/templates
|
||||||
|
cp -r froide_govplan/static $out/${pkgs.python3.sitePackages}/froide_govplan/
|
||||||
'';
|
'';
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
@ -45,8 +46,13 @@
|
||||||
cores = 4;
|
cores = 4;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
disabledModules = [ "services/web-apps/froide-govplan.nix" ];
|
||||||
|
|
||||||
|
imports = [ ./froide-govplan.nix ];
|
||||||
|
|
||||||
services.froide-govplan = {
|
services.froide-govplan = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
package = pkgs.froide-govplan;
|
||||||
settings = {
|
settings = {
|
||||||
DEBUG = lib.mkForce true;
|
DEBUG = lib.mkForce true;
|
||||||
CSRF_TRUSTED_ORIGINS = [ "http://localhost:8080" ];
|
CSRF_TRUSTED_ORIGINS = [ "http://localhost:8080" ];
|
||||||
|
|
|
||||||
242
froide-govplan.nix
Normal file
|
|
@ -0,0 +1,242 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.services.froide-govplan;
|
||||||
|
pythonFmt = pkgs.formats.pythonVars { };
|
||||||
|
settingsFile = pythonFmt.generate "extra_settings.py" cfg.settings;
|
||||||
|
|
||||||
|
pkg = cfg.package.overridePythonAttrs (old: {
|
||||||
|
src = ./.;
|
||||||
|
postInstall =
|
||||||
|
old.postInstall
|
||||||
|
+ ''
|
||||||
|
ln -s ${settingsFile} $out/${pkg.python.sitePackages}/froide_govplan/project/extra_settings.py
|
||||||
|
|
||||||
|
rm -r $out/${pkgs.python3.sitePackages}/froide_govplan/templates
|
||||||
|
ln -sf /var/lib/froide-govplan/templates $out/${pkgs.python3.sitePackages}/froide_govplan/templates
|
||||||
|
cp -r froide_govplan/static $out/${pkgs.python3.sitePackages}/froide_govplan/
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
|
||||||
|
froide-govplan = pkgs.writeShellApplication {
|
||||||
|
name = "froide-govplan";
|
||||||
|
runtimeInputs = [ pkgs.coreutils ];
|
||||||
|
text = ''
|
||||||
|
SUDO="exec"
|
||||||
|
if [[ "$USER" != govplan ]]; then
|
||||||
|
SUDO="exec /run/wrappers/bin/sudo -u govplan"
|
||||||
|
fi
|
||||||
|
$SUDO env ${lib.getExe pkg} "$@"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Service hardening
|
||||||
|
defaultServiceConfig = {
|
||||||
|
# Secure the services
|
||||||
|
ReadWritePaths = [ cfg.dataDir ];
|
||||||
|
CacheDirectory = "froide-govplan";
|
||||||
|
CapabilityBoundingSet = "";
|
||||||
|
# ProtectClock adds DeviceAllow=char-rtc r
|
||||||
|
DeviceAllow = "";
|
||||||
|
LockPersonality = true;
|
||||||
|
MemoryDenyWriteExecute = true;
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
PrivateDevices = true;
|
||||||
|
PrivateMounts = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
PrivateUsers = true;
|
||||||
|
ProtectClock = true;
|
||||||
|
ProtectHome = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectProc = "invisible";
|
||||||
|
ProcSubset = "pid";
|
||||||
|
RestrictAddressFamilies = [
|
||||||
|
"AF_UNIX"
|
||||||
|
"AF_INET"
|
||||||
|
"AF_INET6"
|
||||||
|
];
|
||||||
|
RestrictNamespaces = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
SystemCallArchitectures = "native";
|
||||||
|
SystemCallFilter = [
|
||||||
|
"@system-service"
|
||||||
|
"~@privileged @setuid @keyring"
|
||||||
|
];
|
||||||
|
UMask = "0066";
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.froide-govplan = {
|
||||||
|
|
||||||
|
enable = lib.mkEnableOption "Gouvernment planer web app Govplan";
|
||||||
|
|
||||||
|
package = lib.mkPackageOption pkgs "froide-govplan" { };
|
||||||
|
|
||||||
|
hostName = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "localhost";
|
||||||
|
description = "FQDN for the froide-govplan instance.";
|
||||||
|
};
|
||||||
|
|
||||||
|
dataDir = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "/var/lib/froide-govplan";
|
||||||
|
description = "Directory to store the Froide-Govplan server data.";
|
||||||
|
};
|
||||||
|
|
||||||
|
secretKeyFile = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.path;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Path to a file containing the secret key.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Configuration options to set in `extra_settings.py`.
|
||||||
|
'';
|
||||||
|
|
||||||
|
default = { };
|
||||||
|
|
||||||
|
type = lib.types.submodule {
|
||||||
|
freeformType = pythonFmt.type;
|
||||||
|
|
||||||
|
options = {
|
||||||
|
ALLOWED_HOSTS = lib.mkOption {
|
||||||
|
type = with lib.types; listOf str;
|
||||||
|
default = [ "*" ];
|
||||||
|
description = ''
|
||||||
|
A list of valid fully-qualified domain names (FQDNs) and/or IP
|
||||||
|
addresses that can be used to reach the Froide-Govplan service.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
|
||||||
|
services.froide-govplan = {
|
||||||
|
settings = {
|
||||||
|
STATIC_ROOT = "${cfg.dataDir}/static";
|
||||||
|
DEBUG = false;
|
||||||
|
DATABASES.default = {
|
||||||
|
ENGINE = "django.contrib.gis.db.backends.postgis";
|
||||||
|
NAME = "govplan";
|
||||||
|
USER = "govplan";
|
||||||
|
HOST = "/run/postgresql";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.postgresql = {
|
||||||
|
enable = true;
|
||||||
|
ensureDatabases = [ "govplan" ];
|
||||||
|
ensureUsers = [
|
||||||
|
{
|
||||||
|
name = "govplan";
|
||||||
|
ensureDBOwnership = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
extensions = ps: with ps; [ postgis ];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
enable = lib.mkDefault true;
|
||||||
|
virtualHosts."${cfg.hostName}".locations = {
|
||||||
|
"/".extraConfig = "proxy_pass http://unix:/run/froide-govplan/froide-govplan.socket;";
|
||||||
|
"/static/".alias = "${cfg.dataDir}/static/";
|
||||||
|
};
|
||||||
|
proxyTimeout = lib.mkDefault "120s";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd = {
|
||||||
|
services = {
|
||||||
|
|
||||||
|
postgresql.serviceConfig.ExecStartPost =
|
||||||
|
let
|
||||||
|
sqlFile = pkgs.writeText "immich-pgvectors-setup.sql" ''
|
||||||
|
CREATE EXTENSION IF NOT EXISTS postgis;
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
[
|
||||||
|
''
|
||||||
|
${lib.getExe' config.services.postgresql.package "psql"} -d govplan -f "${sqlFile}"
|
||||||
|
''
|
||||||
|
];
|
||||||
|
|
||||||
|
froide-govplan = {
|
||||||
|
description = "Gouvernment planer Govplan";
|
||||||
|
serviceConfig = defaultServiceConfig // {
|
||||||
|
WorkingDirectory = cfg.dataDir;
|
||||||
|
StateDirectory = lib.mkIf (cfg.dataDir == "/var/lib/froide-govplan") "froide-govplan";
|
||||||
|
User = "govplan";
|
||||||
|
Group = "govplan";
|
||||||
|
};
|
||||||
|
after = [
|
||||||
|
"postgresql.service"
|
||||||
|
"network.target"
|
||||||
|
"systemd-tmpfiles-setup.service"
|
||||||
|
];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
environment =
|
||||||
|
{
|
||||||
|
PYTHONPATH = pkg.pythonPath;
|
||||||
|
GDAL_LIBRARY_PATH = "${pkgs.gdal}/lib/libgdal.so";
|
||||||
|
GEOS_LIBRARY_PATH = "${pkgs.geos}/lib/libgeos_c.so";
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs (cfg.secretKeyFile != null) {
|
||||||
|
SECRET_KEY_FILE = cfg.secretKeyFile;
|
||||||
|
};
|
||||||
|
preStart = ''
|
||||||
|
# Auto-migrate on first run or if the package has changed
|
||||||
|
versionFile="${cfg.dataDir}/src-version"
|
||||||
|
version=$(cat "$versionFile" 2>/dev/null || echo 0)
|
||||||
|
|
||||||
|
if [[ $version != ${pkg.version} ]]; then
|
||||||
|
${lib.getExe pkg} migrate --no-input
|
||||||
|
${lib.getExe pkg} collectstatic --no-input --clear
|
||||||
|
echo ${pkg.version} > "$versionFile"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
script = ''
|
||||||
|
${pkg.python.pkgs.uvicorn}/bin/uvicorn --uds /run/froide-govplan/froide-govplan.socket \
|
||||||
|
--app-dir ${pkg}/${pkg.python.sitePackages}/froide_govplan \
|
||||||
|
project.asgi:application
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = [ "d /run/froide-govplan - govplan govplan - -" ];
|
||||||
|
|
||||||
|
environment.systemPackages = [ froide-govplan ];
|
||||||
|
|
||||||
|
users.users.govplan = {
|
||||||
|
home = "${cfg.dataDir}";
|
||||||
|
isSystemUser = true;
|
||||||
|
group = "govplan";
|
||||||
|
};
|
||||||
|
users.groups.govplan = { };
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
meta.maintainers = with lib.maintainers; [ onny ];
|
||||||
|
|
||||||
|
}
|
||||||
6
froide_govplan/static/froide_govplan/css/bootstrap.min.css
vendored
Normal file
8
froide_govplan/static/froide_govplan/css/docsearch.css
Normal file
5
froide_govplan/static/froide_govplan/css/font-awesome.css
vendored
Normal file
BIN
froide_govplan/static/froide_govplan/images/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
froide_govplan/static/froide_govplan/images/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
froide_govplan/static/froide_govplan/images/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
froide_govplan/static/froide_govplan/images/favicon.png
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
BIN
froide_govplan/static/froide_govplan/images/g3.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 403 KiB After Width: | Height: | Size: 403 KiB |
32
froide_govplan/static/froide_govplan/images/logo.svg
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||||
|
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||||
|
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="640.000000pt" height="640.000000pt" viewBox="0 0 640.000000 640.000000"
|
||||||
|
preserveAspectRatio="xMidYMid meet">
|
||||||
|
<metadata>
|
||||||
|
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
||||||
|
</metadata>
|
||||||
|
<g transform="translate(0.000000,640.000000) scale(0.100000,-0.100000)"
|
||||||
|
fill="#000000" stroke="none">
|
||||||
|
<path d="M990 5042 c0 -10 668 -1325 1170 -2302 103 -201 249 -486 325 -635
|
||||||
|
76 -148 192 -377 259 -507 l121 -238 132 0 132 0 44 83 c25 45 109 208 187
|
||||||
|
362 78 154 176 344 216 421 41 78 74 144 74 146 0 3 -60 8 -132 11 -140 5
|
||||||
|
-238 28 -371 83 -327 137 -587 446 -678 805 -27 108 -37 337 -19 447 16 98 53
|
||||||
|
227 84 292 l25 51 -247 489 -247 489 -538 3 c-295 2 -537 2 -537 0z"/>
|
||||||
|
<path d="M3850 4880 c-44 -88 -80 -162 -80 -165 0 -3 15 -5 33 -5 117 0 387
|
||||||
|
-109 517 -209 66 -50 205 -189 251 -250 l26 -35 210 412 210 412 -544 0 -543
|
||||||
|
0 -80 -160z"/>
|
||||||
|
<path d="M3431 4609 c-74 -13 -218 -62 -293 -100 -273 -138 -477 -392 -557
|
||||||
|
-692 -149 -557 191 -1143 755 -1304 92 -26 112 -28 274 -28 161 0 183 3 275
|
||||||
|
29 100 28 241 88 293 124 l27 20 92 -87 c91 -86 92 -88 81 -117 -6 -17 -8 -43
|
||||||
|
-4 -59 11 -42 724 -757 783 -785 62 -29 136 -27 202 6 101 51 148 159 117 268
|
||||||
|
-16 53 -31 72 -210 259 -304 316 -528 535 -557 542 -15 4 -40 5 -55 3 -23 -2
|
||||||
|
-35 4 -58 32 -16 19 -56 63 -89 96 l-59 62 45 63 c243 344 254 817 26 1187
|
||||||
|
-99 161 -283 324 -457 404 -141 64 -222 81 -407 84 -93 1 -194 -2 -224 -7z
|
||||||
|
m397 -325 c251 -72 427 -242 515 -498 28 -84 31 -102 31 -226 1 -157 -13 -221
|
||||||
|
-74 -345 -48 -96 -107 -170 -198 -247 -144 -123 -292 -177 -488 -178 -208 0
|
||||||
|
-389 75 -539 225 -151 151 -220 321 -219 535 1 126 17 203 64 306 88 194 271
|
||||||
|
359 475 429 111 38 297 37 433 -1z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.8 KiB |
7
froide_govplan/static/froide_govplan/js/bootstrap.bundle.min.js
vendored
Normal file
80
froide_govplan/static/froide_govplan/js/color-modes.js
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*!
|
||||||
|
* Color mode toggler for Bootstrap's docs (https://getbootstrap.com/)
|
||||||
|
* Copyright 2011-2025 The Bootstrap Authors
|
||||||
|
* Licensed under the Creative Commons Attribution 3.0 Unported License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(() => {
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const getStoredTheme = () => localStorage.getItem('theme')
|
||||||
|
const setStoredTheme = theme => localStorage.setItem('theme', theme)
|
||||||
|
|
||||||
|
const getPreferredTheme = () => {
|
||||||
|
const storedTheme = getStoredTheme()
|
||||||
|
if (storedTheme) {
|
||||||
|
return storedTheme
|
||||||
|
}
|
||||||
|
|
||||||
|
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
||||||
|
}
|
||||||
|
|
||||||
|
const setTheme = theme => {
|
||||||
|
if (theme === 'auto') {
|
||||||
|
document.documentElement.setAttribute('data-bs-theme', (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'))
|
||||||
|
} else {
|
||||||
|
document.documentElement.setAttribute('data-bs-theme', theme)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTheme(getPreferredTheme())
|
||||||
|
|
||||||
|
const showActiveTheme = (theme, focus = false) => {
|
||||||
|
const themeSwitcher = document.querySelector('#bd-theme')
|
||||||
|
|
||||||
|
if (!themeSwitcher) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const themeSwitcherText = document.querySelector('#bd-theme-text')
|
||||||
|
const activeThemeIcon = document.querySelector('.theme-icon-active use')
|
||||||
|
const btnToActive = document.querySelector(`[data-bs-theme-value="${theme}"]`)
|
||||||
|
const svgOfActiveBtn = btnToActive.querySelector('svg use').getAttribute('href')
|
||||||
|
|
||||||
|
document.querySelectorAll('[data-bs-theme-value]').forEach(element => {
|
||||||
|
element.classList.remove('active')
|
||||||
|
element.setAttribute('aria-pressed', 'false')
|
||||||
|
})
|
||||||
|
|
||||||
|
btnToActive.classList.add('active')
|
||||||
|
btnToActive.setAttribute('aria-pressed', 'true')
|
||||||
|
activeThemeIcon.setAttribute('href', svgOfActiveBtn)
|
||||||
|
const themeSwitcherLabel = `${themeSwitcherText.textContent} (${btnToActive.dataset.bsThemeValue})`
|
||||||
|
themeSwitcher.setAttribute('aria-label', themeSwitcherLabel)
|
||||||
|
|
||||||
|
if (focus) {
|
||||||
|
themeSwitcher.focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
|
||||||
|
const storedTheme = getStoredTheme()
|
||||||
|
if (storedTheme !== 'light' && storedTheme !== 'dark') {
|
||||||
|
setTheme(getPreferredTheme())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
window.addEventListener('DOMContentLoaded', () => {
|
||||||
|
showActiveTheme(getPreferredTheme())
|
||||||
|
|
||||||
|
document.querySelectorAll('[data-bs-theme-value]')
|
||||||
|
.forEach(toggle => {
|
||||||
|
toggle.addEventListener('click', () => {
|
||||||
|
const theme = toggle.getAttribute('data-bs-theme-value')
|
||||||
|
setStoredTheme(theme)
|
||||||
|
setTheme(theme)
|
||||||
|
showActiveTheme(theme, true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})()
|
||||||
2
froide_govplan/static/froide_govplan/js/jquery-3.6.4.min.js
vendored
Normal file
|
Before Width: | Height: | Size: 134 KiB |
|
|
@ -7,30 +7,32 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<title>{% block title %}{% page_attribute "page_title" %} - {{ SITE_NAME }}{% endblock %}</title>
|
<title>{% block title %}{% page_attribute "page_title" %} - {{ SITE_NAME }}{% endblock %}</title>
|
||||||
|
|
||||||
<script src="https://getbootstrap.com/docs/5.3/assets/js/color-modes.js"></script>
|
<script src="{% static 'froide_govplan/js/color-modes.js' %}"></script>
|
||||||
|
|
||||||
<meta name="description" content="">
|
<meta name="description" content="">
|
||||||
<meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
|
<meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
|
||||||
<meta name="generator" content="Hugo 0.122.0">
|
<meta name="generator" content="Hugo 0.122.0">
|
||||||
|
|
||||||
<link rel="canonical" href="https://getbootstrap.com/docs/5.3/examples/starter-template/">
|
<link rel="canonical" href="https://getbootstrap.com/docs/5.3/examples/starter-template/">
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@docsearch/css@3">
|
<link rel="stylesheet" href="{% static 'froide_govplan/css/docsearch.css' %}">
|
||||||
|
|
||||||
<!-- Favicons -->
|
<!-- Favicons -->
|
||||||
<link rel="apple-touch-icon" href="https://getbootstrap.com/docs/5.3/assets/img/favicons/apple-touch-icon.png" sizes="180x180">
|
<link rel="apple-touch-icon" href="{% static 'froide_govplan/images/apple-touch-icon.png' %}" sizes="180x180">
|
||||||
<link rel="icon" href="https://getbootstrap.com/docs/5.3/assets/img/favicons/favicon-32x32.png" sizes="32x32" type="image/png">
|
<link rel="icon" href="{% static 'froide_govplan/images/favicon-32x32.png' %}" sizes="32x32" type="image/png">
|
||||||
<link rel="icon" href="https://getbootstrap.com/docs/5.3/assets/img/favicons/favicon-16x16.png" sizes="16x16" type="image/png">
|
<link rel="icon" href="{% static 'froide_govplan/images/favicon-16x16.png' %}" sizes="16x16" type="image/png">
|
||||||
<link rel="manifest" href="https://getbootstrap.com/docs/5.3/assets/img/favicons/manifest.json">
|
<link rel="manifest" href="https://getbootstrap.com/docs/5.3/assets/img/favicons/manifest.json">
|
||||||
<link rel="mask-icon" href="https://getbootstrap.com/docs/5.3/assets/img/favicons/safari-pinned-tab.svg" color="#712cf9">
|
<link rel="mask-icon" href="https://getbootstrap.com/docs/5.3/assets/img/favicons/safari-pinned-tab.svg" color="#712cf9">
|
||||||
<link rel="icon" href="https://getbootstrap.com/docs/5.3/assets/img/favicons/favicon.ico">
|
<link rel="icon" href="https://getbootstrap.com/docs/5.3/assets/img/favicons/favicon.ico">
|
||||||
<meta name="theme-color" content="#712cf9">
|
<meta name="theme-color" content="#712cf9">
|
||||||
|
|
||||||
|
|
||||||
|
<script defer data-domain="verwaltungstracker.de" src="https://analytics.project-insanity.org/js/script.js"></script>
|
||||||
|
|
||||||
{% block header_font %}{% endblock %}
|
{% block header_font %}{% endblock %}
|
||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
|
<link href="{% static 'froide_govplan/css/bootstrap.min.css' %}" rel="stylesheet" crossorigin="anonymous">
|
||||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet">
|
<link href="{% static 'froide_govplan/css/font-awesome.css' %}" rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
.bd-placeholder-img {
|
.bd-placeholder-img {
|
||||||
font-size: 1.125rem;
|
font-size: 1.125rem;
|
||||||
|
|
@ -139,9 +141,8 @@
|
||||||
{% block extra_footer %}{% endblock %}
|
{% block extra_footer %}{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
|
<script src="{% static 'froide_govplan/js/bootstrap.bundle.min.js' %}" crossorigin="anonymous"></script>
|
||||||
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
|
<script src="{% static 'froide_govplan/js/jquery-3.6.4.min.js' %}"></script>
|
||||||
<script defer data-domain="verwaltungstracker.de" src="https://analytics.project-insanity.org/js/script.js"></script>
|
|
||||||
<script lang="javascript">
|
<script lang="javascript">
|
||||||
const Ze = t => {
|
const Ze = t => {
|
||||||
const e = t.dataset.confirm;
|
const e = t.dataset.confirm;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
{% load cms_tags %}
|
{% load cms_tags %}
|
||||||
{% load djangocms_alias_tags %}
|
{% load djangocms_alias_tags %}
|
||||||
{% load menu_tags %}
|
{% load menu_tags %}
|
||||||
|
{% load static %}
|
||||||
{% block body %}
|
{% block body %}
|
||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
|
<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
|
||||||
|
|
@ -81,9 +82,10 @@
|
||||||
<div class="col-lg-10 mx-auto p-4 py-md-5">
|
<div class="col-lg-10 mx-auto p-4 py-md-5">
|
||||||
<header class="d-flex align-items-center pb-3 mb-5 border-bottom">
|
<header class="d-flex align-items-center pb-3 mb-5 border-bottom">
|
||||||
<a href="/" class="d-flex align-items-center text-body-emphasis text-decoration-none text-reset">
|
<a href="/" class="d-flex align-items-center text-body-emphasis text-decoration-none text-reset">
|
||||||
<svg class="bi me-2" width="40" height="32">
|
<!-- <svg class="bi me-2" width="40" height="32">
|
||||||
<use xlink:href="#bootstrap" />
|
<use xlink:href="#bootstrap" />
|
||||||
</svg>
|
</svg> -->
|
||||||
|
<img src="{% static 'froide_govplan/images/apple-touch-icon.png' %}" class="bi me-2" height="32">
|
||||||
<span class="fs-4">VerwaltungsTracker</span>
|
<span class="fs-4">VerwaltungsTracker</span>
|
||||||
</a>
|
</a>
|
||||||
</header>
|
</header>
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,10 @@ USE_TZ = True
|
||||||
|
|
||||||
STATIC_URL = "static/"
|
STATIC_URL = "static/"
|
||||||
|
|
||||||
|
STATICFILES_DIRS = [
|
||||||
|
BASE_DIR / "static",
|
||||||
|
]
|
||||||
|
|
||||||
# Default primary key field type
|
# Default primary key field type
|
||||||
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
|
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
|
||||||
|
|
||||||
|
|
|
||||||