Du hast deinen AdBlocker an?

Es wäre ein Traum, wenn du ihn für t3n.de deaktivierst. Wir zeigen dir gerne, wie das geht. Und natürlich erklären wir dir auch, warum uns das so wichtig ist. Digitales High-five, deine t3n-Redaktion

Entwicklung & Design

HTMLy: Der Einsteiger-Guide für das schlanke Blog-System ohne Datenbank

HTMLy. (Screenshot: HTMLy)

HTMLy ist eine junge Blog-Software, die keine Datenbank braucht, sondern nur mit Dateien arbeitet. Was das schlanke Blog-System kann, wie ihr es einrichtet und welche HTMLy-Theme-Funktionen es gibt, erfahrt ihr hier.

HTMLy bringt in der aktuelle Version 1.8 (Version 1.0 ist am 1. Februar erschienen) schon einiges an Funktionen mit: Zu unverzichtbarem wie einem Backend, suchmaschinenfreundlichen URLs, Tags, statischen Seiten und einer Archiv-Funktion kommen noch nützliche Funktionen wie Google Analytics, die Möglichkeit, mehrere Autoren anzulegen, Online-Backups und die Integration eines Markdown-Editors mit Live-Vorschau.

Alle Funktionen und den Quellcode findet ihr auf der GitHub-Site von HTMLy.

HTMLy installieren: Schnell, einfach und ohne Datenbank

Die Installation ist sehr schnell durchgeführt: Ihr schiebt die Dateien von der GitHub-Seite einfach auf euren Webspace. Anschließend müsst ihr die Datei config/config.ini.example in config.ini umbenennen. Damit das Blog erreichbar ist, müsst ihr am Anfang der Datei bei dem Punkt site.url die URL des Blogs angeben. Wenn ihr die URL jetzt aufruft, sollte euer Blog schon zu sehen sein. In der config.ini könnt ihr auch alle anderen Einstellungen ändern wie den Namen des Blogs, die Beschreibung, eure Social-Media-Links, externe Links für das Menü, welches Kommentarsystem ihr nutzen wollt und so weiter. Die Datei ist gut mit Kommentaren versehen und damit eigentlich selbsterklärend.

Jetzt braucht ihr für den Anfang nur noch einen Benutzer und ihr könnt starten. Um den anzulegen, erzeugt ihr einfach eine Datei HierDerNutzername.ini im Ordner config/users. In dieser Datei sind nur (maximal) zwei Zeilen notwendig:

password = YourPassword
role = admin

Wenn ihr einen Nutzer anlegen wollt, der keine Admin-Rechte haben soll, lasst Zeile 2 einfach weg. Jetzt könnt ihr euch über domain.tld/login anmelden.

Das Backend von HTMLy. (Screenshot: eigene HTMLy-Installation)
Das Backend von HTMLy. (Screenshot: t3n)

Anschließend findet ihr euch im Backend eures Blogs wieder. Hier könnt ihr euch die erstellten Artikel anschauen („Posts“, nur als Admin sichtbar), unter dem Punkt „Mine“ findet ihr die Artikel, die ihr selbst erstellt habt. Bei „Add post“ und „Add page“ könnt ihr neue Artikel beziehungsweise statische Seiten anlegen, was dank Live-Vorschau sehr angenehm ist. Euer sichtbares Profil ändert ihr bei „Edit profile“ und mit „Import“ könnt ihr andere Inhalte automatisch in eurem Blog veröffentlichen (was im Test allerdings nicht funktioniert hat). Unter dem Punkt „Backup“ könnt ihr mit einem Klick ein Backup erstellen und wahlweise herunterladen.

Pimp my HTMLy-Blog: Das Design

Die Auswahl an fertigen Designs ist noch sehr bescheiden, nur drei stehen bisher zur Auswahl. Das gewählte Theme kann in der config.ini geändert werden. Folgende Zeile müsst ihr dazu anpassen:

views.root = "themes/default"

