If you don't mind using a plugin, Similar would work very well for your use case:
{% set relatedEntries = craft.similar.find({
element: entry,
context: entry.tagsField.ids()|merge(entry.blogCategory.ids()),
criteria: {
section: 'blog',
limit: 3
}
}) %}
Of course, be sure to replace tagsField
in the above example with the actual handle for your entry type's Tags field.
By default, the entries returned by Similar will be ordered after the number of relations in common with the current entry
(or whatever you pass into the element
parameter). In other words, the entry with the most tags and/or categories in common with the current entry
will be the first. The entries returned by Similar will also have an entry.count
attribute that will indicate the number of relations in common with the current entry.
If you want to do this without a plugin, it's possible to add multiple criteria to the relatedTo
parameter in order to pull entries that has either one or more categories or tags in common with the current entry:
{% set relatedEntries = craft.entries({
section: 'blog',
relatedTo: ['or', {
targetElement: entry.blogCategory.ids(),
field: 'blogCategory'
}, {
targetElement: entry.tagsField.ids(),
field: 'tagsField'
}],
id: 'not ' ~ entry.id,
limit: 3
}) %}
I'm not aware of a way to query the EntriesService for the 3 entries with the most relations in common with entry
, though (the lack of such a feature is why the Similar plugin exists). I guess this could be achieved in plain Twig by possibly setting the limit
parameter to null
(to return all entries – yikes! performance), looping over the returned entries and comparing the number of relations in entry.tagsField
and entry.blogCategory
to each related entry and add the entries to an array ordered by the amount of relations somehow, but I suspect it will get pretty dirty and quickly go beyond what Twig is designed to comfortably do, logic-wise.