einfacher Blog ohne Datenbank

Hier möchte ich euch kurz erklären, was man für einen Blog ohne Datenbank benötigt. Wir brauchen zwei Dateien, ein Model zum auslesen der einzelnen Unterseiten und einen View zum Darstellen des Blogs und dessen Unterseiten.

Der Aufbau des Blogs sollte so oder so ähnlich sein. Mit der blog.php rufen wir unseren Blog auf http://www.domain.tld/blog/blog.php.

folgende OrdnerStruktur wird angelegt:

  • blog
    • models
      • blog.class.php
    • views
      • blog_start.php
      • sites
        • blog_1.php
        • blog_2.php
    • blog.php

/blog/models/blog.class.php

<?php class Blog 
{

} ?>

Das allein nützt uns noch nichts, wir bnötigen ja alle Dateien aus dem Ordner /blog/views/sites/, diese Seiten wollen wir später anzeigen. Also brauchen wir eine Methode um diese Auszulesen.

Damit wir den richtigen Ordner Auslesen, geben wir das Verzeichnis für den Ordner "sites" an, ausgehend vom Root der Webseite.

<?php class Blog
{
	private $folder;
	
	public function __construct()
    {
		$this->folder = $_SERVER['DOCUMENT_ROOT'].'/blog/views/sites';
	}
} ?>

Jetzt lesen wir mit der Methode $blog->getFiles(), den Ordner "sites" aus, in dieser wird mit is_dir geprüft, ob das Verzeichnis auch existiert. Wir nehmen alle Dateien mit der Endung ".php" und erstellen uns ein Array "$files" mit allen zur Verfügung stehenden Dateien.

Wir haben den Key als filetime() für die jeweilige Datei gewählt um das Array vor der Ausgabe noch nach Datum zu sortieren, so ist es möglich den neusten Beitrag als erstes zu sehen.

<?php class Blog 
{
	private $folder;
	
	public function __construct()
    {
		$this->folder = $_SERVER['DOCUMENT_ROOT'].'/blog/views/sites';
	}
	
	private function getFiles()
	{
		$directory = $this->folder;
		if(is_dir($directory))
		{	
			$scan_folder = scandir($directory);
			$files = array();
			foreach($scan_folder as $file)
			{
				if($file != '.' && $file != '..' && strpos($file, '.php') !== FALSE) $files[] = array('time'=>filemtime($this->folder.'/'.$file), 'file'=>$file);
			}
			return $files;
		}
	}
} ?>

Wenn jetzt alles gut gegangen ist, sollten wir ein Array mit den Beiträgen haben, die wir in unserem Blog anzeigen wollen. Damit können wir weiter arbeiten, wir benötigen ja die Inhalte aus den Dateien.

Um diese zu erfahren, erstellen wir eine Methode $blog->getSites(), darein übernehmen wir das erstellte Array der vorhandenen Dateien ($this->getFiles()). Mit ob_start Puffern wir die Inhalte der Dateien um diese vor der Ausgabe verändern zu können. Warum genau erkläre ich später noch.

<?php class Blog 
{
	private $folder;
	
	public function __construct()
    {
		$this->folder = $_SERVER['DOCUMENT_ROOT'].'/blog/views/sites';
	}
	
	public function getSites()
	{
		$files = $this->getFiles();
		$blogs = array();
		foreach($files as $key=>$file)
		{
			$time[$key] = $file['time'];
		}
		array_multisort($time, SORT_DESC, $files);
		foreach($files as $file)
		{
			foreach($file as $site)
			{
				ob_start();  
				ob_implicit_flush(FALSE);
				$file = $this->folder.'/'.$site; 
				if(file_exists($file)) include($file);
				$content = ob_get_contents();  
				ob_end_clean();
				$blogs[] = $content; 
			}
		}
		return $blogs;
	}
	
	private function getFiles()
	{
		$directory = $this->folder;
		if(is_dir($directory))
		{	
			$scan_folder = scandir($directory);
			$files = array();
			foreach($scan_folder as $file)
			{
				if($file != '.' && $file != '..' && strpos($file, '.php') !== FALSE) $files[] = array('time'=>filemtime($this->folder.'/'.$file), 'file'=>$file);
			}
			return $files;
		}
	}
} ?>