Ein eigenes Design zu entwerfen, ist mit HTMLy aber kein Hexenwerk, wenn ihr Erfahrung in HTML, CSS und ein wenig Verständnis für PHP mitbringt. Ein Theme für HTMLy besteht nur aus einigen wenigen Dateien. Zwei davon sind für die Behandlung von nicht gefundenem Inhalt verantwortlich: Die 404-search.html.php wird genutzt, wenn bei einer Suche nichts gefunden wird. Die 404.html.php kümmert sich um herkömmliche 404-Fehler. In der Datei layout.html.php wird alles definiert, was auf jeder Inhaltsseite zu finden sein soll, also unter anderem Header und Sidebar. Je nach Inhalt wird dann eine der folgenden Dateien eingebunden, die sich um den konkreten Inhalt kümmern: Die main.html.php stellt eine Liste der Beiträge auf der Startseite dar, aber auch auf Archiv- und Tagseiten. Die no-posts.html.php macht genau das, was der Name vermuten lässt: Sie wird eingebunden, wenn keine Artikel vorhanden sind. Auch die Funktion von profile.html.php und static.html.php sollte klar sein.

Neben diesen Dateien gibt es dann nur noch den Ordner css mit einer CSS-Datei namens style.css. Ich werde im Folgenden die HTMLy-Theme-Funktionen beispielhaft am Code des Themes „clean“ erläutern. Anschließend sollte es euch leicht möglich sein, ein eigenes Design für euer HTMLy-Blog zu erstellen.

Die 404-Dateien sind fast identisch aufgebaut, ich werde hier kurz die Datei 404-search.html.php erläutern, da dort eine Funktion mehr implementiert ist:

<!DOCTYPE html>
<html>
<head>
<link href='<?php echo site_url() ?>favicon.ico' rel='icon' type='image/x-icon'/>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" user-scalable="no" />
<title>Search results not found! - <?php echo blog_title() ?></title>
<link href="<?php echo site_url() ?>themes/clean/css/style.css" rel="stylesheet" />
<!-- Include the Open Sans font -->
<link href="//fonts.googleapis.com/css?family=Open+Sans+Condensed:700&subset=latin,cyrillic-ext" rel="stylesheet" />
</head>
<body>
<div class="center message">
<h1>Search results not found!</h1>
<div class="search">
<?php echo search() ?>
</div>
<p>Please search again, or would you like to try our <a href="<?php echo site_url() ?>">homepage</a> instead?</p>
</div>
</body>
</html>

Im Gegensatz zu einigen anderen Dateien beinhaltet diese ein komplettes HTML-Gerüst. Die HTMLy-spezifischen Funktionen in dieser Datei sind folgende:

site_url()
blog_title()
search()

site_url() beinhaltet als Rückgabewert die URL des Blogs, die ihr in der config.ini definiert habt, blog_title() gibt dementsprechend den Titel des Blogs zurück, die Funktion search() ein Suchfeld mit Absende-Button. Interessanter ist die layout.html.php:

<!DOCTYPE html>
<html>
<head>
<?php echo $head_contents ?>
<link href="<?php echo site_url() ?>themes/clean/css/style.css" rel="stylesheet" />
<link href="//fonts.googleapis.com/css?family=Open+Sans+Condensed:700&subset=latin,cyrillic-ext" rel="stylesheet" />
<?php if (publisher()):?><link href="<?php echo publisher() ?>" rel="publisher" /><?php endif;?>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body class="<?php echo $bodyclass; ?>" itemscope="itemscope" itemtype="http://schema.org/Blog">
<div class="hide">
<meta content="<?php echo blog_title() ?>" itemprop="name"/>
<meta content="<?php echo blog_description() ?>" itemprop="description"/>
</div>
<?php if(facebook()) { echo facebook();} ?>
<?php if(login()) { toolbar();} ?>
<aside>
<?php if(is_index()) {?>
<h1 class="blog-title"><a rel="home" href="<?php echo site_url() ?>"><?php echo blog_title() ?></a></h1>
<?php } else {?>
<h2 class="blog-title"><a rel="home" href="<?php echo site_url() ?>"><?php echo blog_title() ?></a></h2>
<?php } ?>
<div class="search">
<?php echo search() ?>
</div>
<div class="social"><?php echo social() ?></div>
<div class="menu"><?php echo menu() ?></div>
<div class="archive"><?php echo archive_list()?></div>
<div class="tagcloud"><?php echo tag_cloud()?></div>
<div class="copyright"><?php echo copyright() ?></div>
</aside>
<section id="content">
<?php echo content()?>
</section>
<?php if (analytics()):?><?php echo analytics() ?><?php endif;?>
</body>
</html>

Die neuen HTMLy-spezifischen Funktionen und Variablen sind folgende:

$head_contents
publisher()
$bodyclass
login()
toolbar()
is_index()
social()
menu()
archive_list()
content()
analytics()

Die Variable $head_contents speichert den Seitentitel, den Link zum Favicon, einige meta-Tags, den Verweis zur Sitemap, die Angabe zur Canonical-URL und den Feed-Link. publisher() gibt die Google+-URL des Unternehmens zurück, wenn sie in der config.ini angegeben wurde. Die Variable bodyclass enthält – je nach Ansichtsart – verschiedene Zeichenketten. Wenn sich der Besucher auf der Startseite befindet, ist infront gespeichert. Wird ein einzelner Beitrag betrachtet, enthält die Variable den Wert inpost. Weiterhin gibt es die Werte intag, inarchive und inprofile. So können die verschiedenen Ansichten per CSS individuell gestylt werden.

facebook() hat – falls Facebook-Kommentare in der config.ini aktiviert sind – als Rückgabewert ein Stück JavaScript, das die Funktionalität bereitstellt. login() gibt zurück, ob der Nutzer eingeloggt ist, toolbar() hat als Rückgabewert die Admin-Bar. is_index() gibt true oder false zurück, je nachdem, ob sich der Besucher gerade auf der Startseite befindet oder nicht. social() gibt – sofern in der config.ini angegeben – die Links zu den sozialen Netzwerken zurück. menu() kümmert sich um die Rückgabe des Menüs, archive_list() gibt eine geschachtelte Liste mit Archivlinks aus, tag_cloud() und copyright() machen ebenfalls das, was ihr Name vermuten lässt. Den Copyright-Hinweis könnt ihr entfernen indem ihr ihn in der config.ini einfach leer lasst. Wichtig ist content(), denn hier wird je nach Seitenart eine andere Datei geladen, die sich dann um den Inhalt kümmert. analytics() gibt als Rückgabewert einen Google Analytics Tracking-Code zurück.

Interessant sind jetzt noch die Dateien main.html.php, post.html.php und profile.hmtl.php. Die anderen Dateien haben keine neuen Funktionen oder Variablen. Die main.html.php sieht wie folgt aus:

<?php if (!empty($breadcrumb)):?><div class="breadcrumb"><?php echo $breadcrumb ?></div><?php endif;?>
<?php $i = 0; $len = count($posts);?>
<?php foreach($posts as $p):?>
<?php
if ($i == 0) {
$class = 'post first';
}
elseif ($i == $len - 1) {
$class = 'post last';
}
else {
$class = 'post';
}
$i++;
?>
<div class="<?php echo $class ?>" itemprop="blogPost" itemscope="itemscope" itemtype="http://schema.org/BlogPosting">
<div class="main">
<h2 class="title-index" itemprop="name"><a href="<?php echo $p->url?>"><?php echo $p->title ?></a></h2>
<div class="date">
<span itemprop="datePublished"><?php echo date('d F Y', $p->date)?></span> - Posted in
<span itemprop="articleSection"><?php echo $p->tag ?></span> by
<span itemprop="author"><a href="<?php echo $p->authorurl ?>"><?php echo $p->author ?></a></span>
<?php
if (disqus_count()) {?> - <span><a href="<?php echo $p->url?>#disqus_thread">Comments</a></span>
<?php } elseif (facebook()){ ?> -
<a href="<?php echo $p->url ?>#comments"><span><fb:comments-count href=<?php echo $p->url ?>></fb:comments-count> Comments</span></a>
<?php } ?>
</div>
<div class="teaser-body" itemprop="articleBody">
<?php echo get_thumbnail($p->body)?>
<?php echo get_teaser($p->body, $p->url)?>
</div>
</div>
</div>
<?php endforeach;?>
<?php if (!empty($pagination['prev']) || !empty($pagination['next'])):?>
<div class="pager">
<?php if (!empty($pagination['prev'])):?>
<span><a href="?page=<?php echo $page-1?>" class="pagination-arrow newer" rel="prev">Newer</a></span>
<?php endif;?>
<?php if (!empty($pagination['next'])):?>
<span><a href="?page=<?php echo $page+1?>" class="pagination-arrow older" rel="next">Older</a></span>
<?php endif;?>
</div>
<?php endif;?>
<?php if (disqus_count()):?>
<?php echo disqus_count() ?>
<?php endif;?>

Das hier sind die neuen Funktionen und Variablen:

$breadcrumb
$posts
$class
$p->url
$p->title
$p->date
$p->tag
$p->authorurl
$p->author
disqus_count()
get_thumbnail($p->body)
get_teaser($p->body, $p->url)
$pagination['prev']
$pagination['next']

$breadcrumb speichert, wie der Name schon verrät, die Breadcrumb-Navigation. Durch die Variable $posts wird der Zugriff auf die Daten der einzelnen Posts ermöglicht. $class gibt den Artikeln eine Klasse post, es sei denn, es ist der erste oder letzte. Dann wird noch zusätzlich first oder last gespeichert. Mit den ganzen Varianten von $p-> wird auf die einzelnen Elemente des gerade in der Schleife bearbeiteten Artikels zugegriffen. disqus_count() gibt die Anzahl der Disqus-Kommentare zurück, get_thumbnail() und get_teaser() holen sich das Post-Thumbnail beziehungsweise den Teaser des Artikels. $pagination['prev'] und $pagination['next'] speichern den Slug des vorherigen oder nächsten Artikels.

<?php if (!empty($breadcrumb)):?><div class="breadcrumb" xmlns:v="http://rdf.data-vocabulary.org/#"><?php echo $breadcrumb ?></div><?php endif;?>
<?php if(login()) { echo tab($p);} ?>
<div class="post" itemprop="blogPost" itemscope="itemscope" itemtype="http://schema.org/BlogPosting">
<div class="main">
<a name="more"></a>
<h1 class="title-post" itemprop="name"><?php echo $p->title ?></h1>
<div class="date">
<span itemprop="datePublished"><a href="<?php echo $p->archive ?>" title="Show all posts made on this day"><?php echo date('d F Y', $p->date)?></a></span> - Posted in
<span itemprop="articleSection"><?php echo $p->tag ?></span> by
<span itemprop="author"><a href="<?php echo $p->authorurl ?>"><?php echo $p->author ?></a></span> -
<span><a href="<?php echo $p->url ?>" rel="permalink">Permalink</a></span>
</div>
<div class="post-body" itemprop="articleBody">
<?php echo $p->body; ?>
</div>
</div>
<div class="separator">→</div>
<div class="share-box">
<?php echo $authorinfo ?>
<div class="share">
<h4>Share this post</h4>
<a class="twitter"  href="https://twitter.com/share?url=<?php echo $p->url ?>&text=<?php echo $p->title?>">Twitter</a>
<a class="facebook"  href="https://www.facebook.com/sharer.php?u=<?php echo $p->url ?>&t=<?php echo $p->title?>">Facebook</a>
<a class="googleplus"  href="https://plus.google.com/share?url=<?php echo $p->url ?>">Google+</a>
</div>
</div>
<?php echo get_related($p->tag)?>
<div id="comments" class="comments border">
<?php if (facebook()):?>
<div class="fb-comments" data-href="<?php echo $p->url ?>" data-numposts="<?php echo config('fb.num') ?>" data-colorscheme="<?php echo config('fb.color') ?>"></div>
<?php endif;?>
<?php if (disqus()):?>
<div id="disqus_thread"></div>
<?php endif;?>
</div>
<div class="postnav">
<?php if (!empty($next)):?>
<span><a href="<?php echo ($next['url']);?>" class="pagination-arrow newer" rel="next"><?php echo ($next['title']);?></a></span>
<?php endif;?>
<?php if (!empty($prev)):?>
<span><a href="<?php echo ($prev['url']); ?>" class="pagination-arrow older" rel="prev"><?php echo ($prev['title']); ?></a></span>
<?php endif;?>
</div>
<?php if (disqus()):?>
<?php echo disqus($p->title, $p->url) ?>
<?php endif;?>
</div>

Neue Funktionen und Variablen:

tab($p)
$authorinfo
get_related($p->tag)
disqus()
$next
$prev

tab($p) gibt zwei Tabs aus: „View“ und „Edit“. Ersterer ist einfach ein Link zu dem Artikel, letzterer führt direkt ins Backend zur Bearbeitung des Artikels. $authorinfo speichert die Angaben über den Autoren, die dieser im Backend gemacht hat. get_related($p->tag) Gibt verwandte Beiträge aus, auf Basis der Tags ausgewählt, disqus() ist für die Darstellung der Disqus-Kommentare verantwortlich und $next und $prev geben die jeweiligen Titel des nächsten und vorherigen Artikels aus. In der Datei profile.html.php sind lediglich die zwei Variablen $name und $bio neu, die den Namen des Autors beziehungsweise die Autoreninformation beinhaltet.

