Welcome, Guest. Please login or register.
Did you miss your activation email?
May 24, 2012, 10:28:48 AM

Login with username, password and session length
Search:     Advanced search
Interested in joining the WebsiteBaker team?
For more Information read here or on our new website.
155446 Posts in 21703 Topics by 7731 Members
Latest Member: zvaigzdzius
* Home Help Search Login Register
Pages: [1]   Go Down
Print
Author Topic: Automatisch Links auf Wörter setzen?  (Read 2528 times)
Katerchen

Offline Offline

Posts: 84


« on: November 01, 2008, 05:54:40 PM »

Hallo!

Hat jemand eine Idee, wie man mittels WB (halb-) automatisch Links auf Wörter, die in einer Webseite auftauchen setzen kann? Z.B. so:

Der Bauer verkauft Äpfel und Karotten. Beim Wort "Äpfel" soll ein Link auf obst.html gesetzt werden, bei "Karotten" ein Link auf gemuese.html, und das bei allen Vorkommen dieser Begriffe auf allen Seiten (oder zumindest allen Vorkommen, die auf irgendeine Weise markiert sind). Die Idee dabei ist natürlich, daß nicht sämtliche Links manuell geändert werden müssen, wenn sich die URL ändert.

Die Zuordnung von "Äpfel" zu obst.html wird wohl am besten in einer Datenbanktabelle definiert sein, aber wie kriege ich den Automatismus hin? Hat da jemand eine Idee?
« Last Edit: November 01, 2008, 06:26:00 PM by Katerchen » Logged
Stefek
WebsiteBaker Org e.V.

Offline Offline

Posts: 4884



« Reply #1 on: November 01, 2008, 06:05:13 PM »

Hallo, so eine "vollautomatische" Lösung gibts zwar nicht, aber wenn Du den FCK Editor benutzt, kannst Du ganz einfach Links zu Seiten setzen. Da gibt es so ein Icon mit einem Link und dem WB Hut.
Wenn Di den benutzt, kannst Du aus einer Liste von Seiten eine auswählen.

Das gute daran: Auch wenn Du die URL dieser Seite änderst (was man eigentlich lieber nicht machen sollte), wird der Link weiterhin zu der Seite vorhanden bleiben. Es wird nämlich hierbei die WB interne page_id benutzt.

Probier das mal aus.

MfG,
Stefek
Logged

"In a time of universal deceit, telling the truth becomes a revolutionary act."
- George Orwell, Nineteen eighty-four (1984)
Katerchen

Offline Offline

Posts: 84


« Reply #2 on: November 01, 2008, 06:28:40 PM »

Leider geht es um Links auf Seiten außerhalb dieser WB-Installation, dieses Verfahren dürfte damit nicht funktionieren. Ich dachte eher an irgendeine Art von Auszeichnung der zu verlinkenden Wörter, die dann automatisch in Links umgewandelt werden - geht sowas überhaupt?
Logged
thorn

Offline Offline

Posts: 980


WWW
« Reply #3 on: November 01, 2008, 07:12:46 PM »

Hallo,

im Grunde macht der Frontend Output Filter genau so etwas mit E-Mail-Adressen.
Die fertige Seite wird durch einen Filter geschickt, in dem - in diesem Fall - E-Mail-Adressen verändert werden.
Daraus könnte man ein Modul entwickeln, das bestimmte Wörter um Links erweitert.

Wenn du gut mit PHP umgehen kannst, sieh dir den Frontend Output Filter als Grundlage an.

thorn.
Logged

Katerchen

Offline Offline

Posts: 84


« Reply #4 on: November 01, 2008, 09:21:53 PM »

Mit PHP kann ich ein wenig umgehen, wenn auch lange nicht perfekt - ich gucke mir das Modul mal genauer an, vielleicht kann ich ja was daraus machen. Am liebsten wäre mir was "Wiki-mäßiges", in der Art, daß ich (oder ein Bearbeiter, der kaum HTML-Kenntnisse besitzt) im WYSIWYG-Editor z.B.

    [[Äpfel]]

notiere, woraus dann ein

    <a href="obst.html">Äpfel</a>

gemacht wird.
Logged
thorn

Offline Offline

Posts: 980


WWW
« Reply #5 on: November 01, 2008, 11:01:37 PM »

Hallo,

ich hab nochmal ein bissen mit der Idee herumgespielt. Herausgekommen dabei ist dieses Code-Schnipsel hier:
Code:
global $tag2link;
$tag2link = array(
    'Äpfel'=>'<a href="http://www.obstbauer.de">Äpfel</a>',
    'Birnen'=>'<a href="http://www.obstscheune.de">Birnen</a>',
);
require_once(WB_PATH.'/framework/functions.php');
@ob_start();
    require(WB_PATH.'/templates/'.TEMPLATE.'/index.php');
    $frontend_output = ob_get_contents();
@ob_end_clean();
$frontend_output = preg_replace_callback('#\[\[([^] ]+)\]\]#',
    create_function('$match', '
        global $tag2link;
        $tag = entities_to_umlauts($match[1]);
        if(array_key_exists($tag, $tag2link)) {
            return($tag2link[$tag]);
        } else {
            return($match[1]);
        }
    '),
    $frontend_output
);
echo $frontend_output;
die;

Füge es mal testweise in wb/index.php ein, und zwar hier (Zeile 88):
Code:
...
                // redirect
                header('Location: '.WB_URL.PAGES_DIRECTORY.$target_page_link.PAGE_EXTENSION.($anchor?'#'.$anchor:''));
                exit;
            }
        }
    }
}

// --->  hier einfügen  <---

if(file_exists(WB_PATH .'/modules/output_filter/filter-routines.php')) {
...

Das soll jetzt nur mal als proof-of-concepts dienen. Beachte bitte, dass du damit den Output-Filter außer Betrieb setzt.
Wenn du die Ersetzungen nur in WYSIWYG-Abschnitten brauchst, kannst du eine Ähnliche Funktion besser in wb/modules/wysiwyg/view.php einbauen als hier in die wb/index.php.
Dort würde dann am Ende der Datei aus
Code:
$wb->preprocess($content);

echo $content;
einfach
Code:
$wb->preprocess($content);

global $tag2link;
$tag2link = array(
    'Äpfel'=>'<a href="http://www.obstbauer.de">Äpfel</a>',
    'Birnen'=>'<a href="http://www.obstscheune.de">Birnen</a>',
);
require_once(WB_PATH.'/framework/functions.php');
$content = preg_replace_callback('#\[\[([^ ~]+)\]\]#',
    create_function('$match', '
        global $tag2link;
        $tag = entities_to_umlauts($match[1]);
        if(array_key_exists($tag, $tag2link)) {
            return($tag2link[$tag]);
        } else {
            return($match[1]);
        }
    '),
    $content
);
echo $content;


In dem Array $tag2link kann man die Ersetzungen angeben (würde dann normalerweise aus einer Datenbank gelesen, anstatt es hier von Hand einzutragen -- [wenn dein Editor nicht UTF-8 benutzt wirst du Probleme mit Umlauten bekommen]). Alternative kann man für das Array eine eigene Datei benutzen, die dann einfach z.B. per require_once('/var/www/userroot/tag2link.inc'); geladen wird;

Alle Begriffe in der Form [[Orangen]] werden ersetzt. Wenn es keinen Eintrag für [[Orangen]] werden die Klammen einfach entfernt, und das Wort wird ohne Link dargestellt.

thorn.
« Last Edit: November 05, 2008, 07:28:32 AM by thorn » Logged

pcwacht
AddOn Development
*
Offline Offline

Posts: 2856



WWW
« Reply #6 on: November 01, 2008, 11:33:12 PM »

Sorry for english..., mein Deutsch ist leider nicht genügend um alles zu ubersetsen....


I think there exists a javascript function or an ajax function wich could replace words, dis a brief search on the net for a script-example but couldn't find one

What it does,
after loading the page it search for words wich exists and add links to those words
I thought it was called glossary, but sorry, didn't had luck finding it.
Many sites use it nowadays to autoaticly add advertisements to words in the text.

Same technique could be used here.

Have fun,
John
Logged

http://www.ictwacht.nl = Dutch ICT info
http://www.pcwacht.nl = My first
both still work in progress, since years.....
thorn

Offline Offline

Posts: 980


WWW
« Reply #7 on: November 02, 2008, 12:32:11 AM »

Hallo,

@pcwacht:
Really cool tip! I tried the little javascript-snippet below in an section from type WYSIWYG (copied into the sourcecode at the end) - and it worked very well. The Text [[Birnen]] will be transformed to Birnen (being a link, now).


Na, das ist ja ma cool  cool
Ich habe testweise in einen WYSIWYG-Abschnitt am Ende dies eingefügt:
Code:
<script type="text/javascript">
x=document.body.innerHTML.replace(/\[\[Birnen\]\]/ig, '<a href="http://www.obstscheune.de/">Birnen</a>');
document.body.innerHTML = x;
</script>
und das klappt tatsächlich. Der Text [[Birnen]] auf dieser Seite wird durch den Link ersetzt.

Danke für den Tipp.

Edit II:
Wenn man javascript benutzt wäre es wohl besser eine Klasse als Kennzeichnung zu benutzen anstatt [[]] - falls ein User javascript blockiert (NoScript) schadet das nicht. z.B. mit class="tag".
Dieses Beispiel geht von der <span class="tag></span>-Schreibweise des FCKEditors aus:
Code:
<script type="text/javascript">
x=document.body.innerHTML.replace(/<span class="tag">Birnen<\/span>/ig, '<a href="http://www.obstscheune.de/">Birnen</a>');
document.body.innerHTML = x;
</script>

thorn.
« Last Edit: November 02, 2008, 01:22:00 AM by thorn » Logged

Katerchen

Offline Offline

Posts: 84


« Reply #8 on: November 04, 2008, 10:38:35 PM »

Klasse Ideen - werde jedoch voraussichtlich erst am Wochenende dazu kommen, sie auszuprobieren. Dabei würde ich diejenige ohne JavaScript bevorzugen, da es eben eine Voraussetzung beim Benutzer weniger bedeutet, bei gleichem Resultat. Den vordefinierten Output-Filter brauche ich derzeit sowieso nicht.

Wenn allerdings bei jeder Seite zunächst einmal eine MySQL-Tabelle geladen und zusätzlich die ganze Seite geparst werden muß - wird das Ganze dann nicht zu langsam? Oder würde sich aus Performancegründen eher eine einfache Textdatei (z.B. CSV) mit den Tags und den zugehörigen Links anbieten?

(Doch vielleicht wäre das auch eine Idee für eine zukünftige WB-Version: Einen generischen Output-Filter, bei dem man nur eine Funktion definieren muß, durch die dann die schon fertig aufgebaute Seite durchgejagt wird?)
Logged
thorn

Offline Offline

Posts: 980


WWW
« Reply #9 on: November 05, 2008, 12:17:48 AM »

Hallo,

eine Datei ist auf jeden Fall einfacher ...

Code: (from index.php)
if(file_exists(WB_PATH.'/private_directory/tag2link.php')) { // defines array: $tag2link
    require_once(WB_PATH.'/private_directory/tag2link.php');
    ob_start();
        require(WB_PATH.'/templates/'.TEMPLATE.'/index.php');
        $frontend_output = ob_get_contents();
    ob_end_clean();
    $frontend_output = preg_replace_callback('#\[\[([^] ]+)\]\]#',
        create_function('$match', '
            global $tag2link;
            $tag = $match[1];
            if(array_key_exists($tag, $tag2link)) {
                return($tag2link[$tag]);
            } else {
                return($tag);
            }
        '),
        $frontend_output
    );
    echo $frontend_output;
    die;
}
Code: (tag2link.php)
// prevent this file from being accessed directly
if(!defined('WB_PATH')) die(header('Location: index.php'));

/*
    Anleitung hier ...
    ...

    Bitte Beachten: Umlaute sind als HTML-Entities zu schreiben, also
    ä = &auml;    o = &ouml;    ü = &uuml;    ß = &szlig;
    Ä = &Auml;    O = &Ouml;    Ü = &Uuml;
    á = &aacute;  ...

*/
global $tag2link;
$tag2link = array(
    '&Auml;pfel'=> '<a href="http://www.obstbauer.de">&Auml;pfel</a>',
    'Birnen'    => '<a href="http://www.obstscheune.de">Birnen</a>',
    'Hund'      => '<a href="http://www.hunde.de"><img alt="Bild:Schaeferhund.JPG" src="http://upload.wikimedia.org/wikipedia/commons/3/36/Schaeferhund.JPG" width="35" height="27" border="0" /></a>'
);

Auch in diesem Fall sollte man vielleicht besser eine Klasse benutzen, anstatt der [[ ]]-Schreibweise.
Code: (mit class="tag" des FCKEditors)
$frontend_output = preg_replace_callback('#<span class="tag">([^<]+)<\/span>#',

thorn.
« Last Edit: November 05, 2008, 08:01:22 PM by thorn » Logged

gucci

Offline Offline

Posts: 46


« Reply #10 on: November 05, 2008, 01:38:07 PM »

@thorn,

wir immer eine schnelle Lösung von Dir. Ich denke die Idee von Katerchen ist ein super Feature für wb.
Bei einem kurzen Test habe ich folgendes festgestellt.
1. Fehlt bei Deinem Code nicht noch ein "?>" damit der Code in die index.php eingebunden werden kann?
2. Nachdem ich die entsprechenden Einträge vorgenommen und die Pfade angepass habe erhalte ich beim Klick auf einen Menüeintrag den "Download Hinweis", d.h. mein Browser (FF3) möchte die entsprechende php-Seite des Menüs downloaden und der Text Äpfel auf der Inhaltsseite wird nicht als Link erkannt.

Gruss

Gucci
Logged
thorn

Offline Offline

Posts: 980


WWW
« Reply #11 on: November 05, 2008, 02:01:49 PM »

Hallo,

die <?php dienen hier nur dazu, dass der code farbig dargestellt wird.
Der Code soll in die wb/index.php eingefügt werden, wie im ersten in diesem Beitrag beschrieben.
Da gehören die php-tags <?php und ?> dann nicht mit hinein.
Ich werde den vorhergehenden Beitrag mal entsprechend anpassen...

Den Code selber kann ich gerade nicht testen, sollte dann aber laufen.
Probier es nochmal aus.
Edit: setze Error-Level auf E_ALL (in Optionen -> erweiterte Optionen)

thorn.
« Last Edit: November 05, 2008, 04:18:10 PM by thorn » Logged

gucci

Offline Offline

Posts: 46


« Reply #12 on: November 05, 2008, 03:43:34 PM »

@thorn,

danke für die schnelle Antwort. Leider funktioniert es nicht.
Mit der Auszeichnung "<?php .... ?> kommt die Meldung "Möchten Sie folgende Datei herunterladen"
ohne dies Auszeichnung wird natürlich der PHP-Code selbst im Frontend gezeigt.

Eine Fehlermeldung "Error" wird nicht angezeigt (E_ALL ist gesetzt)

Gruss
Gucci


Logged
thorn

Offline Offline

Posts: 980


WWW
« Reply #13 on: November 05, 2008, 04:15:39 PM »

Hallo,

ohne dies Auszeichnung wird natürlich der PHP-Code selbst im Frontend gezeigt.

hmm, und in welche Datei (und welche Stelle) hast du den Code eingefügt?

thorn.
Logged

gucci

Offline Offline

Posts: 46


« Reply #14 on: November 05, 2008, 07:51:51 PM »

Hallo thorn,

habe das in der index.php meines templates eingebunden - an mehreren Stellen -
sowohl im head als auch im body Bereich kein Erfolg.

Grüssle
Gucci
Logged
thorn

Offline Offline

Posts: 980


WWW
« Reply #15 on: November 05, 2008, 07:54:36 PM »

Hallo,

Füge es mal testweise in wb/index.php ein, und zwar hier (Zeile 88):
Code:
...
                // redirect
                header('Location: '.WB_URL.PAGES_DIRECTORY.$target_page_link.PAGE_EXTENSION.($anchor?'#'.$anchor:''));
                exit;
            }
        }
    }
}

