Hier stelle ich konkrete und überschaubare Aufgaben und ihre Lösung per PHP vor.
Die Seite richtet sich in erster Linie an Web-Autoren ohne Programmierkenntnisse, die ihren Dokumenten einige Extras hinzufügen möchten.
In der Rubrik Gesuchte Skripte skizziere ich Aufgaben, für die ich noch eine Lösung suche.
title-Element mit dem Inhalt der ersten h1-Überschrift
füllen
id-Attribute
für jeden ListenpunktIn der Kürze liegt die Würze.
Dir ist
<?php include "meta.inc" ?>
lieber als
<?php include "/www/domain.de/meine-includes/meta.inc"
?>
Was ist nötig um auf die fett hervorgehobenen Pfadteile zu verzichten?
test.php im gleichen Verzeichnis
wie Ihre Includes an und laden Sie sie hoch.http://domain.de/meine-includes/test.php:
<?php
if (isset($_GET['path']) ) {
header ("Content-Type: text/html;charset=utf-8");
$width = strlen($_SERVER['SCRIPT_FILENAME']);
echo <<<EOD <p>Benutze diesen Pfad, um das aktuelle Script einzubinden:<br>
<input type="text" size="${width}" onFocus="this.select()"
value="${_SERVER['SCRIPT_FILENAME']}">
EOD;
}
?>
?path an
die URL:http://domain.de/meine-includes/test.php?path/www/domain.de/htdocs/meine-includes/test.php /meine-includes/header.inc in
Ihrer Site an:
<?php set_include_path(get_include_path() . PATH_SEPARATOR . "/www/domain.de/htdocs/meine-includes/"); ?>Der fett hinterlegte Teil ist der Teil, den Sie eben kopiert haben.
dokument-eins.php:
<?php include "/www/domain.de/meine-includes/header.inc" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="de" xmlns="http://www.w3.org/1999/xhtml" xml:lang="de">
<head>
. . .
<?php include "/www/domain.de/meine-includes/header.inc" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="de" xmlns="http://www.w3.org/1999/xhtml" xml:lang="de">
<head>
<?php include "meta.inc" ?>
. . .
Includes sollen sich leicht von anderen PHP-Skripten unterscheiden
lassen: anhand der Dateiendung .inc
Das Einbinden eines Includes sähe dann so aus:
<?php include "meta.inc" ?>
Solche Textdateien kann einer Fremder durch Raten und Aufrufen eines passenden URLs im Browser einsehen. Dies soll verhindert werden.
Schließen Sie die Zugriffsmöglichkeit auf *.inc in der
Datei .htaccess aus. Tragen Sie dort folgenden Code an beliebiger
Position ein:
# Includes duerfen nicht per HTTP aufgerufen werden. <Files *.inc> order allow,deny deny from all </Files>
Hier geht es um ein PHP-Skript, ich nenne es auto-toc,
welches ein kurzes und ein vollständiges Inhaltsverzeichnisses
für ein einzelnes HTML-Dokument erzeugt.
Es macht viel Mühe solche Inhaltsverzeichnisse mit dokument-internen
Links basierend auf den h-Elementen bei umfangreichen Dokumenten
zu erstellen – von der Fehlerträchtigkeit einmal ganz zu schweigen.
class="quicktoc")
und ein vollständiges Inhaltsverzeichnis (class="fulltoc")
sind möglich.ul.h1 und h2 nicht
verwiesen: h1 trägt den Sitenamen, h2 den
Seitennamen.id als Zielankerid-Attribute genutzt. Besitzt
eine Überschrift keine id wird eine id nach
einem Buchstabe-Zahl-Muster erzeugt. h-Element werden
nicht angetastetDIVs eingeschlossen
sein, stört dies die Erzeugung des AutoTOC nicht.id für jeden Listenpunkt im Inhaltsverzeichnis#fulltoc-h-2-2 { display: none; } würde den Eintrag "Geheimrat
Dr. Oldenburg" im Beispieldokument ausblenden.Ich danke Stefan Fröhlich, der das Skript auf meine Anregung hin verfasst hat.
Dokument vor dem Parsen:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="de" xml:lang="de" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Pomologie | Gärtner Hans Eden</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
<body>
<h1>Gärtner Hans Eden</h1>
<h2>Pomologie</h2>
<p>Hier geht es um Apfelkunde.</p>
<?php include "autotoc.inc" ?>
<h3 id="bekannte-sorten">Bekannte Sorten</h3>
<h4 id="boskoop">Boskoop</h4>
<p>Der <em>Schöne von Boskoop</em> ist als Zufallssämling 1856 in Boskoop,
Niederlande, entdeckt worden.</p>
<h5>Züchter</h5>
<p>Rob van de Booskopp</p>
<h4 class="herkunft-usa">Golden Delicious</h4>
<p>Es handelt sich um eine sehr pflegeintensive Sorte.</p>
<h3>Wenig bekannte Sorten</h3>
<h4>Berlepsch</h4>
<p>Der Berlepsch oder auch <em>Goldrenette Freiherr von Berlepsch</em> ist
eine Sorte des Kulturapfels (Malus domestica).</p>
<h4>Geheimrat Dr. Oldenburg</h4>
<p><em>Geheimrat Oldenburg</em> ist eine Apfelsorte, die 1897 an der damaligen
Höheren Lehranstalt für Obstbau zu Geisenheim gezüchtet wurde.</p>
</body>
</html>
<?php
# Name: auto-toc
# Zweck: Erzeugen eines Inhaltsverzeichnisses für die jeweilige Seite
# Erstellungsjahr: 2004
# Zuletzt geaendert: November 2006
# Autor: Stefan Froehlich <Stefan@Froehlich.Priv.at>
# Idee: Andreas Borutta <http://borumat.de/kontakt>
function toc($string) {
# Globale Konfigurationsparameter pruefen und ggf. mit Standardwerten belegen
if (is_null($GLOBALS['show_quicktoc'])) $GLOBALS['show_quicktoc'] = true;
if (is_null($GLOBALS['show_fulltoc'])) $GLOBALS['show_fulltoc'] = true;
if (is_null($GLOBALS['toc_toplevel'])) $GLOBALS['toc_toplevel'] = 3; # ab h3
if (is_null($GLOBALS['toc_fulldepth'])) $GLOBALS['toc_fulldepth'] = 2; # 2 Ebenen, also hier h3 und h4
# Alle Ueberschriften der gesuchten Ebenen einfangen
preg_match_all(sprintf('#<h([%1$d-%2$d])\s*([^>]+)?>(.*?)</h[%1$d-%2$d]>#is', $GLOBALS['toc_toplevel'], $GLOBALS['toc_toplevel']+$GLOBALS['toc_fulldepth']-1), $string, $matches, PREG_OFFSET_CAPTURE);
$offset = 0;
if ($GLOBALS['show_quicktoc']) {
# Ueberschrift fuer das kurze Verzeichnis
# "\n" fuegt einen Zeilenumbruch ein
$output .= '<div class="quicktoc">Kurzes Inhaltsverzeichnis:' . "\n";
$output .= '<ul>' . "\n";
}
$level = array();
foreach ($matches[1] as $key => $value) {
# Fuer jede Ueberschrift Name und Level extrahieren
$temp['name'] = $matches[3][$key][0];
$temp['level'] = $matches[1][$key][0]-$GLOBALS['toc_toplevel'];
# Zaehler fuer die aktuelle Ebene erhoehen, fuer alle
# darunterliegenden Ebenen zuruecksetzen
$level[$temp['level']]++;
for ($i=$temp['level']+1; $i<=$GLOBALS['toc_fulldepth']; $i++) $level[$i] = 0;
# Hat das Tag eine zugewiesene Klasse, so wird diese uebernommen
if (($matches[2][$key][1] > 0) && preg_match('#id="([^"]+)"#', $matches[2][$key][0], $tags)) $tag = $tags[1];
else {
# Ist keine Klasse vorhanden, muss eine eindeutige Kennung erzeugt werden
$tag = 'h';
for ($i=0; $i<=$temp['level']; $i++) $tag .= '-' . $level[$i];
$temp['id'] = $tag;
$string = substr_replace($string, sprintf(' id="%s"', $tag), $matches[1][$key][1]+1+$offset, 0);
$offset += strlen($tag)+6;
}
$temp['id'] = $tag;
# Eintrag fuer das lange Verzeichnis abspeichern
$toc[] = $temp;
if ($GLOBALS['show_quicktoc'] && ($temp['level'] == 0)) {
# Wird ein kurzes Verzeichnis gewuenscht, koennen die
# Ueberschriften der obersten Ebene gleich ausgegeben werden
$output .= " <li id=\"quicktoc-" . $temp['id'] . "\"><a href=\"#";
if ($GLOBALS['show_fulltoc']) {
$output .= "fulltoc-";
}
$output .= $temp['id'];
$output .= '">' . $temp['name'] . '</a></li>' . "\n";
}
}
# Kurzes Verzeichnis abschliessen
if ($GLOBALS['show_quicktoc']) $output .= "</ul>\n</div>\n";
# Langes Verzeichnis ausgeben
if ($GLOBALS['show_fulltoc']) {
$output .= '<div class="fulltoc">Vollständiges Inhaltsverzeichnis:' . "\n";
$output .= '<ul>' . "\n";
$level = 0;
$first = true;
foreach ($toc as $line) {
while ($line['level'] > $level) {
$output .= str_repeat(' ', $level+1) . '<ul>' . "\n";
$level++;
$first = true;
}
while ($line['level'] < $level) {
$output .= ' ' . str_repeat(' ', $level) . '</li>' . "\n";
$output .= str_repeat(' ', $level) . '</ul>' . "\n";
$level–;
}
if ($first) $first = false;
else $output .= ' ' . str_repeat(' ', $level) . '</li>' . "\n";
$output .= ' ' . str_repeat(' ', $level) . '<li';
$output .= ' id="fulltoc-' . $line['id'] . '"';
$output .= '><a href="#' . $line['id'] . '">' . $line['name'] . '</a>' . "\n";
}
while (0 < $level) {
$output .= ' ' . str_repeat(' ', $level) . '</li>' . "\n";
$output .= str_repeat(' ', $level) . '</ul>' . "\n";
$level–;
}
$output .= ' ' . str_repeat(' ', $level) . '</li>' . "\n";
$output .= '</ul>' . "\n";
$output .= '</div>' . "\n";
}
$output .= $string;
return $output;
}
ob_start('toc');
?>
Alle Dateinamen des aktiven Verzeichnisses werden extrahiert und als Zielanker in einer Linkliste verwendet.
Ich danke Carsten Wiedmann für die Erstellung des Skriptes auf meine Anregung hin.
Einbinden des Skriptes directory-map.inc:
<body> <h1>Directory Map</h1> <?php include "directory-map.inc" ?> </body>
Quelltext des Skriptes directory-map.inc:
<?php
# Name: directory-map
# Zweck: Erzeugen einer Linkliste aus den Dateinnamen des aktiven Verzeichnisses
# Erstellungsjahr: 26.07.2004
# Autor: Carsten Wiedmann <info@wiedmann-online.de>
# Idee: Andreas Borutta <http://borumat.de/kontakt>
# extrahiert alle Dateinamen ab/des aktuellen Verzeichnisses und verwendet sie als Zielanker
# schreibt jeden Verweis in ein li-Element
# Beispiel:
# [css-vokabular.php]
# <html>. . .<h1>CSS Vokabular und Syntax</h1>
# Ergebnis:
# <ul>. . .<li><a href="css-vokabular">CSS Vokabular und Syntax</a></li>. . .</ul>
define('EXTENSION', 'php,html');
// '%ext%' = Dateien mit welcher Endungen, mit Kommas getrennt, sollen aufgelistet werden
// (z.B: define('EXTENSION', 'php,html'); )
// false = alle Dateien werden aufgelistet
define('EXCL_DATEI', false);
// '%Name%' = Dateien, mit Kommas getrennt, die immer aufgelistet werden sollen
// false = keine Ausnahmen
define('INCL_DATEI', false);
// '%Name%' = Dateien, mit Kommas getrennt, die nie aufgelistet werden sollen
// false = keine Ausnahmen
define('SUBDIR', true);
// true = Unterverzeichnisse werden mit aufgelistet
// false = Unterverzeichnisse werden nicht mit aufgelistet
define('SCHREIBMULTIVIEW', true);
// true = Links werden ohne Dateiendung geschrieben
// false = Links werden mit Dateiendung geschrieben
define('UTF8BOM', true);
// true = Prüfen ob die Datei wo der Linktext herkommt in UTF-8 kodiert ist.
// Wenn nein, konvertiert es den Linktext für die Ausgabe nach UTF-8
// Dies ist interessant, wenn es noch Dateien in z.B. ISO-8859-1 gibt
// und Umlaute vorkommen.
// false = schaltet diese Überprüfung aus
define('LINKSTIL', 'absolut');
// 'absolut'= Links werden ausgehend vom Root geschrieben
// z.B.: <a href="/pfad/datei.php"></a>
// 'relativ'= Links werden ausgehend vom aktuelle Verzeichnis geschrieben
// z.B.: <a href="datei.php"></a>
define('BASEURI', dirname($_SERVER['SCRIPT_NAME']));
// '%uri%/' = hier ermittelt das Script die Start-URI für die Links
define('WORKDIR', dirname($_SERVER['SCRIPT_FILENAME']));
// '%Pfad%' = hier ermittelt das Script das Startverzeichnis
// ab welchem es arbeiten
define('SCHREIBE_WORKDIR', false);
// true = Das Startverzeichnis taucht als erster Listenpunkt auf
// false = Das Startverzeichnis taucht nicht als erster Listenpunkt auf
function teste_utf8($teststring) {
if ((chr(0xEF).chr(0xBB).chr(0xBF) == substr($teststring, 0, 3))) {
return true;
} else {
for ($zeichen = 0; strlen($teststring) > $zeichen; $zeichen++) {
if (0x80 > ord(substr($teststring, $zeichen, 1))) {
$anz_oktett = 0;
} elseif (0xC0 == (ord(substr($teststring, $zeichen, 1)) & 0xE0)) {
$anz_oktett = 1;
} elseif (0xE0 == (ord(substr($teststring, $zeichen, 1)) & 0xF0)) {
$anz_oktett = 2;
} elseif (0xF0 == (ord(substr($teststring, $zeichen, 1)) & 0xF0)) {
$anz_oktett = 3;
} else {
return false;
}
for ($oktett = 0; $anz_oktett > $oktett; $oktett++) {
if ((strlen($teststring) == ++$zeichen)
|| (0x80 != (ord(substr($teststring, $zeichen , 1)) & 0xC0))) {
return false;
}
}
}
return true;
}
}
function lese_verzeichnisse($verzeichnis) {
$excl_datei = array();
$excl_datei = explode(',', EXCL_DATEI);
$incl_datei = array();
$incl_datei = explode(',', INCL_DATEI);
if ((false !== is_dir($verzeichnis)) && ($dir = @opendir($verzeichnis))) {
while (false !== ($datei = readdir($dir))) {
if (SUBDIR && is_dir($verzeichnis.DIRECTORY_SEPARATOR.$datei)
&& ('.' != $datei) && ('..' != $datei)) {
if ($datei = lese_verzeichnisse($verzeichnis.DIRECTORY_SEPARATOR.$datei)) {
$verzeichnisliste[] = $datei;
}
} elseif (!is_dir($datei) && !in_array($datei, $excl_datei)) {
if (in_array($datei, $incl_datei)) {
$datei = $verzeichnis.DIRECTORY_SEPARATOR.$datei;
} else {
$datei = $verzeichnis.DIRECTORY_SEPARATOR.$datei;
if (false !== EXTENSION) {
$pruef_datei = pathinfo($datei);
if (array_key_exists('extension', $pruef_datei)) {
$extension = explode(',', EXTENSION);
} else {
$pruef_datei['extension'] = '';
}
foreach ($extension as $ext) {
if ($pruef_datei['extension'] == trim($ext)) {
$ext = true;
break;
}
}
if (true !== $ext) {
continue;
}
}
}
$verzeichnisliste[] = $datei;
} else {
$verzeichnisliste[] = $verzeichnis;
}
}
}
closedir($dir);
if (isset($verzeichnisliste)) {
asort($verzeichnisliste);
$verzeichnisliste = array_values($verzeichnisliste);
return $verzeichnisliste;
}
}
function hole_titel($datei) {
if (false !== ($dateiinhalt = @file_get_contents($datei))) {
$anfang = strpos(strtolower($dateiinhalt), '<'.'h1');
$ende = strpos(strtolower($dateiinhalt), '</'.'h1'.'>', $anfang);
$titel = strip_tags(substr($dateiinhalt, $anfang, $ende - $anfang));
$titel = str_replace(array("\r", "\n", "\t"), ' ', $titel);
$wort = strtok ($titel, ' ');
$titel = '';
while ($wort) {
$titel .= ' '.$wort;
$wort = strtok(' ');
}
$titel = trim($titel);
if ((false !== $anfang) && (false !== $ende) && (false != $titel)) {
return $titel;
} else {
return '<'.basename($datei).'> : kein Titel';
}
} else {
return '<'.basename($datei).'> : Dateifehler';
}
}
function schreibe_liste($verzeichnisliste = '', $durchlauf = 0) {
flush();
$baseuri = strtr(BASEURI, DIRECTORY_SEPARATOR, '/').'/';
if ('//' == substr($baseuri, 0, 2)) {
$baseuri = substr($baseuri, 1);
}
if (0 == $durchlauf) {
$verzeichnisliste = lese_verzeichnisse(WORKDIR);
echo "\n";
if (SCHREIBE_WORKDIR) {
if ('' == ($verzeichnis = substr($baseuri, 0, -1))) {
$verzeichnis = '/';
}
echo '<ul>'."\n";
echo str_repeat(' ', $durchlauf + 1).'<li>'.$verzeichnis."\n";
}
}
if (is_array($verzeichnisliste)) {
if (array_key_exists(2, $verzeichnisliste)) {
echo str_repeat(' ', $durchlauf + 2).'<ul>'."\n";
}
foreach ($verzeichnisliste as $nr => $datei) {
if (is_array($datei)) {
$verzeichnis = reset($datei);
if (!is_array($verzeichnis) && !is_dir($verzeichnis)) {
$verzeichnis = pathinfo($verzeichnis);
$verzeichnis = $verzeichnis['dirname'];
}
$verzeichnis = strtr($verzeichnis, DIRECTORY_SEPARATOR, '/');
$verzeichnis = substr($verzeichnis, strlen(WORKDIR) + 1);
if (false !== ($start = strrpos($verzeichnis, '/'))) {
$verzeichnis = substr($verzeichnis, $start + 1);
}
echo str_repeat(' ', $durchlauf + 3).'<li>'.$verzeichnis."\n";
schreibe_liste($datei, $durchlauf + 2);
echo str_repeat(' ', $durchlauf + 3).'</li>'."\n";
} elseif (!is_dir($datei)) {
$linktext = hole_titel($datei);
if (UTF8BOM && !teste_utf8($linktext)) {
$linktext = utf8_encode($linktext);
}
$datei = pathinfo($datei);
if (SCHREIBMULTIVIEW && array_key_exists('extension', $datei)) {
$datei = $datei['dirname'].DIRECTORY_SEPARATOR
.substr(basename($datei['basename'], $datei['extension']), 0 , -1);
} else {
$datei = $datei['dirname'].DIRECTORY_SEPARATOR.$datei['basename'];
}
$datei = substr($datei, strlen(WORKDIR) + 1);
$datei = strtr($datei, DIRECTORY_SEPARATOR, '/');
if ('absolut' == LINKSTIL) {
$datei = rawurlencode($baseuri.$datei);
} else {
$datei = rawurlencode($datei);
}
$datei = strtr($datei, array('%2F' => '/'));
echo str_repeat(' ', $durchlauf + 3)
.'<li><a href="'.$datei.'">'.$linktext.'</a></li>'."\n";
}
}
if (array_key_exists(2, $verzeichnisliste)) {
echo str_repeat(' ', $durchlauf + 2).'</ul>'."\n";
}
}
if (0 == $durchlauf) {
if (SCHREIBE_WORKDIR) {
echo str_repeat(' ', $durchlauf + 1).'</li>'."\n";
echo '</ul>'."\n";
}
}
}
schreibe_liste();
?>
Ausgeben des Datums der letzten Speicherung der Datei.
Einbinden des Skriptes lastmodified.inc:
. . . <body> <?php include "last-modified.inc" ?> <h1>. . .</h1> . . .
Quelltext des Skriptes lastmodified.inc:
<p class="aend">Zuletzt geändert am
<?php
$unixTime = filemtime($_SERVER["PATH_TRANSLATED"]);
if ($unixTime) {
$speicherdatum = date("d.m.Y", $unixTime);
$speicherzeit = date("H:i", $unixTime);
}
echo $speicherdatum;
?>
</p>
Manche HTML-Editoren (Beispiel Dreamweaver) können keine kanonischen Links erzeugen. Wenn der Autor sie händisch erzeugt, versagt ihr Sitemanagement.
Daher soll die Kanonizität beim Ausliefern gewährleistet werden.
| Vorher | Nacher |
|---|---|
| Normale Dateien | |
<href="/foo.php"> |
<href="/foo"> |
<href="/bar/foo.php"> |
<href="/bar/foo"> |
| Directory Index | |
<href="/index.php"> |
<href="/"> |
<href="/bar/index.php"> |
<href="/bar/"> |
Das Skript soll mit diversen Sonderfällen klarkommen:
| Sonderfall | Kommentar |
|---|---|
<a href="/bar/foo.php#zot"> |
Fragmentidentifikator |
<href = "/bar/foo.php"> |
Leerzeichen vor und nach dem Gleichheitszeichen |
<a href="/bar/foo.php" class="lorem"> |
Mit Attribut nach href |
<a class="ipsum" href="/bar/foo.php"> |
Mit Attribut vor href |
<a href="/bar/foo.php?a=zot"> |
Mit Query-Part |
<a href = "/bar/foo.php"> |
Mit Leerzeichen vor und nach dem Gleichheitszeichen hinter dem Attribut href |
<form action="/bar/foo.php" method="get"> |
Referenz steht im Attribut action im Element form |
<a Href="/bar/foo.php"> |
Majuskel im Attribut href |
<A href="/bar/foo.php"> |
Majuskel im Element |
<a href="./foo.php"> |
dokument-relative Referenzierung |
<a href="/bar/foo.htm"> |
Endung .htm |
<a href="/bar/foo.html"> |
Endung .html |
Ich danke Carsten Wiedmann und Michael Fesser, die dieses Skript auf meine Anregung hin verfasst haben.
Einbinden des Skriptes canonical-references.inc:
Fügen Sie das Include irgendwo im Kopf ihrer Datei an
. . . <?php include "canonical-references.inc"; ?> </head> . . .
Quelltext des Skriptes canonical-references.inc:
<?php
# Name: canonical-references
# Zweck: Umwandlung von nicht-kanonischen siteinternen Referenzen in kanonische
# Autoren: Carsten Wiedmann <info@wiedmann-online.de> und Michael Fesser <netizen@gmx.de>
# Ergaenzungen von: Stefan Froehlich <Stefan@Froehlich.Priv.at>
# Idee: Andreas Borutta <http://borumat.de/kontakt>
# Erstellungsjahr: Februar 2007
function callback($buffer) {
$pattern = '%
( # Beginn Subpattern $1
< # Beginn Tag
(?:a|form)\s # Elementname
[^>]* # beliebige Attribute
(?:href|action)\s*=\s* # Zielattribut
["\'] # Attributbegrenzer
(?<!http|https).*? # Beginn Attributwert, nur interne URIs
) # Ende Subpattern $1
(?:index)? # optionaler Default-Name
\.(?:php|[psx]?html?) # Dateiendung
( # Beginn Subpattern $2
(?:[\?#][^>]*)? # optionaler Query-String und/oder FI
["\'] # Attributbegrenzer
[^>]* # beliebige weitere Attribute
> # Ende Tag
) # Ende Subpattern $2
%ix';
return preg_replace($pattern, '$1$2', $buffer);
}
ob_start('callback');
?>
Zur Gewährleistung von kanonischen
Links bei der Rückgabe durch den Server existiert ein fertiger
Anweisungsblock für die Steuerdatei .htaccess. Vielleicht
ist dies ebenfalls interessant für Sie?
Eintragen des Datums der letzten Speicherung eines Linkzieles.
Ich danke Thomas Scholz, der dieses Skript auf meine Anregung hin erstellt hat.
Einbinden des Skriptes lastmodified-href.inc:
$href an
(fett hinterlegten Teil. . . <body> <p><a href="/lorem/ipsum.php">Lorem</a> ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. <?php $href="/lorem/ipsum.php"; include "last-modified-href.inc"; ?> </p> . . .
Quelltext des Skriptes lastmodified-href.inc:
<br /><span class="lastmod">Zuletzt geändert am:
<?php
# Name: lastmodified-href
# Zweck: Aenderungsdatum der Zieldatei eines Links ausgeben
# Erstellungsjahr: 2004
# Autor: Thomas Scholz <http://toscho.de/>
# Idee: Andreas Borutta <http://borumat.de/kontakt>
# Fügt das Datum der letzten Änderung derjenigen Datei ein,
# die in der Variable $href vor dem Include angegeben wird.
# Das Datum wird genau an der Position eingefügt,
# wo sich das Include befindet.
# Beispiel für das Einbinden:
# <?php
# $href="/lorem/ipsum.php";
# include "last-modified-href.inc";
# ?>
if ($href != rtrim($href, '/')) { // Für URLs, die auf '/' enden.
$href .= 'index.php';
}
$speicherdatumhref = filemtime(rtrim($_SERVER['DOCUMENT_ROOT'], '/')
. '/' . $href);
echo date("d.m.Y", $speicherdatumhref);
return;
?>
</span>
title-Element mit dem Inhalt der ersten h1-Überschrift
füllenMeist ist die erste h1-Überschrift auch ein vernünftiger title.
Das Skript auto-title füllt das title-Element
mit dem Inhalt der ersten h1. Besonders nach Änderungen
am h1 wird leicht das dan ebenfalls nötige Ändern des title vergessen.
Details der Funktionsweise stehen im Kopf des Skriptes.
Ich danke Stefan Fröhlich für die Erstellung des Skriptes auf meine Anregung hin.
Einbinden des Skriptes auto-title.inc:
. . . <title> <?php include "auto-title.inc" ?> </title> . . .
Quelltext des Skriptes auto-title.inc:
<?php
# Name: auto-title
# Zweck: title-Element mit dem Inhalt des ersten H1 fuellen
# Erstellungsjahr: 2004
# Autor: Stefan Froehlich <Stefan@Froehlich.Priv.at>
# Idee: Andreas Borutta <http://borumat.de/kontakt>
# Liest den Inhalt des ersten H1 aus
# Entfernt im Ausgelesenen alle weiteren Tags (z.B. die
# Tags von Inline-Elementen oder BRs), entfernt kein Linefeed
# Geben Siet Inhalt aus
# Wenn statt des ersten H1 das erste H2 ausgelesen werden soll,
# ersetze in Zeile 2 "h1" im Starttag und im Endtag
$handle = fopen($_SERVER["SCRIPT_FILENAME"],"r");
preg_match("#<h1>([^(].*)</h1>#isU",fread($handle,filesize($_SERVER["SCRIPT_FILENAME"])),$match);
echo preg_replace("#<[^>]+>#","",preg_replace("#<br\s*/?>#i"," ",$match[1]));
?>
| deine-domain.de
Ausgeben der URL der aktuellen Seite. Dies ist z.B. für den Ausdruck nützlich.
Ich danke Adam Schmalhofer, der das Skript auf meine Anregung hin verfasst hat.
url.inc:
<?php
# Gibt den URL der aktuellen Seite aus.
$url = $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
printf('<p class="url">URL dieser Seite: http://%s</p>', $url);
?>
foo.php vor dem Parsen:
. . . <?php include "url.inc" ?> . . .
Für das Beispiel befinden wir uns auf http://example.tld/foo/
foo.php nach dem Parsen:
. . .
<p class="url">URL dieser Seite: http://exammple.tld/foo/</p>
. . .
Um für Thumbnailübersichten für Bildergalerien eine flüssige Anordnung
zu realisieren, bieten sich div an.
Damit alle Boxen in einem gleichmäßigen Raster angeordnet sind, müssen
sie ein festes Maß erhalten. Dafür muss der Autor die größte aller Bildhöhen
und -breiten ermitteln. Diese mühsame Aufgabe soll das Skript grid-size.inc erledigen.
Details zur Funktionsweise stehen im Kopf des Skriptes.
Ich danke Michael Praast für die Erstellung des Skriptes auf meine Anregung hin.
Einbinden des Skriptes grid-size.inc:
. . . <?php include "grid-size.inc" ?> </head> . . .
Quelltext des Skriptes grid-size.inc:
<?php
# Name: grid-size
# Zweck: Gittermass fuer Bildergalerieuebersichten ausgeben
# Erstellungsjahr: 14.11.2005
# Autor: Michael Praast <http://www.praast.de/>
# Idee: Andreas Borutta <http://borumat.de/kontakt>
# Beschreibung:
# Das Skript dient der Gestaltung von Thumbnailseiten fuer Bildergalerien
# in einer "fluessigen" Anordnung, also einer Gestaltung, die sich der Fensterbreite anpasst.
# Dafuer ist ein Rastermass in festen Breiten anzugeben. Das Skript ermittelt
# die Rastermasse automatisch aus den Bildgroessen. Es gibt das Mass als
# interne Stilregel aus.
# Beispiel:
# <style type="text/css">
# div.galeriethumbs div{ width: 210px; height: 210px;}
# </style>
# Das Skript wird als Include eingebunden.
# Die Stilregel wird an der Stelle ausgegeben, wo sich das Include befindet.
# Der Autor kann beliebige Struktur in seinem HTML-Code nutzen.
# Vorraussetzungen:
# Die Bildgroessen muessen in den Attributen width und height angegeben sein.
# Die Seite sollte keine weiteren Bilder enthalten als die Thumbnails, wenn diese groesser
# sind als die Thumbnails, denn das Skript liest alle Bilder aus und zieht deren Groessen
# zur Ermittlung des Rastermasses heran.
# Optionen:
# Es gibt drei Variablen zum Steuern der Wirkungsweise des Skriptes:
#
# 1 Extra-Weite und -Hoehe in px um die maximalen Kantenlaengen der Bilder herum
# Beispiel: $extrawidthheight = "30";
#
# 2 Seitenverhaeltnisse des Rasters
# true: Rastermass ist zwingend quadratisch
# false: Seitenverhaeltnis des Rasters ergibt sich aus den Bildmassen
# Beispiel: $square = true;
#
# 3 CSS-Selector der im interen Stylesheet angewendet wird
# Dieser muss je nach verwendeter HTML-Struktur angepasst werden.
# Beispiel: $selector = "div.galeriethumbs div";
# fuer eine Struktur wie:
# <div class="galeriethumbs">
# <div><a . . .><img . . . /></a></div>
# <div><a . . .><img . . . /></a></div>
# . . .
# </div>
#
# Beispiel: $selector = "div.galeriethumbs table";
# fuer eine Struktur wie:
# <div class="galeriethumbs">
# <table><tr><td><a . . .><img . . . /></a></td></tr></table>
# <table><tr><td><a . . .><img . . . /></a></td></tr></table>
# . . .
# </div>
$extrawidthheight = "30";
$square = true;
$selector = "div.galeriethumbs div, div.galeriethumbs table";
##########Don't touch!#########
// von welcher Datei werde ich aufgerufen?
$vonwo = $_SERVER['SCRIPT_FILENAME'];
// aufrufende Datei einlesen
$datei = file_get_contents($vonwo);
$start = "<img";
$ende = "/>";
// Filtere die IMGs heraus, Ablage in Array $printing
preg_match_all ( '#'.$start.'.*'.$ende.'#', $datei, $printing);
$anzahl = count($printing[0]);
$i = 0;
$Hmax=0;
$Bmax=0;
while ($i < $anzahl)
{
// Arrayfeld -> String
$temp = $printing[0][$i];
// Werte suchen
preg_match('/height=".*"/siU',$temp,$hoehe);
preg_match('/width=".*"/siU',$temp,$weite);
// Arraywert -> String
$hoehe = $hoehe[0];
$weite = $weite[0];
// extrahieren der Pixelangaben
$weite = eregi_replace( 'width="', "", $weite);
$weite = eregi_replace( '"', "", $weite);
$hoehe = eregi_replace( 'height="', "", $hoehe);
$hoehe = eregi_replace( '"', "", $hoehe);
// sind die aktuellen Werte groeszer als die bisherigen?
if ($hoehe > $Hmax) {$Hmax = $hoehe;}
if ($weite > $Bmax) {$Bmax = $weite;}
$i++;
}
// CSS setzen
$style ="<style type=\"text/css\">\n";
if ($square == true)
{
// quadratische Version gewuenscht
if ($Bmax < $Hmax)
{
$HBmax = $Hmax;
}
else
{
$HBmax = $Bmax;
}
$HBmax = $HBmax+$extrawidthheight;
$style .= "$selector{ width: ".$HBmax."px; height: ".$HBmax."px;".$raster_css."}\n";
}
else
{
// nicht quadratisch
$Bmax= $Bmax+$extrawidthheight;
$Hmax= $Hmax+$extrawidthheight;
$style .= "$selector{ width: ".$Bmax."px; height: ".$Hmax."px;".$raster_css."}\n";
}
$style.="</style>\n";
// CSS-Ausgabe
echo $style;
?>
Hier beschreibe ich Aufgaben, für die ich ein Skript suche.
Warum "Site-Navigation" und nicht "Navigation"? Um die Site-Navigation abzugrenzen von dem Inhaltsverzeichnis für eine einzelne Seite.
Die Datei sitemap-data.php enthält alle nötigen Verweise
zur Erzeugung der Sitemap (als Dokument) und des Navigationsbereiches
auf jeder anderen Seite. Sie kann einen oder mehrere Navigationsbereiche
enthalten. Zum Beispiel:
<ul id="service-nav-liste"><ul id="haupt-nav-liste">Dem Bereich Service-Navigation werden Links zugeordnet, die auf jeder beliebigen Site enthalten sein sollten: Startseite, Sitemap, Kontakt
Die sitemap-data.php pflegt der Autor manuell.
Das Skript zeigt aus der Gesamtmenge der beiden Navigationsbereiche auf jeder Seite eine Teilmenge. Am Beispiel wird das Ziel klarer:
<body> <h1>Magna</h1> . . . <?php $list_id = "service-nav-liste"; include "nav.inc"; ?> . . . <?php $list_id = "haupt-nav-liste"; include "nav.inc"; ?> . . . </body>
ULs mit id="service-nav-liste" und id="haupt-nav-liste" der
Datei sitemap.php.ulula, li , …/index.php oder "/"index.php stets
heraus.code a muss sich nicht das ganze li erstreckenstrong ausgezeichnet. Seine
Eltern- und Großelternelemente in der Navigationsliste werden mit em ausgezeichnet.
So ist sowohl der "Pfad" zum aktuellen Punkt als auch der Punkt selbst
mit passendem Markup versehen.Die Navigationsleiste nimmt stets genau diejenige Breite in der Einheit ex ein,
dass der längste Listenpunkt aus der (verschachtelten) Navigation nicht
umbrochen wird.
Wenn der Autor neue Listenpunkte hinzufügt oder entfernt oder er die Verschachtelung ändert, muss er nichts manuell an der Stilregel für die Navigationsleiste ändern.
Das Skript, nennen wir es nav-auto-width, errechnet automatisch
den passenden Wert für die Breite und fügt ihn dynamisch als internes
Stylesheet im Kopf der Seite hinzu.
Am Beispiel wird es klarer:
<?php include="nav-auto-width.inc"; $padding = 1ex; $supplement = 2ex; ?> <ul class="nav"> <li><a . . .>Lorem ipsum</a></li> <li><a . . .>Veniam <ul> <li><a . . .>Dolor</a></li> <li><a . . .>Consectetu sitr</a></li> </ul> </li> <li><a . . .>Nostrud</a></li> </ul>
. . .
.nav ul{ padding: 0; margin: 0; }
.nav li{ list-style-type: none; padding: 0; margin: 0; }
.nav li li, .nav li li li{ padding-left: 1ex; }
. . .
. . . <link rel="stylesheet" href="/css/screen.css" type="text/css" media="screen" /> <link rel="stylesheet" href="/css/print.css" type="text/css" media="print" /> </head> <body> <h1>Dolor</h1> <?php include "nav.inc" ?> . . .
. . .
<link rel="stylesheet" href="/css/screen.css" type="text/css" media="screen" />
<link rel="stylesheet" href="/css/print.css" type="text/css" media="print" />
<style type="text/css" media="screen"> .nav{ width: 18ex; } </style>
</head>
<body>
<h1>Dolor</h1>
<ul class="nav">
<li><a . . .>Lorem ipsum</a></li>
<li><a . . .>Veniam
<ul>
<li><strong>Dolor</strong></li>
<li><a . . .>Consectetur sit</a></li>
</ul>
</li>
<li><a . . .>Nostrud</a></li>
</ul>
. . .
li bzw.
von einem a innerhalb eines li wird ermittelt
und daraus ein Betrag berechnet1ex2exli aus ul class="nav" ist Consectetur
sit und hat 15 Zeichen und befindet sich der Ebene 2ul class="nav" ist: 18ex<style type="text/css" media="screen"> .nav{ width: 18ex;
} </style>Es geht um eine kleine Variation des oben vorgestellten Skriptes zum
Füllen des Elementes title:
Es liest das erste h1 aus.
Nützlich wäre es, wenn man man ein per ID eindeutig benennbares Element
wählen könnte. Zum Beispiel <h2 id="content">…</h2>
Manche Seiten stehen in einer bestimmten Reihenfolge, zum Beispiel
in Artikeln von Magazinen. Im Element link lässt sich diese
Reihenfolge angeben. Manche Benutzerprogramme können dann mit einer Funktion Nächstes bzw. Vorheriges zu
den Artikel navigieren.
Für das Beispiel nehmen wir folgende Reihenfolge von Artikeln an:
/08//08/familien-pino//08/saeuglingstransport//08/babybiker//08/familie-ohne-auto/Der Artikel Babybiker sei geöffnet. Hinter dem /08/ liegt
der erste Artikel, das Editorial.
. . . <?php include "first-prev-next.inc" ?> </head> . . . <div class="nav"> <ol>
<li><a href="/08/">Editorial</a></li>
<li><a href="/08/familien-pino/">Familien-Pino</a></li>
<li><a href="/08/saeuglingstransport/">Säuglingstransport</a></li>
<li class="active>Babybiker</li>
<li><a href="/08/familie-ohne-auto/">Familie ohne Auto</a></li>
</ol> </div> . . .
. . .
<link rel="first" title="Editorial" href="/08/" />
<link rel="prev" title="Säuglingstransport" href="/08/saeuglingstransport/" />
<link rel="next" title="Familie ohne Auto" href="/08/familie-ohne-auto/" />
</head>
. . .
Beim Ausdruck geht das Linkziel verloren. Zwar kann man per CSS den URL als "generated content" ausgeben, aber das wird zum Einen nur von wenigen Browsern unterstützt und zum Anderen stören URLs direkt im Text die Lesbarkeit.
Besser ist ein Einfügen eines Verweiszeichens als fortlaufende Nummer und das Ausgeben einer Linkziel-Liste am Dokumentende.
Weitere Merkmale:
. . .
<style type="text/css" media="screen">
span.linknummer, div.linkziele { position: absolute; left: -1000px; top: -1000px; width: 0; max-height: 0; overflow: hidden; display: inline; }
</style>
<style type="text/css" media="print">
/* Nicht als Link zeigen*/ a.fnz { text-decoration: none; color: black; }
/* Nicht zeigen*/ ul.navi { display: none; }
</style>
<?php include "linkziele.inc" ?>
</head>
. . .
<ul class="navi">
<li><a href="/seite-1/">Navi 1</a></li>
<li><a href="/seite-2/">Navi 2</a></li>
</ul>
. . .
<p>Lorem <a href="http://ipsum.de">ipsum</a> doloret.</p>
<p>Adipisit <a href="#sed">sed</a> consectutur.</p>
<p>Persitia <a href="../bar/vubir">vubir</a> olukat.</p>
<p>Ut enim <a class="fnz" href="#fn-1">[1]</a> minimim.</p>
<p>Laboris nisi<a class="fnz" href="#fn-2">[2]</a> ullamcor.</p>
<p>Sed do <a href="http://eiusmod.de/?a=b&c=d">eiusmod</a> tempor.</p>
<p>Kafitet <a href="#sed">sed</a> hesaltum.</p>
. . .
<div class="fussnoten">
<h4 id="fussnoten">Fußnoten</h4>
<ol>
<li id="fn-1">Enim quis iomur verdita.</li>
<li id="fn-2">Taride e fuzio mostamur.</li>
</ol>
</div>
. . . <ul class="navi">
<li><a href="/seite-1/">Navi 1</a></li>
<li><a href="/seite-2/">Navi 2</a></li>
</ul> . . . <p>Lorem <a href="http://ipsum.de">ipsum <span class="linknummer">{1}</span></a> doloret.</p>
<p>Adipisit <a href="#sed">sed <span class="linknummer">{2}</span></a> consectutur.</p>
<p>Persitia <a href="../bar/vubir">vubir <span class="linknummer">{3}</span></a> olukat.</p> <p>Ut enim <a class="fnz" href="#fn-1">[1]</a> minimim.</p>
<p>Laboris nisi<a class="fnz" href="#fn-2">[2]</a> ullamcor.</p>
<p>Sed do <a href="http://eiusmod.de/?a=b&c=d">eiusmod <span class="linknummer">{4}</span></a> tempor.</p> <p>Kafitet <a href="#sed">sed <span class="linknummer">{2}</span></a> hesaltum.</p> . . . <div class="fussnoten">
<h4 id="fussnoten">Fußnoten</h4>
<ol>
<li id="fn-1">Enim quis iomur verdita.</li>
<li id="fn-2">Taride e fuzio mostamur.</li>
</ol>
</div> . . . <div class="linkziele"> <h4 id="linkziele">Linkziele</h4> <ol> <li>http://ipsum.de</li> <li>http://meine-domain.de/foo/#sed</li> <li>http://meine-domain.de/bar/vubir</li> <li>http://eiusmod.de/?a=b&c=d</li> </ol> </div> </html>
Für das Vorstellen von Beispielen von Quellcode wäre ein Skript hilfreich,
das die jeweiligen Start- und Endtags mit span-Containern
umhüllt, damit passende Selektoren gebildet werden können.
<pre> <h1>Lorem ipsum</h1> <p>Dolor sit <strong>amet </strong>, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut <a href="document.html">labore</a> et dolore magna aliqua.</p> </pre>
<pre> <span class="sh-bl"><h1></span>Lorem ipsum<span class="sh-bl"></h1></span> <span class="sh-bl"><p></span>Dolor sit <span class="sh-in"><strong></span>amet <span class="sh-in"></strong></span>, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut <span class="sh-a"><a href="document.html"></span>labore<span class="sh-a"></a></span> et dolore magna aliqua.<span class="sh-block"></p></span> </pre>
.sh-in{
color: green;
font-weight: bold;
}
.sh-bl{
color: blue;
font-weight: bold;
}
.sh-a{
color: #CC0099;
font-weight: bold;
}
<h1>Lorem ipsum</h1> <p>Dolor sit <strong>amet </strong>, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut <a href="document.html">labore</a> et dolore magna aliqua.</p>
<h1>Lorem ipsum</h1> <p>Dolor sit <strong>amet </strong>, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut <a href="document.html">labore</a> et dolore magna aliqua.</p>
Die Lesbarkeit von Datentabellen verbessert sich, wenn jede zweite Zeile einer Tabelle eine andere Hintergrundfarbe erhält.
Das Skript, nennen wir es alternating-row-classes.inc fügt
in table mit class="alt-row" den entsprechenden tr ein class="even" hinzu.
So kann der Autor über das zentrale Stylesheet die Hintergrundfarben
gestalten.
Am Beispiel wird dies klarer:
. . .
td { background: . . .; }
.even td { background: . . .; }
th { background: . . .; }
.even th { background: . . .; }
. . .
. . . <?php include="alternating-row-classes.inc" ?> . . . <body> . . . <table class="foo alt-row"> <tr> <th>Lorem</th><td>Ipsum</td> </tr> <tr class="bar"> <th>Dolor</th><td>Sit</td> </tr> <tr> <th>Amet</th><td>Consectetur</td> </tr> <tr> <th>Adipisicing</th><td>Elit</td> </tr> </table> <table class="alt-row zot"> <tr> <th>Lorem</th><th>Ipsum</th> </tr> <tr> <td>Dolor</td><td>Sit</td> </tr> <tr> <td>Amet</td><td>Consectetur</td> </tr> <tr> <td>Adipisicing</td><td>Elit</td> </tr> </table> <table class="alt-row"> <tr> <th></th><th>Ipsum</th><th>Sed</th> </tr> <tr> <th>Dolor</th><td>Sit</td><td>Do</td> </tr> <tr> <th>Amet</th><td>Consectetur</td><td>Eiusmod</td> </tr> <tr> <th>Adipisicing</th><td>Elit</td><td>Tempor</td> </tr> </table> . . . </body> </html>
. . . <body> . . . <table class="foo alt-row"> <tr> <th>Lorem</th><td>Ipsum</td> </tr> <tr class="even bar"> <th>Dolor</th><td>Sit</td> </tr> <tr> <th>Amet</th><td>Consectetur</td> </tr> <tr class="even"> <th>Adipisicing</th><td>Elit</td> </tr> </table> <table class="alt-row zot"> <tr> <th>Lorem</th><th>Ipsum</th> </tr> <tr class="even"> <td>Dolor</td><td>Sit</td> </tr> <tr> <td>Amet</td><td>Consectetur</td> </tr> <tr class="even"> <td>Adipisicing</td><td>Elit</td> </tr> </table> <table class="alt-row"> <tr> <th></th><th>Ipsum</th><th>Sed</th> </tr> <tr class="even"> <th>Dolor</th><td>Sit</td><td>Do</td> </tr> <tr> <th>Amet</th><td>Consectetur</td><td>Eiusmod</td> </tr> <tr class="even"> <th>Adipisicing</th><td>Elit</td><td>Tempor</td> </tr> </table> . . . </body> </html>
class-Attribut nicht nur den Wert alt-row enthält:<table class="foo alt-row">
<table class="alt-row zot">tr und
fügt den Wert even hinzu:<tr class="bar">
<tr class="even bar">Für komplexere Tabellen, die mit thead, tbodyund tfoot ausgezeichnet
sind und wo die Attribute scope="row" oder scop="col" gesetzt sind, folgt
hier vielleicht später einmal eine Skizze. Aber schon einen Farbfächer
zu entwerfen, der derart viele Farben enthält und dennoch bei allen denkbaren
Paarungen aus Vorder- und Hintergrundfarbe hinreichenden Kontrast gewährleisten
kann, ist anspruchsvoll. Über Hinweise zu
Beispielseiten zu diesem Thema freue ich mich.