Damit sollten eigentlich alle HTMLy-spezifischen Funktionen und Variablen kurz erläutert sein und euch den Einstieg in die Theme-Entwicklung etwas vereinfachen. Am leichtesten ist vermutlich, wenn ihr eins der drei Themes als Basis nehmt und dann nur die CSS-Datei neu schreibt und im Theme ein paar Anpassungen vornehmt.

Würdet ihr HTMLy, wenn ihr ein datenbankloses Blog-System einsetzen wollt, eine Chance geben? Neben HTMLy gibt es natürlich auch weitere kompakte Systeme – teils mit und teils ohne Datenbank. Welches System nutzt ihr zum Bloggen?

Finde einen Job, den du liebst

Bitte beachte unsere Community-Richtlinien

15 Reaktionen
byens

Ihr sollt nur encryption = password_hash in username.ini einfuegen.

Antworten
Florian Brinkmann

Und genau das ist der Fall, michaelh74, danke für den Denkanstoß! Ich habe gerade noch einmal nachgeschaut und es liegt eine .htacess mit deny from all im config-Ordner.

Antworten
michaelh74

Sieht gut & einfach aus. Sicher einen näheren Blick wert.
Zum Thema config.ini & Passwort. Ohne das System zu kennn, wird ein htaccess auf die .ini mit deny from all sicher schon mal helfen, falls noch nicht vorhanden.

Antworten
Pete

Florian deine Beiträge sind immer sehenswert! Danke für die Vorstellung von htmly :D

Echt schnell, einfach und ein sehr guter Tipp.

Antworten
Florian Brinkmann

Vielen Dank für eure Kommentare, ich werde in nächster Zeit ein Update mit möglichen Lösungen für das Passwort-Problem veröffentlichen.

Antworten
dos

Ich nutze HTMLy seit einigen Tagen und bin sehr zufrieden. Einfach und übersichtlich, dennoch hat es die wichtigsten Features für ein Blog. Das Backend ist allerdings (noch) rudimentär und eher etwas für Notfälle.

Ähnliche Systeme, die man sich anschauen sollte: Dropplets und Textpress.

Antworten
moortaube

Ich setze auf FlatPress.
Werde mit HTMLy aber auch mm näher anschauen, da mich solche „einfachen“ Systeme interessieren...

Antworten
Christian Zumbrunnen

@rené
nur speichere ich bei WordPress die wp-config.php normalerweise ausserhalb des Webroots. Das bedeutet für htmly: die Sicherheit muss via Dateiberechtigungen und .htaccess konfiguriert werden...

Antworten
Torsten

Ein interessanter Ansatz für eine schnelle und schlanke Bloglösung. Ich könnte mir den Einsatz gut im SEO Bereich vorstellen oder eben als extrem einfache Bloglösung. Die Usability bleibt aber bei so abgespeckten System etwas auf der Strecke.

Gruss
Torsten

Antworten
Jens

Klingt interessant, mal schauen was da in Zukunft noch kommt.
Zumindest für den gelegentlichen Blogger, der nicht so viel drum herum an Technik möchte, klingt es erstmal ganz gut geeignet.
Käme aber wohl auf einen Test an …

Gruß,
Jens

Antworten
René

Naja, wäre dann wie bei WP, wo das Passwort auch plain in der wp-config schlummert + DB-Passwort. ;)

Antworten
Michael Kupfer

Seh ich das richtig, dass das Paswort als Klartext gespeichert wird?
Ich bezweifel, dass das sicher ist

Antworten
F-Heck

Ich benutze für alle Blogs inzwischen mein eigenes Python-Skript. Bin ein absolutes Fan von so schlanken Systemen, gerade weil ich ursprünglich aus der Ecke der großen und namhaften CMS' komme.
Werde mir HTMLy mal schauen, danke!

Antworten
stooni2

Gefällt mir echt gut, werde es mal weite ansehen, Super schlank und schnell! Und erst noch individuell!!!

---viele Funktionen die man bei WordPress vermisst sind hier berücksichtigt!
-----stooni

Antworten

Melde dich mit deinem t3n-Account an oder fülle die unteren Felder aus.

Abbrechen