add SEO
This commit is contained in:
parent
b5ed14b767
commit
ef20108403
9 changed files with 104 additions and 16 deletions
3
Makefile
3
Makefile
|
|
@ -7,3 +7,6 @@ build:
|
||||||
install:
|
install:
|
||||||
mkdir -p $(DESTDIR)
|
mkdir -p $(DESTDIR)
|
||||||
cp -r assets $(DESTDIR)/
|
cp -r assets $(DESTDIR)/
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf assets
|
||||||
48
README.md
48
README.md
|
|
@ -53,9 +53,6 @@ Füge dies zu deiner `configuration.nix` hinzu:
|
||||||
```nix
|
```nix
|
||||||
services.fragify = {
|
services.fragify = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
|
||||||
# Konfiguration hier
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -84,13 +81,46 @@ nix run
|
||||||
- **API**: Integration mit der FragDenStaat.de API
|
- **API**: Integration mit der FragDenStaat.de API
|
||||||
- **Styling**: Responsive Design mit Gradient-Hintergrund
|
- **Styling**: Responsive Design mit Gradient-Hintergrund
|
||||||
|
|
||||||
## API-Integration
|
## Frontend-Assets (lokal statt CDN)
|
||||||
|
|
||||||
Fragify nutzt die offizielle [FragDenStaat.de API](https://fragdenstaat.de/api/) um:
|
Die Anwendung kann CSS/JS-Assets lokal bereitstellen. Dafür werden `npm` und `gulp` benutzt.
|
||||||
|
|
||||||
- Behörden zu durchsuchen
|
### Bauen der Assets
|
||||||
- Links zu generieren, die das Anfrage-Formular vorausfüllen
|
|
||||||
- Die korrekte URL-Struktur von FragDenStaat.de zu verwenden
|
```bash
|
||||||
|
# Abhängigkeiten installieren (nutzt npm ci, wenn package-lock.json existiert)
|
||||||
|
make build
|
||||||
|
# Alternativ ohne make
|
||||||
|
npm install
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
Die gebauten Dateien landen in `assets/` und werden vom Server unter `/static/...` ausgeliefert:
|
||||||
|
|
||||||
|
- CSS: `/static/css/bootstrap.min.css`, `/static/css/select2.min.css`, `/static/css/select2-bootstrap-5-theme.min.css`
|
||||||
|
- JS: `/static/js/bootstrap.bundle.min.js`, `/static/js/jquery.min.js`, `/static/js/select2.min.js`
|
||||||
|
|
||||||
|
### Hinweis
|
||||||
|
- Stelle sicher, dass `assets/` existiert, sonst werden stattdessen CDN-Links erwartet.
|
||||||
|
- In der Entwicklungs-Serverausgabe steht: "Serving static assets from: ..." – dort solltest du den Pfad zu `assets/` sehen.
|
||||||
|
|
||||||
|
## Deployment mit Nix/uWSGI
|
||||||
|
|
||||||
|
- Das Nix-Paket installiert Templates und (falls vorhanden) `assets/` nach `$out/share/fragify/...`.
|
||||||
|
- Das NixOS-Modul startet uWSGI und erzeugt einen UNIX-Socket unter `unix:${config.services.uwsgi.runDir}/fragify.sock`.
|
||||||
|
- Die App respektiert folgende Umgebungsvariablen:
|
||||||
|
- `FRAGIFY_TEMPLATES_DIR` – Pfad zu den Templates
|
||||||
|
- `FRAGIFY_STATIC_DIR` – Pfad zu den statischen Assets (`assets/`)
|
||||||
|
|
||||||
|
Beispiel (im uWSGI-Instance Block):
|
||||||
|
```nix
|
||||||
|
services.uwsgi.instance.fragify = {
|
||||||
|
env = {
|
||||||
|
FRAGIFY_TEMPLATES_DIR = "${pkgs.fragify}/share/fragify/templates";
|
||||||
|
FRAGIFY_STATIC_DIR = "${pkgs.fragify}/share/fragify/assets";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
## Entwicklung
|
## Entwicklung
|
||||||
|
|
||||||
|
|
@ -109,6 +139,8 @@ python fragify.py
|
||||||
- Python 3.8+
|
- Python 3.8+
|
||||||
- Falcon (Web-Framework)
|
- Falcon (Web-Framework)
|
||||||
- Requests (HTTP-Client)
|
- Requests (HTTP-Client)
|
||||||
|
- Node.js + npm (für lokale Assets)
|
||||||
|
- gulp (wird via npm-Script genutzt)
|
||||||
|
|
||||||
## Lizenz
|
## Lizenz
|
||||||
|
|
||||||
|
|
|
||||||
3
assets/css/select2-bootstrap-5-theme.min.css
vendored
Normal file
3
assets/css/select2-bootstrap-5-theme.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
2
assets/js/jquery.min.js
vendored
Normal file
2
assets/js/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
assets/js/jquery.min.map
Normal file
1
assets/js/jquery.min.map
Normal file
File diff suppressed because one or more lines are too long
11
fragify.py
11
fragify.py
|
|
@ -181,14 +181,19 @@ app = falcon.App()
|
||||||
# Discover static assets directory
|
# Discover static assets directory
|
||||||
STATIC_DIR = os.environ.get('FRAGIFY_STATIC_DIR')
|
STATIC_DIR = os.environ.get('FRAGIFY_STATIC_DIR')
|
||||||
if not STATIC_DIR:
|
if not STATIC_DIR:
|
||||||
# Prefer local assets folder in development
|
# Prefer local assets folder in development (relative to this file)
|
||||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
candidate = os.path.join(script_dir, 'assets')
|
candidate = os.path.join(script_dir, 'assets')
|
||||||
if os.path.isdir(candidate):
|
if os.path.isdir(candidate):
|
||||||
STATIC_DIR = candidate
|
STATIC_DIR = candidate
|
||||||
else:
|
else:
|
||||||
# Fallback to packaged location under share
|
# Try current working directory (useful when running packaged binary from project root)
|
||||||
STATIC_DIR = os.path.join(script_dir, '..', 'share', 'fragify', 'assets')
|
cwd_candidate = os.path.join(os.getcwd(), 'assets')
|
||||||
|
if os.path.isdir(cwd_candidate):
|
||||||
|
STATIC_DIR = cwd_candidate
|
||||||
|
else:
|
||||||
|
# Fallback to packaged location under share
|
||||||
|
STATIC_DIR = os.path.join(script_dir, '..', 'share', 'fragify', 'assets')
|
||||||
|
|
||||||
# Add routes
|
# Add routes
|
||||||
fragify = FragifyApp()
|
fragify = FragifyApp()
|
||||||
|
|
|
||||||
29
gulpfile.js
29
gulpfile.js
|
|
@ -1,15 +1,36 @@
|
||||||
var gulp = require('gulp');
|
var gulp = require('gulp');
|
||||||
var copy = require('gulp-copy');
|
var copy = require('gulp-copy');
|
||||||
|
|
||||||
gulp.task('copy-assets', function () {
|
// Copy bulk assets that already have css/js folder structure under dist
|
||||||
|
gulp.task('copy-bulk', function () {
|
||||||
return gulp
|
return gulp
|
||||||
.src([
|
.src([
|
||||||
'./node_modules/bootstrap/dist/**/*.+(css|js|map)',
|
'./node_modules/bootstrap/dist/**/*.+(css|js|map)',
|
||||||
'./node_modules/jquery/dist/**/*.+(js|map)',
|
'./node_modules/select2/dist/**/*.+(css|js|map)'
|
||||||
'./node_modules/select2/dist/**/*.+(css|js|map)',
|
|
||||||
'./node_modules/select2-bootstrap-5-theme/dist/**/*.+(css|js|map)'
|
|
||||||
], { allowEmpty: true })
|
], { allowEmpty: true })
|
||||||
.pipe(copy('./assets/', { prefix: 3 }));
|
.pipe(copy('./assets/', { prefix: 3 }));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Ensure jQuery lands in assets/js (jquery package doesn't have css/js subfolders)
|
||||||
|
gulp.task('copy-jquery', function () {
|
||||||
|
return gulp
|
||||||
|
.src([
|
||||||
|
'./node_modules/jquery/dist/jquery.min.js',
|
||||||
|
'./node_modules/jquery/dist/jquery.min.map'
|
||||||
|
], { allowEmpty: true })
|
||||||
|
.pipe(gulp.dest('./assets/js'));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ensure select2 bootstrap theme css lands in assets/css (file sits directly under dist)
|
||||||
|
gulp.task('copy-select2-theme', function () {
|
||||||
|
return gulp
|
||||||
|
.src([
|
||||||
|
'./node_modules/select2-bootstrap-5-theme/dist/select2-bootstrap-5-theme.min.css',
|
||||||
|
'./node_modules/select2-bootstrap-5-theme/dist/select2-bootstrap-5-theme.min.css.map'
|
||||||
|
], { allowEmpty: true })
|
||||||
|
.pipe(gulp.dest('./assets/css'));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('copy-assets', gulp.series('copy-bulk', 'copy-jquery', 'copy-select2-theme'));
|
||||||
|
|
||||||
gulp.task('default', gulp.series('copy-assets'));
|
gulp.task('default', gulp.series('copy-assets'));
|
||||||
|
|
@ -41,6 +41,7 @@ in
|
||||||
pythonPackages = p: with p; [ falcon requests jinja2 ];
|
pythonPackages = p: with p; [ falcon requests jinja2 ];
|
||||||
env = {
|
env = {
|
||||||
FRAGIFY_TEMPLATES_DIR = "${pkgs.fragify}/share/fragify/templates";
|
FRAGIFY_TEMPLATES_DIR = "${pkgs.fragify}/share/fragify/templates";
|
||||||
|
FRAGIFY_STATIC_DIR = "${pkgs.fragify}/share/fragify/assets";
|
||||||
};
|
};
|
||||||
socket = "unix:${config.services.uwsgi.runDir}/fragify.sock";
|
socket = "unix:${config.services.uwsgi.runDir}/fragify.sock";
|
||||||
chmod-socket = "660";
|
chmod-socket = "660";
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,26 @@
|
||||||
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
|
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
|
||||||
<link href="/static/css/select2.min.css" rel="stylesheet">
|
<link href="/static/css/select2.min.css" rel="stylesheet">
|
||||||
<link href="/static/css/select2-bootstrap-5-theme.min.css" rel="stylesheet">
|
<link href="/static/css/select2-bootstrap-5-theme.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<meta name="description" content="{{ meta_description | default('Erstelle vorausgefüllte FragDenStaat.de-Anfragelinks und teile sie mit Freund:innen. Suche Behörden, füge Betreff und Text hinzu und generiere einen teilbaren Link.') }}">
|
||||||
|
<link rel="canonical" href="{{ canonical_url | default('/') }}">
|
||||||
|
<link rel="alternate" hreflang="de" href="{{ canonical_url | default('/') }}">
|
||||||
|
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:site_name" content="Fragify">
|
||||||
|
<meta property="og:title" content="{{ meta_title | default('Fragify') }}">
|
||||||
|
<meta property="og:description" content="{{ meta_description | default('Erstelle vorausgefüllte FragDenStaat.de-Anfragelinks und teile sie mit Freund:innen.') }}">
|
||||||
|
<meta property="og:locale" content="de_DE">
|
||||||
|
<meta property="og:url" content="{{ canonical_url | default('/') }}">
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary_large_image">
|
||||||
|
<meta name="twitter:title" content="{{ meta_title | default('Fragify') }}">
|
||||||
|
<meta name="twitter:description" content="{{ meta_description | default('Erstelle vorausgefüllte FragDenStaat.de-Anfragelinks und teile sie mit Freund:innen.') }}">
|
||||||
|
|
||||||
|
<meta name="theme-color" content="#667eea">
|
||||||
|
<link rel="icon" href="/static/favicon.ico">
|
||||||
|
|
||||||
|
{% block meta_extra %}{% endblock %}
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue