? No Code Attached Yet
avatar WM-Loose
WM-Loose
9 Mar 2023

System:
Joomla 4.2.8 PHP8.1

Problem:
If you sort the keywords (tags) in the backend as you are used to from the menus or posts (e.g. manually according to the order), it has no effect on the order displayed in the frontend. The frontend will only sort from a-z.

This suggestion did not solve the problem:
https://forum.joomla.org/viewtopic.php?t=970050

In the backend you can sort the list manually, but it has no influence on the display in the frontend, the selection of the manual order is not available at all (you can look under the options of the Tags component). And what you set in the component has no effect on the display of the tags in the post, the tags are always sorted from A-Z here.

If there is no bug, it would make sense to include it in an upcoming version.

avatar WM-Loose WM-Loose - open - 9 Mar 2023
avatar joomla-cms-bot joomla-cms-bot - change - 9 Mar 2023
Labels Added: No Code Attached Yet
avatar joomla-cms-bot joomla-cms-bot - labeled - 9 Mar 2023
avatar Hackwar Hackwar - change - 9 Mar 2023
Labels Added: ?
avatar Hackwar Hackwar - labeled - 9 Mar 2023
avatar Sieger66
Sieger66 - comment - 9 Mar 2023

The frontend will only sort from a-z.

No, i think that is not correct:
Standard in core is, the tags displays always unfortunatly by Tags-id number in the frontend.

avatar dgrammatiko
dgrammatiko - comment - 13 Mar 2023

Standard in core is, the tags displays always unfortunatly by Tags-id number in the frontend.

Nope, the tags are displayed in the order they were inserted. I had a PR that would allow reordering the tags: #19642

avatar brianteeman
brianteeman - comment - 13 Mar 2023

order they were inserted === tags id

avatar dgrammatiko
dgrammatiko - comment - 13 Mar 2023

order they were inserted === tags id

You are confused. The order is essentially the order the user typed or selected the tags:

$this->value = explode(',', $this->value);

The tags order by id you're referencing is about how the list of available tags are displayed in the dropdown:

protected function getOptions()
{
$published = (string) $this->element['published'] ?: [0, 1];
$app = Factory::getApplication();
$language = null;
$options = [];
// This limit is only used with isRemoteSearch
$prefillLimit = 30;
$isRemoteSearch = $this->isRemoteSearch();
$db = $this->getDatabase();
$query = $db->getQuery(true)
->select(
[
$db->quoteName('a.id', 'value'),
$db->quoteName('a.path'),
$db->quoteName('a.title', 'text'),
$db->quoteName('a.level'),
$db->quoteName('a.published'),
$db->quoteName('a.lft'),
]
)
->from($db->quoteName('#__tags', 'a'));
// Limit Options in multilanguage
if ($app->isClient('site') && Multilanguage::isEnabled()) {
if (ComponentHelper::getParams('com_tags')->get('tag_list_language_filter') === 'current_language') {
$language = [$app->getLanguage()->getTag(), '*'];
}
} elseif (!empty($this->element['language'])) {
// Filter language
if (strpos($this->element['language'], ',') !== false) {
$language = explode(',', $this->element['language']);
} else {
$language = [$this->element['language']];
}
}
if ($language) {
$query->whereIn($db->quoteName('a.language'), $language, ParameterType::STRING);
}
$query->where($db->quoteName('a.lft') . ' > 0');
// Filter on the published state
if (is_numeric($published)) {
$published = (int) $published;
$query->where($db->quoteName('a.published') . ' = :published')
->bind(':published', $published, ParameterType::INTEGER);
} elseif (\is_array($published)) {
$published = ArrayHelper::toInteger($published);
$query->whereIn($db->quoteName('a.published'), $published);
}
$query->order($db->quoteName('a.lft') . ' ASC');
// Preload only active values and 30 most used tags or fill up
if ($isRemoteSearch) {
// Load the most $prefillLimit used tags
$topQuery = $db->getQuery(true)
->select($db->quoteName('tag_id'))
->from($db->quoteName('#__contentitem_tag_map'))
->group($db->quoteName('tag_id'))
->order('count(*)')
->setLimit($prefillLimit);
$db->setQuery($topQuery);
$topIds = $db->loadColumn();
// Merge the used values into the most used tags
if (!empty($this->value) && is_array($this->value)) {
$topIds = array_unique(array_merge($topIds, $this->value));
}
// Set the default limit for the main query
$query->setLimit($prefillLimit);
if (!empty($topIds)) {
// Filter the ids to the most used tags and the selected tags
$preQuery = clone $query;
$preQuery->clear('limit')
->whereIn($db->quoteName('a.id'), $topIds);
$db->setQuery($preQuery);
try {
$options = $db->loadObjectList();
} catch (\RuntimeException $e) {
return [];
}
// Limit the main query to the missing amount of tags
$count = count($options);
$prefillLimit = $prefillLimit - $count;
$query->setLimit($prefillLimit);
// Exclude the already loaded tags from the main query
if ($count > 0) {
$query->whereNotIn($db->quoteName('a.id'), ArrayHelper::getColumn($options, 'value'));
}
}
}
// Only execute the query if we need more tags not already loaded by the $preQuery query
if (!$isRemoteSearch || $prefillLimit > 0) {
// Get the options.
$db->setQuery($query);
try {
$options = array_merge($options, $db->loadObjectList());
} catch (\RuntimeException $e) {
return [];
}
}
// Block the possibility to set a tag as it own parent
if ($this->form->getName() === 'com_tags.tag') {
$id = (int) $this->form->getValue('id', 0);
foreach ($options as $option) {
if ($option->value == $id) {
$option->disable = true;
}
}
}
// Merge any additional options in the XML definition.
$options = array_merge(parent::getOptions(), $options);
// Prepare nested data
if ($this->isNested()) {
$this->prepareOptionsNested($options);
} else {
$options = TagsHelper::convertPathsToNames($options);
}
return $options;
}

To clear this up: the dropdown for selecting a tag is ordered by ID, the display of selected tags is by the order the user inserted/typed the tags

avatar brianteeman
brianteeman - comment - 13 Mar 2023

i am not confused at all

Add a Comment

Login with GitHub to post a comment