Sind wir mit dem Auslesen der Dateien fertig, sollten wir ein schönes Array mit den Inhalten zur Verfügung stehen haben. Damit wir dieses ausgeben können, müssen wir unseren View (blog_start.php) aufbauen, vorher binden wir unsere Klasse (Blog) über die blog.php ein.

Diese Datei übernimmt dann auch gleich die Ausgabe der Views.

/blog/blog.php

<?php include_once(dirname(__file__).'/models/blog.class.php');
$blog = new Blog();
include_once(dirname(__file__).'/views/blog_start.php'); ?>

Jetzt lassen wir unser erstelltes Array mit den Inhalten in der blog_start.php, mit einem foreach ausgeben.

/blog/views/blog_start.php

<div id="blogs">
	<h2>Next Level Design Blog</h2>
	<?php foreach($blog->getSites() as $site) { ?>
		<div class="site">
			<?php echo $site; ?>
		</div>
	<?php } ?>
</div>

Um noch einmal auf den Puffer in der blog.class.php zurückzukommen, wenn wir ein "weiterlesen" haben wollen, können wir die Ausgabe darüber steuern.

Dazu bauen wir uns in die Sites ein:

<hr class="weiterlesen" />

ein und erweitern unser Model $blog->getSites() mit den folgenden Zeilen.

<?php if(strpos($content, '<hr class="weiterlesen" />') !== FALSE)
{
	$_content = str_replace('<hr class="weiterlesen" />', '<a href="/blog/blog.php?site='.strstr($site, '.', TRUE).'">» weiterlesen</a><hr class="weiterlesen" />', $content);
	$blogs[] = strstr($_content, '<hr class="weiterlesen" />', TRUE);
} else {
	$blogs[] = $content; 
} ?>

Es sollte dann so aussehen. So haben wir die Möglichkeit, den Text nach dem Weiterlesen zu entfernen und erst nach dem klick auf weiterlesen anzuzeigen.

<?php class Blog 
{
	private $folder;
	
	public function __construct()
    {
		$this->folder = $_SERVER['DOCUMENT_ROOT'].'/blog/views/sites';
	}
	
	public function getSites()
	{
		$files = $this->getFiles();
		$blogs = array();
		foreach($files as $key=>$file)
		{
			$time[$key] = $file['time'];
		}
		array_multisort($time, SORT_DESC, $files);
		foreach($files as $file)
		{
			foreach($file as $site)
			{
				ob_start();  
				ob_implicit_flush(FALSE);
				$file = $this->folder.'/'.$site; 
				if(file_exists($file)) include($file);
				$content = ob_get_contents();  
				ob_end_clean();
				if(strpos($content, '<hr class="weiterlesen" />') !== FALSE)
				{
					$_content = str_replace('<hr class="weiterlesen" />', '<a href="/blog/blog.php?site='.strstr($site, '.', TRUE).'">» weiterlesen</a><hr class="weiterlesen" />', $content);
					$blogs[] = strstr($_content, '<hr class="weiterlesen" />', TRUE);
				} else {
					$blogs[] = $content; 
				}
			}
		}
		return $blogs;
	}
	
	private function getFiles()
	{
		$directory = $this->folder;
		if(is_dir($directory))
		{	
			$scan_folder = scandir($directory);
			$files = array();
			foreach($scan_folder as $file)
			{
				if($file != '.' && $file != '..' && strpos($file, '.php') !== FALSE) $files[] = array('time'=>filemtime($this->folder.'/'.$file), 'file'=>$file);
			}
			return $files;
		}
	}
} ?>

Jetzt erweitern wir unsere Model noch um eine weitere Methode $blog->getSite(), so können wir einzelne Seiten komplett darstellen. Den hr Tag entfernen wir noch.

