Wenn indexed_search nicht indiziert

Mittwoch, 08. Februar 2012

Das hier ist eine kleine Schritt-für-Schritt Checkliste um zu prüfen, warum indexed_search nicht funktioniert.

1. Logge Dich aus dem Backend aus.

Oder verwende einen anderen Browser um das Frontend zu besuchen während Du im Backend arbeitest. Wenn man im Backend eingeloggt ist, wird das Caching manchmal automatisch deaktiviert.

2. Prüfe, ob das indexing eingeschaltet ist.

Im TSsetup: page.config.index_enable = 1

3. Prüfe, ob das Caching deaktiviert wurde.

Die Seiteninhalte werden nur indiziert, wenn sie auch in Typo3 gecached werden, also in eine der Tabellen cf_cache… wandern. Der absolute indexed_search-Killer ist folglich $GLOBALS["TSFE"]->set_no_cache();
Eingrenzung:
Diese Zeile

if ($GLOBALS['TSFE']->no_cache) echo "No Cache ist aktiviert!";

als letzte Zeile in die index.php von Typo3 einfügen. Wenn der Text beim Aufruf der Seite ausgegeben wird, dann nacheinander folgende Sache prüfen:

  • Ist unter den Seiteneigenschaften -> Verhalten -> Cache deaktiviert?
  • Gibt es im TSsetup diese beiden Zeilen?
    config.no_cache = 0
    config.cache = 1
  • Muss eine Extension speziell zum Cachen konfiguriert werden wie z.B. plugin.tt_news.allowCaching = 1
  • Ist eine Extension auf der Seite im Einsatz, die im Quelltext set_no_cache(); aufruft?

Der “Übeltäter” kann durch die syslog eingegrenzt werden. Dazu in der typo3conf/localconf.php diesen Eintrag machen und dann die Seite im Frontend neu laden.

$TYPO3_CONF_VARS['SYS']['systemLog'] = 'file,log.txt,0';

Im Stammverzeichnis erscheint dann eine Datei log.txt – mit einem Eintrag in dieser Art “$TSFE->set_no_cache() was triggered by typo3conf/ext/dbfindit/pi1/…” – dort muss man suchen!

4. Enthält der Quelltext die Such-Marker?

Alle Texte, die von der indexed_search durchsucht werden sollen müssen innerhalb dieser Marker sein:
<!–TYPO3SEARCH_begin–>
… dieser Text wird indiziert …
<!–TYPO3SEARCH_end–>

5. Ist eine fe_login-Box auf allen Seiten eingebunden?

So schön es auch ist, ein Login-Formular für Benutzer auf allen Seiten zu haben: Das fe_login-Formular schaltet per $TSFE->set_no_cache(); das Caching ab. Abhilfe: Das Formular von einer anderen Seite per AJAX laden und einbinden.

6. Ist die Extension “crawler” installiert?

Wenn Crawler aktiv ist, wird indexed_search nicht ausgeführt. In der Core-Extension indexed_search unter typo3/sysext/indexed_search/class.indexer.php findet man in der function hook_indexContent alle Entscheidungen darüber, ob indiziert werden soll oder nicht. Der ganze sieht ungefähr so aus:

if ($pObj->config['config']['index_enable']) {
   if (!$indexerConfig['disableFrontendIndexing'] || $this->crawlerActive) {
       if (!$pObj->page['no_search']) {
          if (!$pObj->no_cache) {
               if (!strcmp($pObj->sys_language_uid,$pObj->sys_language_content)) {
...

7. Wurde bei der Konfiguration von indexed_search das Indexing abgeschaltet?

Unter “Erweiterungen” auf die Extension “indexed_search” klicken. In den Reiter “Konfiguration” wechseln. Etwa in der Mitte befindet sich eine Checkbox mit dem Titel “Disable Indexing in Frontend”. Ist das Häkchen gesetzt? Dann kann es nicht klappen. Die Variable befindet sich auch (serialisiert) in der localconf.php in der Zeile

$GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['indexed_search'] ...

Typo3 Cache-Tabellen regelmäßig löschen

Zum Debuggen hilft mir auch dieses kleine PHP-Script, dass alle Cache-Tabellen und Indizierungen löscht. Eignet sich auch gut zum regelmäßigen Leeren der Cache-Tabellen in Typo3, falls z.B. eine Cache-Killer-Extension wie Kaldender “cal” im Einsatz ist: Dieses Script als Cron-Job (evtl. ohne die index_…-Tabellen) regelmäßig aufrufen…

<?php
	require_once('typo3conf/localconf.php');
	$clean = array(
		'cache_extensions', 'cache_imagesizes', 'cache_md5params', 'cache_treelist', 'cache_typo3temp_log', 'cf_cache_hash', 'cf_cache_hash_tags', 'cf_cache_pages',
		'cf_cache_pagesection', 'cf_cache_pagesection', 'cf_cache_pagesection_tags', 'cf_cache_pages_tags',
		'index_debug', 'index_fulltext', 'index_grlist', 'index_phash', 'index_rel', 'index_section', 'index_stat_search', 'index_stat_word', 'index_words'	
	);
 
	$link = mysql_connect($typo_db_host, $typo_db_username, $typo_db_password);
	mysql_select_db( $typo_db, $link );
 
	if (!$link) die("Could not connect to DB");
 
	foreach ($clean as $tbl) {
		$sql = "TRUNCATE $tbl;";
		$result = mysql_query( $sql );
		if (!$result) die("Could not execute query!".mysql_error());
	}
 
	mysql_close($link);
?>

Nächste Probleme: indexed_search indiziert, aber zeigt “NO results” an

1. Verwendest Du das aktualisierte Template von indexed_search?

Lieber noch mal abgleichen: unter typo3/sysext/indexed_search findet man das aktuelle Template. Es enthält evtl. kleinere Änderungen am Code, z.B. neue ID-Attribute oder hidden-Felder. Verwendet man ein eigenes Template aus alten Projekten, fehlen diese IDs möglicherweise.

...
<input type="text" name="tx_indexedsearch[sword]" value="" id="tx-indexedsearch-searchbox-sword" class="tx-indexedsearch-searchbox-sword sword" data-deftext="Suchbegriff">
<input type="submit" name="tx_indexedsearch[submit_button]" value="Suchen" id="tx-indexedsearch-searchbox-button-submit" class="tx-indexedsearch-searchbox-button submit">
<input type="hidden" name="tx_indexedsearch[_sections]" value="0" />
<input type="hidden" name="tx_indexedsearch[_freeIndexUid]" id="tx_indexedsearch_freeIndexUid" value="_" />
<input type="hidden" name="tx_indexedsearch[pointer]" id="tx_indexedsearch_pointer" value="0" />
...

2. Stimmt die search.rootPidList?

Im Setup gibt es eine Einstellung für plugin.tx_indexedsearch.search.rootPidList die zu Problemen führen kann. Klassischer Fall: Man hat eine Multidomain-Installation und möchte die Suchergebnisse nur auf eine Domain beschränken. Eigentlich würde man laut Doku so etwas machen, wobei “621″ die Page-ID der entsprechenden Domain im Seitenbaum ist.

plugin.tx_indexedsearch.search.rootPidList = 621

Warum das nicht funktioniert ist mir bis heute nicht ganz klar. Funktioniert hat hingegen folgende Einstellung:

plugin.tx_indexedsearch {
   _DEFAULT_PI_VARS.sections=rl621_621
   search {
      rootPidList = -1
   }
}

Die Variable rl621_621 (rl steht für “RootLevel”) landet als Marker ###SECTIONS### im Such-Template:

   <input type="hidden" name="tx_indexedsearch[_sections]" value="###SECTIONS###">

Nächstes Problem: Suchergebnisse von indexed_search werden angezeigt, aber Pagination / Paginierung / Pagebrowser / Seitennavigation funktioniert nicht.

1. Verwendest Du einen eigene Suchbox (z.B. macina_searchbox) oder ein ganz eigenes Template für das Suchfeld? Kommt die id=”tx_indexedsearch_pointer”, “tx_indexedseach” oder “tx_indexedsearch_freeIndexUid” doppelt im DOM vor?

Das Problem an dem “normalen” indexed_search-Plugin ist, dass das Suchfeld und die Suchergebnisse fest miteinander verbunden sind. Möchte man ein Suchfeld auf allen Seiten integrieren, dann stört das sofort, weil auf der Suchergebnis-Seite auch das Suchfeld zu einer Ergebnis-Liste wird. Die meisten Leute greifen dann auf eine andere Extension zurück (macina_searchbox) oder bauen das Formular nach, das von indexed_search geliefert wird.
Der Haken dabei: In das Formular mit dem kleinen Suchfeld für alle Seiten wird versehentlich das id-Attribut mitkopiert:

<form ... id="tx_indexedsearch">
<input ... id="tx_indexedsearch_pointer">
<input ... id="tx_indexedsearch_freeIndexUid">

Diese IDs werden aber im PageBrowser der Suchergebnis-Liste per JavaScript manipuliert:

onclick="document.getElementById('tx_indexedsearch_pointer').value='0';document.getElementById('tx_indexedsearch_freeIndexUid').value='-1';document.getElementById('tx_indexedsearch').submit();return false;"

Sobald das Dokument zwei Elemente mit der gleichen ID enthält, wird nur das erste Element verändert. Wenn jetzt zufälligerweise das Suchfeld im DOM vor der Suchergbnisliste erscheint, dann wird es an der falschen Stelle geändert. Das gemeine daran: Evtl. hat man bei einer anderen Webseite das Problem nie gehabt, trotz identischer Setup-Scripte und Templates. Nur war dort die Reihenfolge zwischen Suchergebnis-Liste (indexed_search) und Suchbox (macina_searchbox) im HTML-Quelltext (DOM) anders herum, darum funktioniert es.
Lösung: Alle ID-Attribute der FORM- und INPUT-Tags im kleinen Suchfeld eindeutig machen. Und eindeutig heißt: nicht tx_indexedsearch, tx_indexedsearch_pointer oder tx_indexedsearch_freeIndexUid verwenden. Man kann die IDs bei dem Template für die Suchbox auch ganz entfernen.

2. Hast Du wichtige Teile aus dem Suchergebnis-Template gelöscht?

Klassischer Fehler: Du möchtest, dass über der Suchergebnis-Liste kein Feld für “Suche, erweiterte Suche” etc. erscheint. Dazu hast Du ja ein eigenes Suchfeld integriert. Also: Raus damit aus dem Template. Problem ist aber, dass auch die hidden-Felder mit ids (siehe oben) verschwunden und das JavaScript findet sein Ziel nicht.
Lösung: Alle Felder und Formulare, die nicht angezeigt werden sollen per CSS ausblenden (display: none) – NICHT aus dem Template löschen!

Gute Links zum Thema:
Tutorial zu crawler