Grav: Unterschied zwischen den Versionen
Lukas (Diskussion | Beiträge) |
Lukas (Diskussion | Beiträge) |
||
Zeile 102: | Zeile 102: | ||
{% set theme_config = attribute(config.themes, config.system.pages.theme) %} | {% set theme_config = attribute(config.themes, config.system.pages.theme) %} | ||
<!DOCTYPE html> | <!DOCTYPE html> | ||
<html lang="{{ grav.language.getActive ?: theme_config.default_lang }}"> | <html lang="<nowiki>{{</nowiki> grav.language.getActive ?: theme_config.default_lang <nowiki>}}</nowiki>"> | ||
<head> | <head> | ||
{% block head %} | {% block head %} | ||
<meta charset="utf-8" /> | <meta charset="utf-8" /> | ||
<title>{{ site.title|e('html') }}: {% if header.title %}{{ header.title|e('html') }}{% endif %}</title> | <title><nowiki>{{</nowiki> site.title|e('html') <nowiki>}}</nowiki>: {% if header.title %}<nowiki>{{</nowiki> header.title|e('html') <nowiki>}}</nowiki>{% endif %}</title> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | <meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1"> | <meta name="viewport" content="width=device-width, initial-scale=1"> | ||
{% include 'partials/metadata.html.twig' %} | {% include 'partials/metadata.html.twig' %} | ||
<link rel="icon" type="image/png" href="{{ url('theme://images/logo.png') }}" /> | <link rel="icon" type="image/png" href="<nowiki>{{</nowiki> url('theme://images/logo.png') <nowiki>}}</nowiki>" /> | ||
<link rel="canonical" href="{{ page.url(true, true) }}" /> | <link rel="canonical" href="<nowiki>{{</nowiki> page.url(true, true) <nowiki>}}</nowiki>" /> | ||
{% block stylesheets %} | {% block stylesheets %} | ||
{#% do assets.addCss('http://yui.yahooapis.com/pure/0.6.0/pure-min.css', 100) %#} | {#% do assets.addCss('http://yui.yahooapis.com/pure/0.6.0/pure-min.css', 100) %#} | ||
Zeile 119: | Zeile 119: | ||
{% do assets.addCss('theme://css/anpassung.css', 97) %} | {% do assets.addCss('theme://css/anpassung.css', 97) %} | ||
{% endblock % } | {% endblock % } | ||
{{ assets.css() }} | <nowiki>{{</nowiki> assets.css() <nowiki>}}</nowiki> | ||
{% block javascripts %} | {% block javascripts %} | ||
{% do assets.addJs('jquery', {'priority' : 100, 'group' : 'bottom'}) %} | {% do assets.addJs('jquery', {'priority' : 100, 'group' : 'bottom'}) %} | ||
{% do assets.addJs('theme://js/bootstrap.min.js', {'priority' : 99, 'group' : 'bottom'}) %} | {% do assets.addJs('theme://js/bootstrap.min.js', {'priority' : 99, 'group' : 'bottom'}) %} | ||
{% endblock %} | {% endblock %} | ||
{{ assets.js() }} | <nowiki>{{</nowiki> assets.js() <nowiki>}}</nowiki> | ||
{% endblock head%} | {% endblock head%} | ||
</head> | </head> | ||
<!--<div class="wrapper padding"> | <!--<nowiki><div</nowiki> class="wrapper padding"> | ||
<a class="logo left" href="{{base_url == '' ? '/' : base_url }}"> | <a class="logo left" href="<nowiki>{{</nowiki>base_url == '' ? '/' : base_url <nowiki>}}</nowiki>"> | ||
<i class="fa fa-rebel"></i > | <i class="fa fa-rebel"></i > | ||
{{ config.site.title }}--> | <nowiki>{{</nowiki> config.site.title <nowiki>}}</nowiki>--> | ||
<body id="top" class="{{ page.header.body_classes }}"> | <body id="top" class="<nowiki>{{</nowiki> page.header.body_classes <nowiki>}}</nowiki>"> | ||
<div id="einspaltig"> | <nowiki><div</nowiki> id="einspaltig"> | ||
<div class="container"> | <nowiki><div</nowiki> class="container"> | ||
{% block header %} | {% block header %} | ||
<div class="row" id="header"> | <nowiki><div</nowiki> class="row" id="header"> | ||
<div class="col-md-12"> | <nowiki><div</nowiki> class="col-md-12"> | ||
<div id="skiplink"> | <nowiki><div</nowiki> id="skiplink"> | ||
<a class="skip" title="Direkt zur Navigation springen" href="#navigation">Zur Navigation springen</a><br> | <a class="skip" title="Direkt zur Navigation springen" href="#navigation">Zur Navigation springen</a><br> | ||
<a class="skip" title="Direkt zum Content springen" href="#content">Zum Content springen</a> | <a class="skip" title="Direkt zum Content springen" href="#content">Zum Content springen</a> | ||
Zeile 146: | Zeile 146: | ||
{% endblock %} | {% endblock %} | ||
{% block header_navigation %} | {% block header_navigation %} | ||
<div id="navbar"> | <nowiki><div</nowiki> id="navbar"> | ||
<nav class="navbar navbar-default" role="navigation"> | <nav class="navbar navbar-default" role="navigation"> | ||
<a id="navigation" name="navigation"></a> | <a id="navigation" name="navigation"></a> | ||
<!-- Titel und Schalter werden für eine bessere mobile Ansicht zusammengefasst --> | <!-- Titel und Schalter werden für eine bessere mobile Ansicht zusammengefasst --> | ||
<div class="navbar-header"> | <nowiki><div</nowiki> class="navbar-header"> | ||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-collapse-1"> | <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-collapse-1"> | ||
<span class="sr-only">Navigation ein-/ausblenden</span> | <span class="sr-only">Navigation ein-/ausblenden</span> | ||
Zeile 160: | Zeile 160: | ||
</div> | </div> | ||
<!-- Alle Navigationslinks, Formulare und anderer Inhalt werden hier zusammengefasst und können dann ein- und ausgeblendet werden --> | <!-- Alle Navigationslinks, Formulare und anderer Inhalt werden hier zusammengefasst und können dann ein- und ausgeblendet werden --> | ||
<div class="collapse navbar-collapse" id="navbar-collapse-1"> | <nowiki><div</nowiki> class="collapse navbar-collapse" id="navbar-collapse-1"> | ||
{% include 'partials/navigation.html.twig' %} | {% include 'partials/navigation.html.twig' %} | ||
</div> <!-- /.navbar-collapse --> | </div> <!-- /.navbar-collapse --> | ||
Zeile 166: | Zeile 166: | ||
</div> | </div> | ||
{% endblock %} | {% endblock %} | ||
<!--<div id="service">Service</div> | <!--<nowiki><div</nowiki> id="service">Service</div> | ||
<div id="rootline">Rootline</div>--> | <nowiki><div</nowiki> id="rootline">Rootline</div>--> | ||
{% block body %} | {% block body %} | ||
<div id="inhalt" class="row equalheight"> | <nowiki><div</nowiki> id="inhalt" class="row equalheight"> | ||
<div class="col-md-12 equal" id="hauptinhalt"> | <nowiki><div</nowiki> class="col-md-12 equal" id="hauptinhalt"> | ||
{% block content %} | {% block content %} | ||
{% endblock %} | {% endblock %} | ||
Zeile 177: | Zeile 177: | ||
{% endblock %} | {% endblock %} | ||
{% block footer %} | {% block footer %} | ||
<div class="row" id="footer"> | <nowiki><div</nowiki> class="row" id="footer"> | ||
<div class="col-md-12">© Netthelp.de (2016)</div> | <nowiki><div</nowiki> class="col-md-12">© Netthelp.de (2016)</div> | ||
</div> | </div> | ||
{% endblock %} | {% endblock %} | ||
Zeile 184: | Zeile 184: | ||
</div> | </div> | ||
{% block bottom %} | {% block bottom %} | ||
{{ assets.js('bottom') }} | <nowiki>{{</nowiki> assets.js('bottom') }} | ||
{% endblock %} | {% endblock %} | ||
</body> | </body> |
Version vom 13. November 2016, 21:55 Uhr
Momentan setze ich auf vielen Seiten das Content Management System Typo3 ein, das sehr mächtig und vielseitig, dadurch aber an einigen Stellen auch kompliziert ist. Besonders für kleine Seiten ist daher der Wunsch nach einem kleineren CMS immer größer geworden. Die Ausgabe 15/2016 der c't stellt eine spannende Alternative zur Verfügung: Das CMS Grav, das ohne Datenbank auskommt und alle Daten in Dateien speichert.
Wahlweise gibt es Grav mit oder ohne Administration-Oberfläche. Die Inhalte der Seiten können auch über die Kommandozeile manipuliert werden. Zur Bedienung durch Endanwender ist aber eine Admin-Oberfläche sinnvoll.
Installation
Zunächst lädt man sich das entsprechende Paket von der Seit https://getgrav.org/downloads herunter:
wget https://github.com/getgrav/grav/releases/download/1.1.1/grav-admin-v1.1.1.zip
Nach dem Entpacken
unzip grav-admin-v1.1.1.zip
ist die Installation unter http://example.com/grav-admin erreichbar. Für eine öffentliche Homepage kann es sinnvoll sein, die Dateien in das Wurzelverzeichnis der Domain zu kopieren. Wichtig ist hierbei, auch die .htaccess-Datei mit zu kopieren.
Wenn die Verzeichnisrechte stimmen, bekommen wir einen Dialog angezeigt, um unsere Benutzerdaten einzugeben. Falls nicht:
sudo chown www-data.www-data ./grav-admin sudo chmod -R 0770 ./grav-admin
Nach dem Erstellen des Benutzers, bekommen wir das Dashboard zu Gesicht, in dem wir Infos über den Zustand der Installation und die letzten Änderungen erhalten.
Konfiguration
Die Grav-Installation lässt sich bequem über die Weboberfläche konfigurieren. Dafür wählt man links den Punkt "Configuration" aus. Hier kann man im ersten Schritt die Sprache "de" unter "languages" hinzufügen, um die Administration auf Deutsch anzuzeigen. Mit dem Klick auf entsprechenden Button zum Speichern an der Oberseite des Bildschirms, wird die entsprechende Änderung wirksam. Hier können wir auch den Seitentitel und weitere Einstellungen verändern.
Grav arbeitet mit der Auszeichnungssprache YAML. Im Prinzip kann man also die gesamte Konfiguration über die Dateien unter ./grav-admin/user/config/ manipulieren.
Seiten erstellen
Unter dem Menüpunkt "Seiten" lassen sich die Seiten anlegen und verwalten. Um eine neue Seite zu erstellen, wählt man im oberen Menü den Punkt "Seite hinzufügen" aus. Die Positionierung der Seite, der Name und die Sichtbarkeit lassen sich im darauffolgenden Dialog einstellen. Die Seite lässt sich nach dem Erstellen noch weiter konfigurieren.
Grav arbeitet mit unterschiedlichen Seitenvorlagen. Je nach Theme lassen sich neben "Default" noch weitere Templates auswählen. So können beispielsweise ein Blog oder ein Kontaktformular einfach eingestellt werden.
Inhalt einstellen
Nach dem Anlegen der Seite landet man direkt auf der Eingabemaske für Inhalt. Hier bedient sich Grav der Textauszeichnungssprache Markdown. Die verschiedenen Gestaltungs- und Logikmerkmale, wie Überschrift, fett, kursiv oder unterstrichen lassen sich bequem über die Formatierungsleiste auswählen. Alternativ kann man die Formartierung auch direkt in das Textfeld eingeben, der Editor wandelt das dann auch entsprechend um:
#
steht für die Überschrift 1, weitere Rauten markieren dann die weiteren Ebenen (##
für Überschrift 2, etc.).**Text**
lässt den Text fett werden_Text_
unterstreicht den Text~~Text~~
streicht den Text durch===
fügt einen Strich für die Zusammenfassung ein[](http://)
setzt einen Link![](http://)
fügt ein Bild aus der angegebenen Quelle ein
Theme mit Twig
Spannend wird die Themeerstellung. Grav nutzt die Engine Twig, um Layouts mit Inhalt zu füllen. Dadurch lassen sich auch komplexe Layouts relativ einfach in Grav einbinden.
Zunächst installiert man die Developer-Tools entweder über die Oberfläche oder über den GPM (Grav Paket Manager):
./grav-admin/bin/gpm install devtools
Daraufhin lässt man sich ein neues leeres Theme anlegen:
./grav-admin/bin/plugin devtools new-theme
Enter Theme Name: LT42 Enter Theme Description: Simple theme providing bootstrap Enter Developer Name: Lukas Thiel Enter Developer Email: lukas@lt42.de Please choose a template type [0] pure-blank [1] inheritence > 0
Das "pure-blank"-Theme erstellt ein neues leeres Theme, "inheritence" würde ein bestehendes Theme erweitern. Daraufhin ist unter ./grav-admin/user/themes/ das angegebene Verzeichnis erstellt worden. Generell gilt folgende Struktur:
lt42 |--blueprints |--css |--css-compiled |--fonts |--images |--js |--scss |--templates |--forms |--modular |--partials lt42.php lt42.yaml blueprints.yaml screenshot.jpg scss.sh thumbnail.jpg
Die Struktur ist relativ selbst erklärend. Das Grav-Team rät, die entsprechenden Dateien in die dafürvorgesehenden Verzeichnisse zu legen. Für die Verwendung sind mindestens die blueprints.yaml, lt42.php, lt42.yaml und das Verzeichnis templates/ nötig. Für eine Veröffentlichung zusätzlich:
- CHANGELOG.md
- LICENSE
- README.md
- screenshot.jpg
- thumbnail.jpg
Theme erstellen
Im Verzeichnis templates/ finden sich die HTML-Grundgerüste des Themes und der verschiedenen Templates. Im Ordner partials/ findet sich die Datei base.html.twig. Diese stellt das Grundgerüst des Themes dar. Die Datei spricht für sich: Es gibt verschiedene Blocks, in denen dynamisch Inhalt generiert wird. Interessant sind zusätzlich die angegebenen Assets. Jede CSS- oder JavaScript-Datei wird hinzugefügt. Daraufhin werden die Assets generiert und ausgegeben. Der Vorteil ist, dass man prinzipiell völlig ungeordnet alle Dateien in das Twig-Template schreiben könnte und die Sortierung trotzdem richtig wäre. Eine Übersicht über die verschiedenen Möglichkeiten bietet der Artikel zum Asset Manager in der Grav-Doku (https://learn.getgrav.org/themes/asset-manager).
Mein Ziel ist es, ein Bootstrap-Layout einzubinden. Ich habe das Bootstrap-Paket heruntergeladen und in die entsprechenden Verzeichnisse entpackt. Zusätzlich auch die im Bootstrap-Grundlayout (http://getbootstrap.com/getting-started/#template) eingebundenen JavaScripts, damit diese nicht von extern eingebunden werden müssen. Meine base.html.twig sieht so aus:
{% set theme_config = attribute(config.themes, config.system.pages.theme) %} <!DOCTYPE html> <html lang="{{ grav.language.getActive ?: theme_config.default_lang }}"> <head> {% block head %} <meta charset="utf-8" /> <title>{{ site.title|e('html') }}: {% if header.title %}{{ header.title|e('html') }}{% endif %}</title> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> {% include 'partials/metadata.html.twig' %} <link rel="icon" type="image/png" href="{{ url('theme://images/logo.png') }}" /> <link rel="canonical" href="{{ page.url(true, true) }}" /> {% block stylesheets %} {#% do assets.addCss('http://yui.yahooapis.com/pure/0.6.0/pure-min.css', 100) %#} {% do assets.addCss('theme://css/font-awesome.min.css', 100) %} {% do assets.addCss('theme://css/bootstrap.min.css', 99) %} {% do assets.addCss('theme://css/bootstrap-theme.min.css', 98) %} {% do assets.addCss('theme://css/anpassung.css', 97) %} {% endblock % } {{ assets.css() }} {% block javascripts %} {% do assets.addJs('jquery', {'priority' : 100, 'group' : 'bottom'}) %} {% do assets.addJs('theme://js/bootstrap.min.js', {'priority' : 99, 'group' : 'bottom'}) %} {% endblock %} {{ assets.js() }} {% endblock head%} </head> <body id="top" class="{{ page.header.body_classes }}"> <div id="einspaltig"> <div class="container"> {% block header %} <div class="row" id="header"> <div class="col-md-12"> <div id="skiplink"> <a class="skip" title="Direkt zur Navigation springen" href="#navigation">Zur Navigation springen</a>
<a class="skip" title="Direkt zum Content springen" href="#content">Zum Content springen</a>
Header
{% endblock %}
{% block header_navigation %}
<div id="navbar">
<nav class="navbar navbar-default" role="navigation">
<a id="navigation" name="navigation"></a>
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-collapse-1">
Navigation ein-/ausblenden
</button>
<a class="navbar-brand" href="#">Hauptmenü</a>
<div class="collapse navbar-collapse" id="navbar-collapse-1"> {% include 'partials/navigation.html.twig' %}
</nav>
{% endblock %} {% block body %} <div id="inhalt" class="row equalheight"> <div class="col-md-12 equal" id="hauptinhalt"> {% block content %} {% endblock %}
{% endblock %} {% block footer %} <div class="row" id="footer">
<div class="col-md-12">© Netthelp.de (2016)
{% endblock %}
{% block bottom %} {{ assets.js('bottom') }} {% endblock %} </body>
Die navigation.html.twig kommt später. Spannend ist aber, dass Twig von Haus aus eine Funktion zum Ein- oder Abschalten des DropDown-Menüs mitbringt.
Theme aktivieren
Stellt man das Theme in den Einstellungen oder unter dem Menü-Punkt "Themes" um, kann man sein Ergebnis sofort betrachten. Nun fehlen noch ein zweites Menü und die Einbindung des DropDown-Menüs.
Weblinks
- https://learn.getgrav.org/themes/theme-basics - Grundlegendes zu Grav-Themes
- https://learn.getgrav.org/themes/theme-tutorial - Eine Anleitung zum Erstellen von Grav-Themes