se7enxweb / eztags-ls
eZ Tags LS: taxonomy management for Exponential. A tag tree with synonyms and translations, a tags datatype with autocomplete, select and tree editing, a tags admin tab, fetch functions, attribute filters and a tag cloud.
Package info
Type:ezpublish-legacy-extension
pkg:composer/se7enxweb/eztags-ls
Fund package maintenance!
Requires
- php: >=8.0
- se7enxweb/expui: ^1.0.0.1
- se7enxweb/ezpublish-legacy-installer: *
Requires (Dev)
None
Suggests
- se7enxweb/ezfind: Tag suggestions, related tags and the tag cloud over Solr
Provides
None
Conflicts
None
Replaces
None
- dev-master / 2.4.x-dev
- v2.4.24
- v2.4.23
- v2.4.22
- v2.4.21
- v2.4.20
- v2.4.19
- v2.4.18
- v2.4.17
- v2.4.16
- v2.4.15
- v2.4.14
- v2.4.13
- v2.4.12
- v2.4.11
- v2.4.10
- v2.4.9
- v2.4.8
- v2.4.7
- v2.4.6
- v2.4.5
- v2.4.4
- v2.4.3
- v2.4.2
- v2.4.1
- v2.4.0
- v2.3.5
- v2.3.4
- v2.3.3
- v2.3.2
- v2.3.1
- 2.3
- 2.2.2
- 2.2.1
- 2.2
- 2.1
- 2.0.2
- 2.0.1
- 2.0
- 1.4.2
- 1.4.1
- 1.4
- 1.3
- 1.2.3
- dev-2.2-stable
- dev-2.1-stable
- dev-2.0-stable
- dev-1.4-stable
- dev-1.3-stable
- dev-1.2-stable
This package is auto-updated.
Last update: 2026-10-24 02:34:14 UTC
README
eZ Tags LS brings real taxonomy management to Exponential. Tags live in a tree,
can have synonyms and translations, and are attached to content through the
eztags datatype, which editors fill with autocomplete, a select list or a tree.
It is for site builders who need categories, keywords or folksonomies that are
easier to manage than the kernel's ezkeyword datatype, and for developers who
want to list, filter and link content by tag in templates.
- Package:
se7enxweb/eztags - Source and issues: https://github.com/se7enxweb/eztags
- License: GNU General Public License v2.0 (or any later version), see LICENSE
Contents
- What you get
- Requirements
- Installation
- Configuration
- Usage
- Template reference
- Permissions
- Scripts
- Upgrading
- Known limits
- Troubleshooting
- Contributing
- License and credits
What you get
- A tag tree with as many levels as you need, managed in its own admin tab: add, edit, move, merge, translate and delete tags, turn a tag into a synonym of another, and see which content uses a tag.
- Synonyms: "Automobile" can be a synonym of "Car"; filters and fetches can include synonyms or not.
- Multilingual tags: each tag has translations and a main language, and can be marked as always available.
- The
eztagsdatatype for content classes, with a subtree limit, a maximum number of tags, an option to hide the root tag, and three edit views: Default (autocomplete with suggestions and adding new tags in place), Select and Tree. - Tag pages for visitors at
tags/view/<path>(for exampletags/view/Countries/Croatia) with the tag and its content. - Template fetch functions, attribute filters and operators to list tags, find content by tag and draw a tag cloud.
- A
taglinkcustom tag for rich text, linking to a tag by its ID. - eZ Find integration (optional): tags are indexed in Solr, and Solr can serve the tag cloud, tag suggestions and related tags.
- A converter from
ezkeywordattributes toeztagsattributes. - Translations of the interface in many languages (
translations/).
Requirements
- Exponential 6.x
- PHP 8.0 or later
- The ezjscore extension (part of Exponential)
- Optional: Exponential UI (
se7enxweb/expui, installed with eZ Tags by Composer). When it is active, the children tables of the tags admin use it; without it they fall back to the older tables. - Optional: eZ Find, for suggestions, related tags and the tag cloud over Solr
- Three database tables (
eztags,eztags_attribute_link,eztags_keyword): installation step 3
Installation
With Composer
From the root of your Exponential installation:
composer require se7enxweb/eztags
The Exponential legacy installer puts the extension in extension/eztags.
Continue with step 2 below.
By hand
-
Download a release from https://github.com/se7enxweb/eztags/releases and unpack it so that the files are in
extension/eztags/(extension/eztags/ezinfo.phpmust exist). -
Activate the extension in
settings/override/site.ini.append.php:[ExtensionSettings] ActiveExtensions[]=eztagsor in the administration under Setup > Extensions.
-
Create the tables, with the schema file for any supported database:
php bin/php/ezsqlinsertschema.php --type=mysql --user=<user> --password=<password> \ extension/eztags/share/db_schema.dba <database>
or with the SQL file of your database (
sql/mysql,sql/postgresql,sql/sqlite):mysql -u <user> -p <database> < extension/eztags/sql/mysql/schema.sql
-
Regenerate the autoload array and clear the caches:
php bin/php/ezpgenerateautoloads.php --extension php bin/php/ezcache.php --clear-all
-
Let visitors see tags: give the Anonymous role the policy tags / view (and tags / read if your site uses the tag tree menu).
-
Optional, faster tree menu: copy or symlink
index_treemenu_tags.phpnext toindex.phpand add these rewrite rules before the general one:RewriteRule tags/treemenu/? index_treemenu_tags.php RewriteRule ^index_treemenu_tags\.php - [L]
-
Optional, eZ Find: add these two fields inside
<fields>of your Solrschema.xml(extension/ezfind/java/solr/ezp-default/conf/schema.xmlfor the bundled server), restart Solr and re-index:<field name="ezf_df_tags" type="lckeyword" indexed="true" stored="true" multiValued="true" termVectors="true"/> <field name="ezf_df_tag_ids" type="sint" indexed="true" stored="true" multiValued="true" termVectors="true"/>
The original notes, with older details, are in doc/INSTALL.md.
Configuration
Do not edit extension/eztags/settings/eztags.ini; put your changes in
settings/override/eztags.ini.append.php or in a siteaccess. These are all the
settings, with their defaults:
[GeneralSettings] # The URL prefix of tag pages URLPrefix=tags/view # enabled shows the older children list in tags/id and tags/dashboard instead of the table ShowOldStyleChildrenList=disabled # New tags are created as always available DefaultAlwaysAvailable=false # Use Solr for the tag cloud when eZ Find is available TagCloudOverSolr=enabled # Number of suggestions of the autocomplete in content edit MaxResults=24 # start: match the start of a tag; any: match any part of it AutoCompleteType=start [TreeMenu] ToolTips=enabled # Children shown per tag in the tree, 0 for all MaxTags=100 AutoopenCurrentTag=enabled # Remember opened branches in a cookie MenuPersistence=enabled [Icons] # Icons from design/standard/images/tag_icons; IconMap[<tag ID>] applies to that tag and its subtree Default=empty.png IconMap[] #IconMap[1]=people.png [SearchSettings] # Results per page of tags/search SearchLimit=15 # Re-index related content when a tag changes and delayed indexing is off (slow) ReindexWhenDelayedIndexingDisabled=disabled # disabled: index the main tag instead of a synonym (useful for facets) IndexSynonyms=enabled # Also index the synonyms of a tag (needs IndexSynonyms=enabled) IncludeSynonyms=disabled # Also index the parent tags of a tag IndexParentTags=disabled [EditSettings] # The edit views a class attribute can choose AvailableViews[] AvailableViews[Default]=Default view AvailableViews[Select]=Select view AvailableViews[Tree]=Tree view
The extension also registers the datatype (content.ini), the taglink custom
tag (content.ini, ezoe_attributes.ini), its ezjscore server functions
ezjsctags and ezjsctagschildren (ezjscore.ini), the attribute filters
(extendedattributefilter.ini), the Solr field mapping (ezfind.ini) and the
admin tab (menu.ini).
Usage
1. Build the tag tree
Open the Tags tab in the administration. In the admin4 design it shows a
tags icon (Icon=tags in [Topmenu_eztags] of settings/menu.ini.append.php).
The tab opens the dashboard (tags/dashboard) with the tags at the root of the tree
and the tabs Latest tags, Latest content and Tags search.
- Add child tag (
tags/add/<parent tag ID>) adds a tag below another one, or at the root. - Open a tag (
tags/id/<tag ID>) to edit it, translate it, add a synonym, move it, merge it into another tag, make it a synonym, or delete it. - Show all content related to tag lists the content that uses it.
- Tags search (
tags/search) finds tags by name.
2. Add a tags attribute to a class
In Setup > Classes, edit a class (for example Article), add an attribute of the type Tags and choose:
- Limit by tags subtree: editors only pick tags below this tag;
- Hide root subtree limit tag when editing object: the subtree's root tag is not offered;
- Maximum number of allowed tags (0 for no limit);
- Edit view: Default, Select or Tree.
3. Tag content
When editors edit an object of that class, they type into the tags field and pick suggestions, or add new tags in place (if they may add tags there), or choose from the select list or the tree, depending on the edit view.
4. Show tags on the site
The bundled view template of the datatype links each tag to its tag page and adds the keywords to the page's meta keywords. In your own templates:
{foreach $node.data_map.tags.content.tags as $tag} <a href={$tag.url|ezurl}>{$tag.keyword|wash}</a> {/foreach}
The attribute content also has tag_ids, keywords, keyword_string,
meta_keyword_string, parent_string and tags_count.
A tag page (tags/view/<path>) renders design:tags/view.tpl with the variable
$tag; override that template in your site design to change it. A tag has,
among others, keyword, url, parent, children, children_count,
related_objects, related_objects_count, synonyms, main_tag,
is_synonym, path, icon and translations.
Template reference
Fetch functions
{* one tag *} {def $tag = fetch( tags, tag, hash( 'tag_id', 42 ) )} {def $tag = fetch( tags, tag_by_remote_id, hash( 'remote_id', '1143ae02e8c0995ccd15a1847e886328' ) )} {def $tag = fetch( tags, tag_by_url, hash( 'url', 'Countries/Croatia' ) )} {* all tags with a keyword *} {def $tags = fetch( tags, tags_by_keyword, hash( 'keyword', 'Croatia' ) )} {* the newest tags, optionally below a tag *} {def $latest = fetch( tags, latest_tags, hash( 'parent_tag_id', 42, 'limit', 10 ) )} {* children (list) or the whole subtree (tree) of a tag *} {def $tags = fetch( tags, tree, hash( 'parent_tag_id', 42, 'sort_by', array( 'modified', 'desc' ), 'offset', 0, 'limit', 15, 'depth', 4, 'depth_operator', 'le', 'include_synonyms', true() ) )} {def $count = fetch( tags, tree_count, hash( 'parent_tag_id', 42, 'depth', 4, 'depth_operator', 'le' ) )}
listandlist_countreturn the first level below a tag,treeandtree_countthe whole subtree;depthanddepth_operator(lt,gt,le,ge,eq) only apply to the tree fetches.sort_bysorts byid,parent_id,main_tag_id,keyword,depth,path_string,modifiedorremote_id, withascordesc.- Every fetch takes an optional
language(a locale like'cro-HR'or an array of locales). Without it, tags come in the languages ofsite.ini [RegionalSettings] SiteLanguageList.
More examples are in doc/USAGE.md.
Content by tag: attribute filters
{* content below node 2 that has tag 42 or tag 24 *} {def $nodes = fetch( content, list, hash( 'parent_node_id', 2, 'extended_attribute_filter', hash( 'id', 'TagsAttributeFilter', 'params', hash( 'tag_id', array( 42, 24 ) ) ) ) )}
| Filter ID | Matches content that has |
|---|---|
TagsAttributeFilter |
at least one of the tags in tag_id |
TagsAttributeAndFilter |
all of the tags in tag_id |
TagsAttributeAndMultipleFilter |
at least one tag of every group: tag_id is an array of groups, e.g. array( array( 1, 2 ), array( 3 ) ) |
TagsTreeAttributeFilter |
a tag anywhere below parent_tag_id (an ID or an array); exclude_parent leaves out the parent tag itself, type 'and' requires every parent |
The tag filters take include_synonyms (synonyms count unless you pass
false()) and language.
Template operators
{* a tag cloud, from Solr when eZ Find is available, else from the database *} {eztagscloud( hash( 'class_identifier', 'article', 'parent_node_id', 2, 'offset', 0, 'limit', 20, 'sort_by', array( 'count', false() ), 'post_sort_by', 'keyword' ) )} {* "Countries / Croatia": the path of a tag, with "(+n)" after tags that have synonyms *} {eztags_parent_string( 42 )} {* the image URL of a tag icon, small (default) or normal *} <img src="{$tag.icon|tag_icon}" alt="" /> {* the policy limitations of the current user for a module function *} {def $access = user_limitations( 'tags', 'add' )}
sort_by of the cloud sorts by keyword or count, true() ascending; the
optional post_sort_by (keyword, keyword_reverse, count, count_reverse)
sorts the result again. latest_tags( 10 ) still works but is deprecated: use
fetch( tags, latest_tags, ... ).
Rich text
The custom tag taglink (attribute tag, the tag ID, plus optional id,
title, target and class) links a piece of text to a tag page.
Permissions
The module tags has these policy functions (module.php):
| Function | Views | Use |
|---|---|---|
read |
treemenu |
The tag tree menu. |
view |
view |
Tag pages on the site; give it to Anonymous. |
dashboard |
dashboard |
The admin tab; the tab is only shown with it. |
id |
id, list_objects |
A tag's admin page and its content. |
search |
search |
Searching tags in the admin. |
add |
add |
Adding tags; can be limited to a tag subtree (limitation Tag). |
addsynonym, editsynonym, deletesynonym |
same names | Managing synonyms. |
edit |
edit, movetags, translation |
Editing, moving and translating tags. |
delete |
delete, deletetags |
Deleting tags. |
makesynonym, merge |
same names | Turning a tag into a synonym, merging tags. |
Editors who may add new tags while editing content need add for the subtree of
the attribute.
Scripts
Convert an ezkeyword attribute to an eztags attribute of the same class. The
keywords become tags below --parent-tag-id. The script updates the published
versions in place, so clear the caches and re-index afterwards:
php extension/eztags/bin/php/convertezkeyword.php \
--from-attr-id=123 --to-attr-id=456 --parent-tag-id=42
update/common/scripts holds the scripts that older upgrades call for (see
doc/UPGRADE.md). eZ Tags has no cron jobs.
Upgrading
- Replace
extension/eztagswith the new release (composer update se7enxweb/eztags, or unpack the archive over it). - Read the release notes on https://github.com/se7enxweb/eztags/releases.
Upgrades from versions before 2.2 have database steps, described in
doc/UPGRADE.md (
update/database/<mysql|postgresql>). - Regenerate the autoloads and clear the caches (installation step 4).
Known limits
- The
eztagsdatatype cannot be used for sorting, nor in the plainattribute_filterof content fetches; use the attribute filters above. - Suggestions, related tags and the Solr tag cloud need eZ Find with the two schema fields of installation step 7.
- With delayed indexing off, editing a tag does not re-index the content that uses
it unless
ReindexWhenDelayedIndexingDisabled=enabled.
Troubleshooting
- Visitors get "access denied" on tag pages: give Anonymous tags / view.
- The Tags tab is missing: the user needs tags / dashboard; clear the caches after activating the extension.
- No suggestions in the tags field: check that ezjscore is active, and for Solr suggestions that eZ Find is configured with the two schema fields.
- The tag cloud is empty with eZ Find: re-index after adding the schema
fields, or set
TagCloudOverSolr=disabledto use the database. - New classes or templates are not found: regenerate the autoloads and clear the caches.
Contributing
Bug reports and pull requests are welcome at https://github.com/se7enxweb/eztags. Please state the Exponential and PHP versions and how to reproduce the problem.
License and credits
eZ Tags is licensed under the GNU General Public License v2.0 (or any later version), see LICENSE.
eZ Tags was created by Netgen for eZ Publish, whose legacy line its creator later
discontinued, with contributions from the eZ Community; Netgen continued it for
newer platforms as the Netgen Tags Bundle.
The history of the early versions is in doc/CHANGELOG.md, and
a user manual of that time is in doc/eztags-user-manual.pdf. 7x and the
Exponential Foundation maintain eZ Tags for Exponential.