XF 2.2 How to get rich username working in phrases? (with tooltip)

Earl

Well-known member
<xf:username> is not working in phrases, but only in templates?

So I tried to pass it as a variable like this:
PHP:
public function getPhraseHtml(Suggestion $suggestion){
   $UserLink = \XF::app()->templater()->fnUsernameLink(\XF::app()->templater(), $escape, $suggestion->User, true);

   return \XF::phrase('user_x_thinks_this_has_to_be_changed', ['user'=>$userLink])

}

But, it doesn't get rendered in template. it just shows the HTML code.
 
Last edited:

Gobb

Member
<xf:username> is not working in phrases, but only in templates?

So I tried to pass it as a variable like this:
PHP:
function getPhraseHtml(Suggestion $suggestion){
   $UserLink = \XF::app()->templater()->fnUsernameLink(\XF::app()->templater(), $escape, $suggestion->User, true);

   return \XF::phrase('user_x_thinks_this_has_to_be_changed', ['user'=>$userLink])

}

But, it doesn't get rendered in template. it just shows the HTML code.
If you've made a function just specifically to try and build the username link for a phrase, which would be in a template, you would just do it like this assuming you're fetching the data joined with the user data:
Code:
{{ phrase('user_x_thinks_this_has_to_be_changed', {
    'user': username_link($suggestion.User, false, {'defaultname': $suggestion.User.username})}
    ) }}

But, if you're calling the phrase within a controller action specifically or something I'm no help, sorry.
 

Earl

Well-known member
Thank you very much for trying to help and replying.

If you've made a function just specifically to try and build the username link for a phrase, which would be in a template, you would just do it like this assuming you're fetching the data joined with the user data:
Code:
{{ phrase('user_x_thinks_this_has_to_be_changed', {
    'user': username_link($suggestion.User, false, {'defaultname': $suggestion.User.username})}
    ) }}

But, if you're calling the phrase within a controller action specifically or something I'm no help, sorry.
this is the phrase
sVtWIOa.png


and this is what it displays on page:
mk3DKHB.png


I'm trying to do this like in the approval_item_thread built-in template.
But this phrase part never gets to be used in a real template.
It gets rendered in handler

Here is a part in the template which renders the list of items, This foreach loop calls this suggestion_item macro
HTML:
        <xf:macro template="earl_cm_suggestions_list_macros" name="suggestion_item"
                  arg-messageHtml="{$messageHtml}"
                  arg-user="{$suggestion.Thread.User}"
                  arg-suggestionData="{$suggestion.getHandler().render($suggestion)|raw}"
                  arg-suggestion="{$suggestion}"
        />

arg-suggestionData renders the template inside of that handler and it passes the rendered contents to that macro.

When it get renders, Inside of that handler class has this public function getPhraseHtml method.

PHP:
public function getPhraseHtml(Suggestion $suggestion){
   $UserLink = \XF::app()->templater()->fnUsernameLink(\XF::app()->templater(), $escape, $suggestion->User, true);

   return \XF::phrase('user_x_thinks_this_has_to_be_changed', ['user'=>$userLink])

}

That method returns the HTML data after and puts it into another template which is the one being called in arg-suggestionData=
 
Last edited:

Gobb

Member
Thank you very much for trying to help and replying.


this is the phrase
sVtWIOa.png


and this is what it displays on page:
mk3DKHB.png


I'm trying to do this like in the approval_item_thread built-in template.
But this phrase part never gets to be used in a real template.
It gets rendered in handler

Here is a part in the template which renders the list of items, This foreach loop calls this suggestion_item macro
HTML:
        <xf:macro template="earl_cm_suggestions_list_macros" name="suggestion_item"
                  arg-messageHtml="{$messageHtml}"
                  arg-user="{$suggestion.Thread.User}"
                  arg-suggestionData="{$suggestion.getHandler().render($suggestion)|raw}"
                  arg-suggestion="{$suggestion}"
        />

arg-suggestionData renders the template inside of that handler and it passes the rendered contents to that macro.

When it get renders, Inside of that handler class has this public function getPhraseHtml method.

PHP:
public function getPhraseHtml(Suggestion $suggestion){
   $UserLink = \XF::app()->templater()->fnUsernameLink(\XF::app()->templater(), $escape, $suggestion->User, true);

   return \XF::phrase('user_x_thinks_this_has_to_be_changed', ['user'=>$userLink])

}

That method returns the HTML data after and puts it into another template which is the one being called in arg-suggestionData=
Ah, I've got you now. I'll try and have a look but I don't think I'll be of any help, so best of luck!
 

