XF 2.3 Collapse long subforum lists with "More..." link?

darkeye

Active member
Licensed customer
On the forum list, some parent forums have quite a large number of subforums. For example, a manufacturer forum might contain 10 or 11 model subforums plus a general discussion forum.

To make the forum list cleaner and more compact, I'd like to display only the first six subforums by default. Below them, there would be an expandable link such as:

More models (5)

Clicking the link would reveal the remaining subforums. Ideally, all subforum links would still be present in the HTML so they remain visible to search engines.

The goal is purely to improve the appearance and usability of the forum list without affecting SEO.

Would something like this be possible with XenForo, either natively, via an add-on, or with a template modification?
 
or with a template modification?

Yes, this can be done with a template modification and a small amount of CSS.

This assumes your sub-forums are set to display as “Listed below node,” not as the popup menu style.

Go to:

Admin CP → Appearance → Template modifications → Add template modification

Template: forum_list
Search type: Regular expression

Find:

#<div class="node-subNodesFlat">\s*<span class="node-subNodesLabel">\{\{ phrase\('sub_forums:'\) \}\}</span>\s*<ol class="node-subNodeFlatList">\s*<xf:contentcheck>(.[I]?)</xf:contentcheck>\s[/I]</ol>\s*</div>#s

Replace:

<div class="node-subNodesFlat xenc-subNodesLimited">
<xf:if is="{{ count($children) > 6 }}">
<xf:set var="$xencSubNodesToggleId" value="{{ unique_id('xencSubNodes') }}" />
<input type="checkbox" class="xenc-subNodesToggleInput" id="{$xencSubNodesToggleId}" hidden />
</xf:if>

<span class="node-subNodesLabel">{{ phrase('sub_forums:') }}</span>

<ol class="node-subNodeFlatList">
<xf:contentcheck>$1</xf:contentcheck>
</ol>

<xf:if is="{{ count($children) > 6 }}">
<label for="{$xencSubNodesToggleId}" class="xenc-subNodesToggle">
<span class="xenc-subNodesMoreText"
data-more="More sub-forums ({{ count($children) - 6 }})"
data-less="Show fewer"></span>
</label>
</xf:if>
</div>
 
Then add this to extra.less:

[data-template="forum_list"]
{
.xenc-subNodesLimited
{
.node-subNodeFlatList > li:nth-child(n+7)
{
display: none;
}

.xenc-subNodesToggleInput:checked ~ .node-subNodeFlatList > li:nth-child(n+7)
{
display: inline-block;
}

.xenc-subNodesToggle
{
display: inline-block;
margin-top: 3px;
cursor: pointer;
font-weight: 600;
color: @xf-linkColor;
}

.xenc-subNodesToggle:hover
{
text-decoration: underline;
}

.xenc-subNodesMoreText:before
{
content: attr(data-more);
}

.xenc-subNodesToggleInput:checked ~ .xenc-subNodesToggle .xenc-subNodesMoreText:before
{
content: attr(data-less);
}
}
}
 
That should show the first six sub-forums by default, then display a “More sub-forums (X)” toggle when there are more than six. The remaining links are only hidden with CSS, so they are still present in the rendered HTML.

If you specifically want the text to say “More models” instead, change this line:
data-more="More sub-forums ({{ count($children) - 6 }})"
to this:
data-more="More models ({{ count($children) - 6 }})"
 
Back
Top Bottom