<?php public function getSite()
{
	$site = $_GET['site'].'.php'; // Bitte einen Filter auf GET legen, über ein Framework, oder mit PHP
	if(file_exists($this->folder.'/'.$site))
	{
		ob_start();  
		ob_implicit_flush(FALSE);
		$file = $this->folder.'/'.$site; 
		if(file_exists($file)) include($file);
		$content = ob_get_contents();  
		ob_end_clean();
		return str_replace('<hr class="weiterlesen" />', '', $content);
	} else {
		return FALSE;
	}
} ?>

Unser komplettes Model sieht nun so aus, wir haben es noch erweitert um die Funktion der Listenlänge, so können wir eine bestimmte Anzahl an Beiträgen pro Seite darstellen. Mit der Listenlänge von Arrays beschäftigen wir uns später.

<?php class Blog 
{
	private $folder;
	
	public function __construct()
    {
		$this->folder = $_SERVER['DOCUMENT_ROOT'].'/blog/views/sites';
	}
	
	public function getSite()
	{
		$site = $_GET['site'].'.php'; // Bitte einen Filter auf GET legen, über ein Framework, oder mit PHP
		if(file_exists($this->folder.'/'.$site))
		{
			ob_start();  
			ob_implicit_flush(FALSE);
			$file = $this->folder.'/'.$site; 
			if(file_exists($file)) include($file);
			$content = ob_get_contents();  
			ob_end_clean();
			return str_replace('<hr class="weiterlesen" />', '', $content);
		} else {
			return FALSE;
		}
	}
	
	public function getSites()
	{
		$files = $this->getFiles();
		$blogs = array();
		foreach($files as $key=>$file)
		{
			$time[$key] = $file['time'];
		}
		array_multisort($time, SORT_DESC, $files);
		foreach($files as $file)
		{
			foreach($file as $site)
			{
				ob_start();  
				ob_implicit_flush(FALSE);
				$file = $this->folder.'/'.$site; 
				if(file_exists($file)) include($file);
				$content = ob_get_contents();  
				ob_end_clean();
				if(strpos($content, '<hr class="weiterlesen" />') !== FALSE)
				{
					$_content = str_replace('<hr class="weiterlesen" />', '<a href="/blog/blog.php?site='.strstr($site, '.', TRUE).'">» weiterlesen</a><hr class="weiterlesen" />', $content);
					$blogs[] = strstr($_content, '<hr class="weiterlesen" />', TRUE);
				} else {
					$blogs[] = $content; 
				}
			}
		}
		return $blogs;
	}
	
	private function getFiles()
	{
		$directory = $this->folder;
		if(is_dir($directory))
		{	
			$scan_folder = scandir($directory);
			$files = array();
			foreach($scan_folder as $file)
			{
				if($file != '.' && $file != '..' && strpos($file, '.php') !== FALSE) $files[] = array('time'=>filemtime($this->folder.'/'.$file), 'file'=>$file);
			}
			return $files;
		}
	}
} ?>

Wenn wir jetzt in unserem View abfragen ob $blog->getSite() !empty ist, können wir die Ansicht auf den einzelnen Beitrag wandeln. Mit einem Zurückbutton kommen wir wieder auf die Blogansicht.

<div id="blogs">
	<?php $site = $blog->getSite(); ?>
	<h2>Next Level Design Blog</h2>
	<?php if(empty($site)) { ?>
		<?php foreach($blog->getSites() as $site) { ?>
			<div class="site">
				<?php echo $site; ?>
			</div>
		<?php } ?>
	<?php } else { ?>
		<?php echo $site; ?>
		<a onclick="window.history.back();" class="button_box">zurück</a>
	<?php } ?>
</div>

Wir haben jetzt css weggelassen, Ihr könnt euch den Blog so stylen, wie es euch am besten gefällt. Hier das fertige Script zum Download blog.zip. Wir hoffen euch hat unser erster Blog gefallen und Ihr könnt mit dem Script etwas anfangen. Gern würden wir uns auch über ein Like freuen.

Kommentare

Kommentare können nur mit einer Verifizierten E-Mail-Adresse geschrieben werden, die E-Mail-Adresse muss einmal bestätigt werden.
@
(success)