XF 2.2 Modifying thread titles in threads list


Well-known member

Here is my dilemma: one of my forum's category is 'Fishing Reports' with subforums 'Rivers' and 'Lakes' withing.
Threads in those forums have names of water bodies: "Detroit Lake", "Salmon River" etc.

From SEO point of view, I'd better name threads 'Detroit Lake Fishing Reports', 'Salmon River Fishing Reports', etc. In this case, titles would have keywords in it, as well as urls. However, it would be not user friendly, as a forum view page would be overstuffed with the words "fishing reports" in every thread title.

I'm thinking about the best solution - to have keywords, and not overstuffing threads list. And I guess I could do it by placing conditional in forum view template
like if node id is x or y.... modify '{thread_title}' to '{thread_title} Fishing Reports'. But all those extensions and macros are a little bit too complicated for me. )
Give me some help please with what and where to modify.


Well-known member
It looks like a template I'm looking for is thread_list_macros.
Also, I realized, that I need to do quite opposite from what I described yesterday. )
If I want keywords "fishing reports" in page titles & urls, I need to call threads 'Water Body Fishing Reports', and in thread list I'll have to remove 'fishing reports', not to add.
I didn't have an idea how to do that, I have no idea how to do this. )

Mr Lucky

Well-known member
This will work, seems simple and elegant BUT but Fishing Reports will be at the beginning of the title.
  • Make a thread prefix Fishing Reports
  • Give it a custom class
  • Set the forum so people must use a prefix.

In your extra.less template make that custom class display=none

The prefix will be invisible to users, but it will be in the meta title.

Hopefully Google does not see this as cloaking, I don't think so.

EDIT: problem to solve: users don't actually see the prefix now in the prefix list when starting the thread - Doh!
Last edited:


Well-known member
Thanks @Mr Lucky ! I guess I figured this one out. Just in case someone will try to do something similar:

In thread_list_macros I replaced
                <a href="{{ link('threads' . (($thread.isUnread() AND !$forceRead) ? '/unread' : ''), $thread) }}" class="" data-tp-primary="on" data-xf-init="{{ $canPreview ? 'preview-tooltip' : '' }}" data-preview-url="{{ $canPreview ? link('threads/preview', $thread) : '' }}">{$thread.title}</a>
<xf:if is="{$forum.node_id} === xxx">
                <a href="{{ link('threads' . (($thread.isUnread() AND !$forceRead) ? '/unread' : ''), $thread) }}" class="" data-tp-primary="on" data-xf-init="{{ $canPreview ? 'preview-tooltip' : '' }}" data-preview-url="{{ $canPreview ? link('threads/preview', $thread) : '' }}">{$thread.title|replace({'Fishing Reports':null})}</a>               
<xf:else />
                <a href="{{ link('threads' . (($thread.isUnread() AND !$forceRead) ? '/unread' : ''), $thread) }}" class="" data-tp-primary="on" data-xf-init="{{ $canPreview ? 'preview-tooltip' : '' }}" data-preview-url="{{ $canPreview ? link('threads/preview', $thread) : '' }}">{$thread.title}</a>


Well-known member
Damn... and now I have 12k errors in Server error log... (

  • ErrorException: Template error: Illegal string offset 'node_id'
  • internal_data/code_cache/templates/l1/s31/public/thread_list_macros.php:262
It looks like I can't referrer to node_id in that template. Can someone advise how to do it properly, please?
Last edited:


Well-known member

Stack trace​

#0 internal_data/code_cache/templates/l1/s31/public/thread_list_macros.php(262): XF\Template\Templater->handleTemplateError(2, 'Illegal string ...', '/home/xxxxxxx/...', 262, Array)
#1 src/XF/Template/Templater.php(961): XF\Template\Templater->{closure}(Object(XF\Template\Templater), Array, Object(XF\Template\ExtensionSet))
#2 src/XF/Template/Templater.php(897): XF\Template\Templater->renderExtensionInternal('main_cell', Array, Array, Object(XF\Template\ExtensionSet))
#3 internal_data/code_cache/templates/l1/s31/public/thread_list_macros.php(508): XF\Template\Templater->renderExtension('main_cell', Array, Object(XF\Template\ExtensionSet))
#4 src/XF/Template/Templater.php(798): XF\Template\Templater->{closure}(Object(XF\Template\Templater), Array, Object(XF\Template\ExtensionSet))
#5 internal_data/code_cache/templates/l1/s31/public/xfes_widget_similar_threads.php(22): XF\Template\Templater->callMacro('thread_list_mac...', 'item', Array, Array)
#6 src/XF/Template/Templater.php(1598): XF\Template\Templater->{closure}(Object(XF\Template\Templater), Array, NULL)
#7 src/XF/Widget/WidgetRenderer.php(62): XF\Template\Templater->renderTemplate('xfes_widget_sim...', Array)
#8 src/XF/Widget/WidgetRenderer.php(67): XF\Widget\WidgetRenderer->render()
#9 src/XF/Template/Templater.php(1873): XF\Widget\WidgetRenderer->__toString()
#10 internal_data/code_cache/templates/l1/s31/public/thread_view.php(972): XF\Template\Templater->widgetPosition('thread_view_bel...', Array)
#11 src/XF/Template/Templater.php(1598): XF\Template\Templater->{closure}(Object(XF\Template\Templater), Array, Object(XF\Template\ExtensionSet))
#12 src/XF/Template/Template.php(24): XF\Template\Templater->renderTemplate('thread_view', Array)
#13 src/XF/Mvc/Renderer/Html.php(48): XF\Template\Template->render()
#14 src/XF/Mvc/Dispatcher.php(458): XF\Mvc\Renderer\Html->renderView('XF:Thread\\View', 'public:thread_v...', Array)
#15 src/XF/Mvc/Dispatcher.php(440): XF\Mvc\Dispatcher->renderView(Object(XF\Mvc\Renderer\Html), Object(XF\Mvc\Reply\View))
#16 src/XF/Mvc/Dispatcher.php(400): XF\Mvc\Dispatcher->renderReply(Object(XF\Mvc\Renderer\Html), Object(XF\Mvc\Reply\View))
#17 src/XF/Mvc/Dispatcher.php(58): XF\Mvc\Dispatcher->render(Object(XF\Mvc\Reply\View), 'html')
#18 src/XF/App.php(2300): XF\Mvc\Dispatcher->run()
#19 src/XF.php(464): XF\App->run()
#20 index.php(20): XF::runApp('XF\\Pub\\App')
#21 {main}

Request state​

array(4) {
["url"] => string(38) "/threads/my-brothers-first-carp.12625/"
["referrer"] => bool(false)
["_GET"] => array(0) {
["_POST"] => array(0) {