Tag Cloud 'slug'

Topics: Administration, General
Jan 3, 2015 at 1:55 PM
originally I opened issue 20610: "tag cloud buckets not recognised 1.8"
The original 'bucket' issue has been solved BUT there were quite some discussions re using the 'slug'.
I realize now that some discussions around 'slug' say: 'issue solved'!
HOWEVER, whatever I try I CANNOT reduce the scope of the 'tag cloud' e.g. to specific ContentType using the 'slug' field!
PS: when leaving the 'slug' field blank ALL is fine with my 'Tag Cloud'.

Thanks for anybodies time helping. I must misunderstand something!
Environment: 1.8.1

What do I try to do:
I defined a ContentType 'flash' which includes the 'tags' Part. I would like to reduce the 'Tag Cloud' to tags defined ONLY in the 'flash' CT i.e tags only defined in 'flash' ContentItems!.

When entering for 'slug' just 'flash' nothing is found! The same when entering '/' (like the help text says!)!
I must misunderstand something here
Thanks for your help and time
Jan 3, 2015 at 9:17 PM
Edited Jan 3, 2015 at 9:30 PM
Look at the comments in the tag cloud widget settings
Enter the slug of the container for which you want the tag cloud, e.g. blog, /, or leave empty for the cloud to be scoped to the whole site
The tags scope is related to the container, not the content type. So, if you leave empty, that means tags of the whole site, "blog" for the blog area...

Jan 4, 2015 at 1:57 AM
But, it doesn't work (tested on a 1.8.x version)

First, I thought that the slug is related to a normal content item (not container and not content type) and I have first done an update that works in this idea. But, when I saw that by design slug is related to a container, I tried the original code that doesn't work

In fact, a container is a special content item that can contain others content items. It can be a blog, a list created with the List module, or your own specific content type with a container part. All tested with the following update, it works

Because a container is a content item, the following update is part of what I have done to associate the slug to a normal content item

.Select(x => x.Id)
.Select(x => x.ContentItemRecord.Id)
If you really want to associate the slug to a normal content item (not its container if it exists), even it's not by design, you have to replace
.Where(t => t.Container.Id == containerId)
.Where(t => t.ContentItemRecord.Id == containerId)
My advise is to apply only the 1st update. So, in your case, to associate the slug to a specific content type, create another content type with a "Container part" and with a Title and Autoroute part (you can also use a "List" from the List module). Create an instance of this container, in the autoroute part use the slug you want (if after you forgot this slug, go to the "Aliases" page to retrieve it). And associate this container with your first specific content type

After that, you have to add to your first content type a "Containable part", then, you can create and publish content items of this type. Finally, in your tag cloud widget, input the slug of your container (without starting with "/", as it is displayed in the Aliases page). Finally, go to "Content", edit your container and here add the items that you want to associate with your container

You will see the tags related to the items of your specific content type, but remember, only those that have been added to your container

Note: On the front-end, it's not required to use your container, you can use the items of your specific content type as before

Jan 4, 2015 at 1:38 PM
Edited Jan 5, 2015 at 6:27 AM
Hi jt, that was a handfull ... thanks again for your time.
Your guidance gave me the base to understand the idea behind the TagCloud 'slug'!
thanks, ed

PS: An afterthought: wouldn't this justfy (or obligate!) opening an issue? After all 'TagCloudServices.cs' needs to be changed.
Jan 5, 2015 at 6:10 PM
well, it never ends ...

Now where I've the 'slug / container business' under control I'm struggling again with the 'Bucket=1; in TagCount.cs!

I've on the same CI two TagCloud widgets A + B
A: leaving the 'slug' field blank i.e. see tags of complete Site. Buckets are ALL ok!
B: using a 'slug / container' config. In this Tag cloud the items are coming BUT both are in Bucket=1;
the source code gives me two different <li> items BUT both having 'tag-cloud-tag-1'
again: this is all ok under A!

In the issue (20610) I opened sebastien once mentioned 'solved'. Obviously under certain circumstances its still an issue.
After some moreinvestigation I might open a new thread/issue!
Jan 5, 2015 at 8:50 PM
Edited Jan 5, 2015 at 8:59 PM
First, because I have seen that a container, even it can be unpublished / published, has always only one version, I wasn't using the .Published property. But, @j3ffb (see workitem #21124) has found the case where you delete a content item (e.g a page), and after you create a container (e.g a blog) with the same slug. Then, in the autoroute table, the first "slug" found isn't the right one