// --->  hier einfügen  <---

if(file_exists(WB_PATH .'/modules/output_filter/filter-routines.php')) {
...
Es sollte eigentlich in die Datei wb/index.php, das ist die index.php im Hauptverzeichnis von wb. Dort bei Zeile 88 einfügen, siehe oben.

EDIT: Ein Fehler war allerdings auch noch im Code: fehlendes global $tag2link; hinzugefügt.

thorn.
« Last Edit: November 05, 2008, 08:03:00 PM by thorn » Logged

gucci

Offline Offline

Posts: 46


« Reply #16 on: November 06, 2008, 08:31:52 AM »

Hallo thorn,

sorry, dass mit der index.php, dachte einfach dass es die index im template-Verzeichnis ist.

Folgende Fehlermeldung bekomme ich noch:
Code:
Notice: Undefined variable: tag2link in C:\xamp\www\test\index.php(104) : runtime-created function on line 3

Warning: array_key_exists() [function.array-key-exists]: The second argument should be either an array or an object in C:\xamp\www\test\index.php(104) : runtime-created function on line 3

Noch eine Frage:
global $tag2link; ist doch in der tag2link.php gesetzt huh

Gruss
Gucci
« Last Edit: November 06, 2008, 09:25:50 AM by gucci » Logged
thorn

Offline Offline

Posts: 980


WWW
« Reply #17 on: November 06, 2008, 10:10:36 AM »

Hallo,

kopiere dir nochmal den code zum Einfügen von hier http://www.websitebaker2.org/forum/index.php/topic,11612.msg70214.html#msg70214

Dort fehlte noch ein global $tag2link; das ich inzwischen ergänzt habe.

thorn.
Logged

gucci

Offline Offline

Posts: 46


« Reply #18 on: November 06, 2008, 03:52:29 PM »

@thorn,

 grin Es funktioniert!

Nochmals vielen  Dank für Deine Dienste hier im Forum und die tolle Unterstützung.

Gruss
Gucci
Logged
Katerchen

Offline Offline

Posts: 84


« Reply #19 on: November 10, 2008, 09:35:06 PM »

So, jetzt habe ich es auch mal probiert, und es funktioniert bisher sehr gut (die tag2link.php brauchte noch die Auszeichnung <?php ... ?>). Allerdings darf in den Tags kein Leerzeichen vorkommen, sonst werden sie offenbar nicht als solche erkannt und die Ersetzung findet nicht statt - ich vermute mal, daß das man das durch eine erweiterte Regular Expression im Aufruf von preg_replace_callba ck() fixen kann.

Auf alle Fälle danke für die klasse Umsetzung dieser Idee - es sieht ja so aus, als ob es noch mehr Interessenten für sowas gibt.
« Last Edit: November 10, 2008, 09:50:05 PM by Katerchen » Logged
thorn

Offline Offline

Posts: 980


WWW
« Reply #20 on: November 10, 2008, 11:21:00 PM »

Hallo,

Allerdings darf in den Tags kein Leerzeichen vorkommen, sonst werden sie offenbar nicht als solche erkannt und die Ersetzung findet nicht statt - ich vermute mal, daß das man das durch eine erweiterte Regular Expression im Aufruf von preg_replace_callba ck() fixen kann.
gut erkannt. In diesem Fall reicht es das vorhandene Leerzeichen aus dem regex zu entfernen.

thorn.
Logged

thorn

Offline Offline

Posts: 980


WWW
« Reply #21 on: November 13, 2008, 04:39:10 PM »

Hallo,
noch ein Nachtrag:

mir fällt gerade auf, dass man das ja viel besser im Template unterbringen kann, und zwar anstelle des page_content()-Aufrufes.

Also statt
Code:
page_content();
so:
Code:
<?php
if(file_exists(WB_PATH.'/private_directory/tag2link.php')) { // defines array: $tag2link
    
require_once(WB_PATH.'/private_directory/tag2link.php');
    
ob_start();
        
page_content();
        
$frontend_output ob_get_contents();
    
ob_end_clean();
    
$frontend_output preg_replace_callback('#\[\[([^] ]+)\]\]#',
        
create_function('$match''
            global $tag2link;
            $tag = $match[1];
            if(array_key_exists($tag, $tag2link)) {
                return($tag2link[$tag]);
            } else {
                return($tag);
            }
        '
),
        
$frontend_output
    
);
    echo 
$frontend_output;
} else {
page_content();
}
Logged

Katerchen

Offline Offline

Posts: 84


« Reply #22 on: November 16, 2008, 09:05:59 AM »

Wunderbar, noch besser. Habe es gerade umgebaut, funktioniert prima. Danke für die tolle Unterstützung! (Ich habe den Code in eine eigene Funktion page_content2() ausgelagert und diese per require_once() im Template zur Verfügung gestellt, das hält das Template weiterhin knapp.)

Nun möchte ich noch die Verwaltung des Arrays vereinfachen. Die Website soll auch von Leuten bearbeitet werden können, denen ich die Einhaltung einer komplizierteren Syntax nicht zumuten kann. (Daher auch das wiki-mäßige [[...]] zur Kennzeichnung der Tags, was man bequem im WYSIWYG-Editor eingeben kann - der Umgang mit <span> und Class-IDs wird über kurz oder lang schiefgehen, da doch irgendwann ein Anführungszeichen oder eine schließende Klammer vergessen wird, und im Source-Bereich des Editors sollten sie nicht editieren müssen. Doch vielleicht kann ich in der Konfiguration des FCKeditors noch was machen, mit der habe ich mich bislang nur oberflächlich beschäftigt.)

Am liebsten würde ich das Array $tag2link aus einer MySQL-Tabelle lesen lassen (zur Not auch aus einer CSV-Datei), allerdings sollte das die Performance nicht nennenswert beeinträchtigen, immerhin geschieht diese Datenbankabfrage bei jedem Seitenaufruf. Der Query-Cache von MySQL ist eingeschaltet, die Abfrage immer dieselbe, daher erhoffe ich mir, daß die Gescheindigkeit des Seitenaufbaus nicht sehr darunter leidet (es sind ca. 100 Einträge in der Tabelle zu erwarten).
Logged
thorn

Offline Offline

Posts: 980


WWW
« Reply #23 on: November 16, 2008, 12:16:36 PM »

Hallo,

ich glaube nicht das sich das zeitlich nennenswert bemerkbar machen würde.
Du kannst das aber leicht testen, indem du unter Optionen in das Feld "Fußzeile"
Code:
[PROCESS_TIME]
einträgst. Dann wird ganz unten auf jeder Seite die benötigte Zeit zur Erstellung der Seite angezeigt (nur die reine Erstellungszeit auf dem Server. Zeiten für Übertragen oder nachladen von Bildern werden nicht berücksichtigt).
Und dann die gleiche Seite ein paar mal laden - erst ohne die Ersetzung, dann mit.
Oder du benutzt XDebug - womit man sich tolle bunte Bilder erzeugen kann  grin

Wenn du die Übersetzungstabelle in mySQL anlegen willst, wirst du auch ein Frontend brauchen um die Daten zu pflegen - oder soll das nur ein Admin über z.B. phpmyAdmin machen können?

thorn.
Logged

Katerchen

Offline Offline

Posts: 84


« Reply #24 on: November 16, 2008, 12:34:14 PM »

[PROCESS_TIME] - klasse Möglichkeit. Danke.

Quote
Wenn du die Übersetzungstabelle in mySQL anlegen willst, wirst du auch ein Frontend brauchen um die Daten zu pflegen - oder soll das nur ein Admin über z.B. phpmyAdmin machen können?
Hier habe ich mich noch nicht entschieden - selbst mache ich solche Dinge gerne mit Access über eine ODBC-Verbindung, vielleicht ist das auch eine Lösung für die anderen Bearbeiter. Evtl. gibt es noch ein anderes einfaches (Freeware-) Tool, mit dem man Datenbanktabellen über ODBC bearbeiten kann und das ich denen an die Hand geben kann. An phpMyAdmin will ich sie nicht ranlassen, das ist viel zu kompliziert.

Sollte ich mich doch für ein Webinterface entscheiden, kann ich es natürlich auch beim derzeitigen PHP-Array belassen.
Logged
Pages: [1]   Go Up
Print
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.16 | SMF © 2011, Simple Machines Valid XHTML 1.0! Valid CSS!