PHPackages                             venne-media/venne-search-contao-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [PDF &amp; Document Generation](/categories/documents)
4. /
5. venne-media/venne-search-contao-bundle

ActiveContao-bundle[PDF &amp; Document Generation](/categories/documents)

venne-media/venne-search-contao-bundle
======================================

Volltext-Suche für Contao mit Live-Indexing von Seiten und Datei-Inhalten (PDF, DOCX, ODT, RTF). Mehrsprachig, Tag-System mit Tree-Picker, anonymes Search-Analytics-Tracking, Tippfehler-Toleranz, ACL-aware.

v1.0.2(1mo ago)15LGPL-3.0-or-laterPHPPHP ^8.1CI failing

Since Apr 29Pushed 1mo agoCompare

[ Source](https://github.com/Venne-Media-GmbH/venne-search-contao-bundle)[ Packagist](https://packagist.org/packages/venne-media/venne-search-contao-bundle)[ Docs](https://venne-search.de)[ RSS](/packages/venne-media-venne-search-contao-bundle/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (11)Versions (5)Used By (0)

Venne Search · Contao Bundle
============================

[](#venne-search--contao-bundle)

Volltext-Suche für Contao. Findet Inhalte in Seiten, Artikeln, Content-Elementen und Dateien (PDF, DOCX, ODT, RTF, TXT, MD) — mehrsprachig, mit Tags und anonymen Such-Analytics.

Die Plattform-Anbindung läuft über [venne-search.de](https://venne-search.de) — das Bundle holt sich beim ersten Request einen scoped Meilisearch-Token und schreibt direkt in den passenden Index. Pro Site ein API-Key, fertig.

Was es kann
-----------

[](#was-es-kann)

- **Live-Indexing**: Wenn du eine Seite speicherst oder eine Datei hochlädst, ist sie kurze Zeit später in der Suche
- **Mehrsprachig**: Pro Locale ein Index, automatische Sprach-Erkennung für Dateien (Pfad → Embedding → Filename) mit Override-Möglichkeit
- **Tag-System mit Tree-Picker**: Seitenbaum öffnen, per Klick oder Drag-&amp;-Drop Tags zuweisen — Tags erscheinen klickbar als Filter in den Such-Treffern
- **Anonymes Search-Analytics**: Erfasst auf der Plattform welche Begriffe gesucht werden (kein IP, kein User-Agent, keine User-ID) — nützlich um Content-Lücken zu finden
- **PDF-Inhalte durchsuchen**: Texte aus PDFs werden extrahiert und indexiert
- **Tippfehler-Toleranz**: `Krabbnburger` findet `Krabbenburger`
- **Diakritik-Folding**: `cafe` findet `café`, `Cafe`, `CAFÉ`
- **ß ↔ ss**: `masse` findet `Maße`
- **Schnell**: Suchen unter 50 ms bei zehntausenden Dokumenten
- **JSON-API** unter `/vsearch/api?q=…` für eigene Frontends
- **Permission-aware**: geschützte Inhalte erscheinen nur in der Suche, wenn der eingeloggte Member auch wirklich Zugriff hat

Voraussetzungen
---------------

[](#voraussetzungen)

- Contao 4.13 oder 5.x (getestet auf 4.13, 5.3 und 5.7)
- PHP 8.1 oder neuer
- Aktiver Account auf [venne-search.de](https://venne-search.de)

Installation
------------

[](#installation)

```
composer require venne-media/venne-search-contao-bundle
vendor/bin/contao-console contao:migrate
```

Wer den Contao-Manager nutzt: Paket suchen, installieren, Updates anwenden — der Manager ruft `contao:migrate` automatisch im Anschluss auf.

Konfiguration
-------------

[](#konfiguration)

1. Auf venne-search.de einloggen → Dashboard → API-Keys → einen erzeugen
2. Im Contao-Backend: **System → Venne Search** öffnen
3. API-Key eintragen, Sprachen wählen, speichern

Das war's. Beim ersten Speichern fragt das Bundle den Endpoint und den scoped Token von venne-search.de ab und cached das eine Stunde.

Erste Indexierung
-----------------

[](#erste-indexierung)

Im Backend bei „Venne Search" auf **Vorschau &amp; Indexieren** klicken. Du siehst vorab:

- Wie viele Seiten und Dateien indexiert werden
- Wie viele schon im Index sind (werden übersprungen)
- Welche durch Berechtigungen ausgeschlossen sind

Danach läuft die Indexierung live durch. Pro Datei siehst du Anzahl Zeichen, Dauer und ETA. Bei Problemen klare Skip-Gründe wie „PDF passwortgeschützt", „PDF zu groß" oder „PDF enthält nur Bilder".

Sicherheit
----------

[](#sicherheit)

Geschützte Inhalte (Member-Bereiche) bleiben geschützt. Zwei Modi zur Auswahl:

- **Nur öffentlich erreichbare Inhalte** (empfohlen, Default): geschützte Seiten und Dateien landen gar nicht erst im Index
- **Auch geschützte Inhalte — Frontend filtert pro Mitglied**: alles indexiert, anonyme Besucher sehen nur freie Treffer, eingeloggte Member zusätzlich ihre erlaubten geschützten — markiert mit einem Schloss-Icon

Zusätzlich gibt es einen **Tree-Picker** im Backend, mit dem du pro Klick einzelne Ordner aus dem Datei-Manager komplett von der Indexierung ausschließen kannst. Bei der ersten Migration werden — falls vorhanden — `files/intern`, `files/admin` und `files/private` automatisch vorausgewählt.

Im Frontend filtert Meilisearch hart bei jedem Such-Call:

```
Anonymer Besucher           → is_protected != true
Eingeloggter Member [3, 7]  → is_protected != true OR allowed_groups IN [3, 7]

```

Auch wenn versehentlich was Geschütztes im Index liegt, der Filter blockiert es zur Suchzeit.

Frontend einbauen
-----------------

[](#frontend-einbauen)

### Variante 1: Contao-Frontend-Modul

[](#variante-1-contao-frontend-modul)

Layout → Frontend-Module → Neues Modul → Typ **Venne Search** → ins Layout ziehen.

### Variante 2: Eigenes Frontend per JSON-API

[](#variante-2-eigenes-frontend-per-json-api)

```

document.getElementById('search').addEventListener('input', async (e) => {
    const q = e.target.value.trim();
    if (q.length  `${h.title}${h.snippet}`)
        .join('');
});

```

### API-Antwort

[](#api-antwort)

```
{
  "hits": [
    {
      "id": "page-42",
      "type": "page",
      "title": "Über uns",
      "url": "/ueber-uns.html",
      "snippet": "…Team…",
      "tags": ["team"],
      "score": 0.876
    }
  ],
  "totalHits": 12,
  "facets": {"type": {"page": 8, "file": 4}},
  "queryTimeMs": 7
}
```

### Fehler-Codes der API

[](#fehler-codes-der-api)

HTTP`error`Was bedeutet das401`unauthorized`Plattform-Key ungültig oder widerrufen402`subscription_inactive`Kein aktives Abo403`not_provisioned`Plattform-Admin muss den Key noch einrichten429`rate_limited`Zu viele Anfragen, kurz warten503`platform_unreachable`venne-search.de gerade nicht erreichbarArchitektur in einem Bild
-------------------------

[](#architektur-in-einem-bild)

```
Contao-Site (Bundle)
   │
   │  1. Plattform-Key vsk_live_…
   ▼
venne-search.de   ───►   { endpoint, indexPrefix, scopedToken }
                                       │
                                       │  2. scoped Token darf nur t__*
                                       ▼
                                Meilisearch-Server

```

Der Master-Key bleibt bei der Plattform, das Bundle bekommt nur den Token für seinen eigenen Tenant. Alle Index-Calls werden zusätzlich gegen ein erwartetes UID-Pattern validiert — Defense in Depth.

Auto-Indexing
-------------

[](#auto-indexing)

Diese Hooks sind aktiv, ohne dass du was tun musst:

- Speichern einer Seite, eines Artikels oder Content-Elements → indexiert
- Hochladen einer Datei im Datei-Manager → indexiert
- Löschen einer Datei → aus Index entfernt

Im Backend gibt es einen **Toggle**, der das Auto-Indexing komplett abschaltet — falls du den Index lieber gebündelt manuell aktualisierst. Pro Eintrag in der Tabelle „Indexierte Daten" gibt es einen **Refresh-Knopf**, mit dem du einzelne Dokumente neu indexieren kannst, ohne den ganzen Lauf anzustoßen.

Datei per FTP direkt auf den Server kopieren umgeht den Hook — dafür gibt's den **Vorschau &amp; Indexieren**-Button im Backend, der die Datei dann beim nächsten Lauf erfasst.

Mehrsprachigkeit
----------------

[](#mehrsprachigkeit)

Das Bundle indexiert pro **Locale** in einen eigenen Index — eine Site mit `de,en,fr` als aktive Sprachen hat drei Indexe. Pages bringen ihre Sprache aus `tl_page.language` mit; **Dateien werden über fünf Strategien automatisch zugeordnet** (in dieser Reihenfolge, erste die liefert gewinnt):

1. **Override** aus den Settings (`file_locale_overrides` JSON-Map)
2. **Page-Embedding**: Wo ist die Datei in `tl_content.singleSRC` / `multiSRC` eingebunden? Dominante Sprache der Pages gewinnt.
3. **Pfad-Hint**: `files/de/...`, `files/en_US/...`
4. **Filename-Hint**: `manual_de.pdf`, `flyer-en.pdf`
5. **Default**: `default_file_locale` aus den Settings, sonst erste aktive Locale

Du kannst pro Datei direkt im Documents-Panel die Sprache überschreiben — der Eintrag wird sofort reindexiert.

Beim Anlegen eines Frontend-Moduls oder Content-Elements vom Typ "Venne Search" wählst du **eine** feste Such-Sprache. Endnutzer wechseln die Sprache **nicht** selbst — sie sehen genau eine Suche, die zur aktuellen Seite passt.

Tag-System
----------

[](#tag-system)

Im Backend unter **System → Venne Search** zwei neue Bereiche:

- **Seitenbaum-Tagging**: Tree mit allen Seiten, pro Zeile aktuelle Tag-Chips. "+"-Button öffnet eine Combobox mit Live-Search; nicht existierende Tags lassen sich on-the-fly anlegen. Drag-&amp;-Drop: Chip auf eine andere Page-Zeile ziehen = Tag mit-zuweisen. Jede Änderung triggert sofortiges Reindexing.
- **Tag-Verwaltung**: Eigene Tabelle `tl_venne_search_tag` mit Slug, Label, Beschreibung, Farbe (8 vorgegebene Farben). Pro Tag wird die Anzahl der Zuweisungen direkt angezeigt.
- **Tag-Übersicht**: Tabellarisch alle Tags mit Counts, Farb-Chips und Edit-Link.

Im Frontend werden Tag-Chips an jeden Treffer gehängt (`tagsResolved` mit `slug`, `label`, `color`). Klickbar als Filter via `?tags[]=spongebob&tags[]=krabbenburger`. Mehrere Tags = AND-Verknüpfung (Meilisearch `IN`).

Die Migration übernimmt einmalig vorhandene `tl_page.keywords`-CSVs ins neue System — gleicher Slug = gleicher Tag.

Search-Analytics
----------------

[](#search-analytics)

Standardmäßig aktiv. Jede Suche auf deiner Site wird sofort und unsichtbar an [venne-search.de](https://venne-search.de) geschickt — kein Cron, kein Worker, kein zusätzliches Setup. Du logst dich auf venne-search.de ein, gehst zu deinen API-Keys → Analytics und siehst Top-Suchen, Zero-Result-Rate (sehr wertvoll für SEO) und einen 30-Tage-Verlauf.

**Was wird gespeichert**: Suchbegriff, Sprache, Treffer-Anzahl, Zeitstempel. **Was wird NICHT gespeichert**: IP-Adresse, User-Agent, Cookies, Session-IDs, User-Account-Bezug.

Wenn du Analytics nicht möchtest, deaktivierst du im Backend unter **System → Venne Search** die Checkbox „Such-Analytics aktivieren". Der Such-Request läuft auch dann unverändert durch — nur ohne Tracking.

Lizenz
------

[](#lizenz)

LGPL-3.0-or-later

Kontakt
-------

[](#kontakt)

- E-Mail:
- Issues: [GitHub](https://github.com/Venne-Media-GmbH/venne-search-contao-bundle/issues)
- Plattform: [venne-search.de](https://venne-search.de)

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance92

Actively maintained with recent releases

Popularity6

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

41d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/109477845?v=4)[JanSch92](/maintainers/JanSch92)[@JanSch92](https://github.com/JanSch92)

---

Top Contributors

[![JanSch92](https://avatars.githubusercontent.com/u/109477845?v=4)](https://github.com/JanSch92 "JanSch92 (18 commits)")

---

Tags

searchmeilisearchpdfcontaofulltextcontao-bundle

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/venne-media-venne-search-contao-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/venne-media-venne-search-contao-bundle/health.svg)](https://phpackages.com/packages/venne-media-venne-search-contao-bundle)
```

###  Alternatives

[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.4M195](/packages/sulu-sulu)[open-dxp/opendxp

Content &amp; Product Management Framework (CMS/PIM)

9017.2k55](/packages/open-dxp-opendxp)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