So, in TagCloudService.cs, including the 1st update of my previous post, replace
 .Where(c => c.DisplayAlias == slug)
 .Select(x => x.Id)
 .Where(c => c.DisplayAlias == slug && c.ContentItemVersionRecord.Published)
 .Select(x => x.ContentItemRecord.Id)
Note: @j3ffb propose a pull request where he use the content manager in place of the autoroute repository

That said, for the buckets, it works for me on a 1.8.x version. At the beginning, I though that it didn't work, but it was because I was using only a few tags, and I had to decrease the Buckets setting from 5 to 3. If Buckets = 5 and the count of your most popular tag is 3, all your tags will be in Bucket=1

Finally, for the Slug setting, remember to use your container slug without a starting "/"

Jan 6, 2015 at 7:49 PM
thanks again for the case of deleted Items!

apropos 'Buckets': the bucket # must obviously be <= the most popular tag!

Again, many thanks for your time and hints
hope certain changes will be seen in 1.9
Feb 11, 2015 at 5:04 PM
Edited Feb 11, 2015 at 5:05 PM
I am experiencing that if I use a number above 4 for buckets the Tag Cloud does not render the sizes. I tried pulling the latest code today http://orchard.codeplex.com/SourceControl/latest#src/Orchard.Web/Modules/Orchard.Tags/Services/TagCloudService.cs

It works well with bucket=4
<ul class="tag-cloud">
<li class="tag-cloud-tag tag-cloud-tag-2">
    <a href="/Tags/C%23">C#</a>
<li class="tag-cloud-tag tag-cloud-tag-2">
    <a href="/Tags/Games">Games</a>
<li class="tag-cloud-tag tag-cloud-tag-1">
    <a href="/Tags/Infographics">Infographics</a>
<li class="tag-cloud-tag tag-cloud-tag-2">
    <a href="/Tags/Javascript">Javascript</a>
<li class="tag-cloud-tag tag-cloud-tag-4">
    <a href="/Tags/Orchard">Orchard</a>
<li class="tag-cloud-tag tag-cloud-tag-1">
    <a href="/Tags/Reporting">Reporting</a>
<li class="tag-cloud-tag tag-cloud-tag-1">
    <a href="/Tags/Typescript">Typescript</a>

If I type any higher value all li becomes tag-cloud-tag-1

If I select in SQL with this
SELECT t.*, COUNT(ctr.Id) as [Count]
FROM [SQL2012_710384_em].[dbo].[orc_Orchard_Tags_ContentTagRecord] ctr
INNER JOIN [dbo].[orc_Orchard_Tags_TagRecord] t ON ctr.TagRecord_Id = t.Id
GROUP BY ctr.TagRecord_Id,t.Id, t.TagName

My result is:
Id TagName Count
1 Orchard 5
2 C# 2
3 Games 2
4 Javascript 2
5 Typescript 1
6 Reporting 1
7 Infographics 1

Anyone else getting this problem? Should I file a bug?
Feb 11, 2015 at 10:50 PM
Somewhere in TagCloudService.cs you have
                var maxDistance = maxCount - minCount;
                for (int i = 0; i < centroids.Length; i++) {
                    centroids[i] = maxDistance/buckets * (i+1);
In your case, maxDistance = (5-1) = 4
So, if buckets > 4, maxDistance/buckets is always equal to 0

Feb 12, 2015 at 6:30 AM
Edited Feb 12, 2015 at 7:24 AM
Thank you for the quick reply. This makes sense but I think it is possible to make it more robust so buckets cannot exceed maxDistance.

I changed this
var centroids = new int[buckets];
var maxCount = tagCounts.Any() ? tagCounts.Max(tc => tc.Count) : 0;
var minCount = tagCounts.Any() ? tagCounts.Min(tc => tc.Count) : 0;
var maxDistance = maxCount - minCount;
To this
var maxCount = tagCounts.Any() ? tagCounts.Max(tc => tc.Count) : 0;
var minCount = tagCounts.Any() ? tagCounts.Min(tc => tc.Count) : 0;
var maxDistance = maxCount - minCount;
buckets = maxDistance < buckets ? maxDistance : buckets;
var centroids = new int[buckets];
And it seems to fix the behaviour the way i want it.
Feb 12, 2015 at 2:57 PM
@RolfVS, thanks for this interesting idea