Lá está, da má documentação publicamente acessível também não tenho a certeza, até porque literalmente nunca trabalhei com o XenForo (ou qualquer outro sistema do género), mas do que li fiquei com a ideia de que existia um menu que permitiria criar ou modificar as templates (e, por extensão, activar/desactivar/apagar as modificações de templates). Depois, suponho, seria uma questão de testar essas modificações num fórum/numa
thread privada e inacessível aos utilizadores, para não haver quaisquer problemas ou queixas dos utilizadores...
Não tenho a certeza se o sistema te permite limitar o uso dessas modificações apenas a alguns fóruns ou
threads em específico, mas quanto a isso terias uma alternativa: especificares os fóruns/as
threads em que farias isso. Do que vejo, a forma de modificar as templates segue um mecanismo de
search and replace, confesso que só não sei o que pesquisar neste caso, mas do que li, na parte do
replace, seria só:
Código:
<xf:set var="$desired_forum_node_id" value="{{ [ 111, 999 ] }}" />
<xf:set var="$desired_thread_ids" value="{{ [ 1000000 ] }}" />
<xf:if is="{{ (in_array({$forum.node_id}, {$desired_forum_node_ids}) or in_array({$thread.thread_id}, {$desired_thread_ids})) and ({$post.isFirst) }}">
... Aquela Tanga Toda Do Post Anterior ...
<xf:else/>
$0
</xf:if>
Aquele §0 manda espetar ali com o texto todo do match feito no search and replace. Ou seja, isto asseguraria que, fora dos casos em que o forum_node_id fosse o especificado em <xf:set var="§desired_forum_node_id" value="{{ [ 111, 999 ] }}" /> ou o thread_id fosse o especificado em <xf:set var="§desired_thread_ids" value="{{ [ 1000000 ] }}" />, o código da template seria exactamente igual ao que lá estava antes, sem afectar mais nada. Ah, e claro, que isto só afecta o primeiro
post de cada thread, como desejado.
Agora, vai depender das templates que já existem e como estão escritas, mas suponho que vamos querer editar alguma coisa que diga
post content ou coisa do género.
Pesquisando um pouco, encontrei alguma informação publicamente acessível que me leva a acreditar que deve haver uma
post template que, algures pelo meio, terá um código do género:
Código:
<article class="message-body js-selectToQuote">
<xf:ad position="post_above_content" arg-post="{$post}" />
{{ bb_code($post.message, 'post', $post) }}
<div class="js-selectToQuoteEnd"> </div>
<xf:ad position="post_below_content" arg-post="{$post}" />
</article>
Neste caso, suponho que possamos fazer o search and replace do seguinte modo:
Search:
Código:
{{ bb_code($post.message, 'post', $post) }}
Replace:
Código:
$0
<xf:set var="$zz_uni_desired_forum_node_id" value="{{ [ 111, 999 ] }}" />
<xf:set var="$zz_uni_desired_thread_ids" value="{{ [ 1000000 ] }}" />
<xf:if is="{{ (in_array({$forum.node_id}, {$zz_uni_desired_forum_node_ids}) or in_array({$thread.thread_id}, {$zz_uni_desired_thread_ids})) and ({$post.isFirst) }}">
<xf:set var="$zz_uni_post_list" value="{{ {$thread}.posts }}" />
<xf:set var="$zz_uni_separators" value=",;|" />
<xf:set var="$zz_uni_max_msg_length" value="512" />
<xf:set var="$zz_uni_msg_list" value="{{ array_filter(array_map(function($elem){ if (strlen($elem.message) < {$zz_uni_max_msg_length}) { $ret = preg_split ("/(\s*[" . {$zz_uni_separators} . "]*\s*)*[" . {$zz_uni_separators} . "]+(\s*[" . $zz_uni_separators . "]*\s*)*/",$elem.message); if (count($ret) >= 4) { return $ret; } } return; }, {$zz_uni_post_list} ) ) }}" />
<xf:set var="$zz_uni_sorted_list" value="{{ usort({$zz_uni_msg_list}, function(&$a, &$b){ $cmp1 = strnatcmp($a[count($a)-1], $b[count($b)-1]); if($cmp1 == 0) { $cmp2 = strnatcmp($a[count($a)-2], $b[count($b)-2]); if($cmp2 == 0) { return strnatcmp($a[0], $b[0]); } else { return $cmp2; } } else { return $cmp1; } } ) }}">
<xf:set var="$zz_uni_curr_val" value="Nowhere" />
<table style="width:100%">
<tr>
<th>Nome</th>
<th>Nota de Candidatura</th>
<th>Curso</th>
<th>Instituição</th>
</tr>
<xf:foreach loop="$zz_uni_sorted_list" key="$key1" value="$zz_msg" i="$i">
<xf:if is="{{ strcmp({$zz_uni_curr_val}, {$zz_msg}[count({$zz_msg})-1] ) != 0 }}" >
<xf:set var="$zz_uni_curr_val" value="{{ {$zz_msg}[count({$zz_msg})-1] }}" />
<tr height = 20px></tr>
</xf:if>
<xf:foreach loop="$zz_msg" key="$key2" value="$zz_text" i="$j">
<xf:if is="{{ j == 0}}">
<tr>
<td>{$zz_text}</td>
<td>
<xf:elseif is="{{ j == 1 }}" />
{$zz_text},
<xf:elseif is="{{ j == count({$zz_msg})-2 }}" />
</td>
<td>{$zz_text}</td>
<xf:elseif is="{{ j == count({$zz_msg})-1 }}" />
<td>{$zz_text}</td>
</tr>
<xf:else />
{$zz_text}
</xf:if>
</xf:foreach>
</xf:foreach>
</table>
</xf:if>
(Devo destacar que corrigi um erro no código anterior e introduzi uma optimização que faz todo o sentido, que é evitar um dos loops feitos na template syntax e usar uma função nativa do PHP. Outra alteração, que penso que pode ser relevante para garantir que não há nenhum problema se se escreverem
posts muito compridos em vez daqueles com o formato pretendido, é só executar as funções que vão analisar o
post para obter as informações (Nome, Instituição, etc.) em mensagens que tenham um comprimento inferior a §zz_uni_max_msg_length (512 caracteres, o valor actual, dá para uma mensagem absurdamente comprida para o que é pretendido; poderíamos até reduzir mais ainda, só por segurança, mas em princípio - se tudo correr bem - não será um problema). Além disso, para impedir quaisquer problemas de variáveis com o mesmo nome, introduzi um prefixo zz_ ou zz_uni_ naquelas que estamos a definir neste código.)
Isto, se correr tudo bem, irá permitir que se escreva a mensagem do post como normalmente, mas, no fim (espero eu que antes da assinatura e tudo o mais), aparece a desejada tabelinha. Basta ajustar §zz_uni_desired_forum_node_id e/ou §zz_uni_desired_thread_ids para os valores relevantes.
Risk assessment de se fazer este
search and replace:
Se a template for inválida ou não compilar ou coisa do género, pode haver temporariamente problema em apresentar os posts.
Probabilidade: ?? (eu sou reconhecidamente idiota, o código foi escrito por mim,
ergo, o código pode ter problemas).
Solução imediata: apagar/inibir essa modificação da templates.
Se a avaliação destas templates for até ao fim mesmo quando a condição no if não é verdaeira, pode demorar mais uns milissegundos a carregar uma
thread (dependendo do número total de
posts, mas nem mesmo o Diário deve ser assim tão grave, visto que nunca temos muito mais de 2000
posts...).
Probabilidade: baixa (em princípio, uma implementação mentalmente sã de uma condição não vai prejudicar a eficiência executando ambos os ramos dessa condição [à parte
branch predicting nos CPU, mas estamos tão, tão longe disso aqui...])
Solução/Mitigação: optimizar? Dado que os meus conhecimentos de PHP são limitados, não serei a pessoa certa para determinar o que poderemos fazer melhor, mas, no limite desses mesmos conhecimentos, não estou bem a ver o que poderíamos fazer de outro modo... Aliás, até incluí a questão de só irmos percorrer mensagens inferiores a §zz_uni_max_msg_length para evitar mais perdas de tempo.
Fora isto, não penso que haja quaisquer outros
side effects possíveis, embora, lá está, não possa dar 100% de garantias.
(Só estou a perder algum tempo com isto tudo porque penso que poderia ser um alívio para os moderadores. Vocês bem merecem o descanso.

)
EDIT: O malandro do LaTeX a querer transformar os cifrões em símbolos para inline math, substituí por "§" no texto corrido...