Earl

Well-known member
Ah, I've got you now. I'll try and have a look but I don't think I'll be of any help, so best of luck!
the problem is this line works
$UserLink = \XF::app()->templater()->fnUsernameLink(\XF::app()->templater(), $escape, $moderationSuggestion->User, true);
and gives value <a href="/index.php?members/jerry.3/" class="username " dir="auto" itemprop="name" data-user-id="3" data-xf-init="member-tooltip">Jerry</a> this is good html

but after that value being used in \XF:phrase() as an argument,
it escapes HTML characters.

PHP:
 $phrase =  \XF::phrase('user_x_thinks_this_has_to_be_changed', [
                'user' => $UserLink,
            ],true)->render();
            return $phrase;
here in $phrase gets this value
HTML:
User &lt;a href=&quot;/index.php?members/jerry.3/&quot; class=&quot;username &quot; dir=&quot;auto&quot; itemprop=&quot;name&quot; data-user-id=&quot;3&quot; data-xf-init=&quot;member-tooltip&quot;&gt;Jerry&lt;/a&gt; thinks this has to be changed

And thank you very much for trying to help! I really appreciate it.
 

Gobb

Member
the problem is this line works
$UserLink = \XF::app()->templater()->fnUsernameLink(\XF::app()->templater(), $escape, $moderationSuggestion->User, true);
and gives value <a href="/index.php?members/jerry.3/" class="username " dir="auto" itemprop="name" data-user-id="3" data-xf-init="member-tooltip">Jerry</a> this is good html

but after that value being used in \XF:phrase() as an argument,
it escapes HTML characters.

PHP:
 $phrase =  \XF::phrase('user_x_thinks_this_has_to_be_changed', [
                'user' => $UserLink,
            ],true)->render();
            return $phrase;
here in $phrase gets this value
HTML:
User &lt;a href=&quot;/index.php?members/jerry.3/&quot; class=&quot;username &quot; dir=&quot;auto&quot; itemprop=&quot;name&quot; data-user-id=&quot;3&quot; data-xf-init=&quot;member-tooltip&quot;&gt;Jerry&lt;/a&gt; thinks this has to be changed

And thank you very much for trying to help! I really appreciate it.
No worries. Is there a reason that you're trying to render the phrase in the way that you are? After reviewing the XenForo approval stuff, everything is in the templates and as you said in your first response, the render function in the template usually returns a template depending on the content type.

approval_queue is the base template, in the example of a thread this renders the template approval_item_thread where thread is the content type. Within that template itself is where standard XenForo phrases are called along with the other data that makes the list of items. From what I'm gathering based on what you've written, you're trying to do the same thing? One option would appear to be just making one of the arugments of the macro the phrase itself like the XenForo Macro. Again, unless I've misunderstood what you're trying to do.
 

Earl

Well-known member
No worries. Is there a reason that you're trying to render the phrase in the way that you are? After reviewing the XenForo approval stuff, everything is in the templates and as you said in your first response, the render function in the template usually returns a template depending on the content type.

approval_queue is the base template, in the example of a thread this renders the template approval_item_thread where thread is the content type. Within that template itself is where standard XenForo phrases are called along with the other data that makes the list of items. From what I'm gathering based on what you've written, you're trying to do the same thing? One option would appear to be just making one of the arugments of the macro the phrase itself like the XenForo Macro. Again, unless I've misunderstood what you're trying to do.
Yeah, I do have a reason and I'm trying to do something the same but a little bit different, I have to render different phrases depending on the content type as in approval_item_thread, , I have only different phrases for each content type but gets rendered in the same template, so I do not need different templates like approval_item_thread. I am gonna add another method named getPhraseName and call it from the inside of the getPhraseHtml method, so I can dynamically compile the HTML code of these phrases depending on the content type.

Why are you editing the master language instead of the language for your forum?
Because that phrase is a custom phrase that is only in the add-on I'm currently developing. In other way, that phrase is not a XenForo built-in phrase, it's a custom phrase I am adding with my add-on.
I guess editing language for the forum is something you have to do after you built the add-on and installed it on the production/staging site.

Pass "raw" string as argument to render() function. This is disable escaping phrase arguments.
Wow, I didn't see that one...! AND THAT'S IT!!!!!
Thank you so much for opening my eyes 🤓😬
( I couldn't post this thread as a question, and I feel regret now. @Chris D Please help, will you change the type of this thread to a question, and select @Kruzya 's reply as the answer. Thanks in advance. )
 
Top