XF 2.0 Context for BB Code Parsing/Rendering

Kirby

Well-known member
Either I am missing something or the context provided to the BB code subsytem is somewhat limited:

  • The Ruleset (\XF\BbCode\RuleSet) does get a "context" (post, conversation_message, etc.), but no information about the user or post
  • The Renderer (\XF\BbCode\Renderer\Html) does get the user as an option, but no information about what is actually being rendered
    It also does have access to the RuleSet, but not to the "context" within it as this is protected and there is no getter (of course I could add one, but that doesn't make much sense to me as other addons needing the same information would have to do the same).
If my observation is correct, it would be very useful if the full context (eg. type and the full post/conversation mesage, etc.) would somehow be accessible.
 
Last edited:
That would be so useful. Here's the horrendous bodge I've had to come up with:

PHP:
        $thread = \XF::repository('XF:Thread')->getThreadFromUrl(\XF::app()->request()->getRoutePath(), 'public', $error);
        if (!$thread)
        {
            // This must be outside the Show Thread page, ignore it
            return \XF::phrase('dbtech_credits_stripped_content');
        }

That's inside the callback class for my custom BBCode [CHARGE] that should strip the post content if the user has not purchased the content or is not the original poster of the content.

If there was a $context variable, something like
PHP:
[
    'content_type' => 'post',
    'context' => $entity // object(\XF\Entity\Post)
]

It would plz me greatly. I would be able to offer support for charging for viewing content outside of just threads, I would be able to ensure that no matter where the post was viewed, not only would the "do you want to buy this for X credits?" button work, but I would be able to detect authorised purchases...


Fillip
 
I've taken another hacky approach:

I modified post_macros to pass the post
Code:
{{ bb_code($post.message, 'post', $post.User, {
    'attachments': $post.attach_count ? $post.Attachments : [],
    'viewAttachments': $thread.canViewAttachments(),
    'post': $post
}) }}

So I can access it in the renderer
PHP:
if (isset($options['post']))
{
    // do smth. useful
}
 
I am pretty sure I know the difference between a manual template edit/modification and an automatic one, I wrote the "original" TMS for vBulletin ;)
 
The bbcode rendering is stubbornly context free. There is a User object passed very haphazardly, and not consistently at all.

For example; I can't see any sane way to just render a particular bbcode if the user posting it. The user object just isn't consistent even when it is coming from content with a user object associated with it.
 
Null Consistent Logics!

Code:
{{ bb_code($post.message, 'post', $post.User, {
    'attachments': $post.attach_count ? $post.Attachments : [],
    'viewAttachments': $thread.canViewAttachments(),
    'post': $post
}) }}

is not a good idea!
If several add-ons want to set parameters at the same place, this leads to problems

Screen_20171019121344.webp

######

As context is "'{$bbCodeContext}'" set!

eg: Template "widget_new_threads" is ok
Code:
bb_code($post.message, 'post', $post.User
Context "post" is set.

For example, the template "post_macros" also has
Code:
bb_code($post.message, 'post', $post.User

How can I tell the difference between "widget_new_threads" | "post_macros"?


A transfer of important variables would be more than desirable!

a) to know who where what and why
b) who came up with this stupid idea to move the bbCode parsing into the template?


XF2 is no fun!
 
Last edited by a moderator:
The next release will have a number of changes here which I believe should address this issue. In most cases, the entity is now exposed to the BB code renderer. Technically, this has happened through a number of changes and some BC breaks.
  1. The bb_code() function in the templater has had its $user argument changed to $content. Note that this used to have a null default. This argument is now explicitly required, though you can pass null if there isn't a relevant entity or user. (For example, the BB code help page.) If there's a relevant entity, pass that; if not but there's a relevant user, pass that here; if neither apply, pass null. Most existing calls should work here provided they passed a $user value, though they should be updated.
  2. The XF\SubContainer\BbCode::render() function has had its signature changed to add a $content argument before the options argument. This is now required and has the same semantics as the bb_code() function above.
  3. There's a new XF\BbCode\RenderableContentInterface interface that should be implemented if you plan on passing an entity type into either of the above functions. If implemented for your entity, we will call the getBbCodeRenderOptions($context, $type) method. This will return a default set of options/data that should be passed to the BB code renderer (as $options worked previously). This change means that we rarely pass options to the BB code renderer through templates. For example, passing attachments and attachment viewing permissions are now handled within the Post entity. XFMG now just extends this method to pass extra data rather than relying on a template modification. (By extension, any add-on doing something similar to XFMG will likely have a template modification that doesn't get applied).
  4. XF\BbCode\RuleSet now supports a primary context (generally a content type) and a secondary "usage" context in the form of post:rss or user:signature, though most usages will only provide the general content type. This is passed to the getBbCodeRenderOptions method for you to change behavior based on context. There are now also getters on the object so you can retrieve them if needed. There's also a code event so you don't have to extend the object to manipulate the rules in a specific context. (Note that BB code rules will not depend on any of the context supplied to the renderer. The rule set defines the known tags and what defines whether a tag is syntactically valid. Contextual validity is generally a render-time decision.)
 
@Mike, thanks for these changes. One question - I have an addon that extends XF\BbCode\Renderer\Html to override renderTagUrl(). With the given changes outlined above in beta 8, would it be possible to get a context from within renderTagUrl()?
 
In case anyone is interested, I did something like this which does the trick (I needed to know the forum id if available).

PHP:
    protected $nodeId = null;

    public function renderTagUrl(array $children, $option, array $tag, array $options)
    {
        $return = parent::renderTagUrl($children, $option, $tag, $options);

        if ($options['entity'] instanceof \XF\BbCode\RenderableContentInterface)
        {
            $this->nodeId = $options['entity']->Thread->node_id;
        }

        /* ... */
    }
 
  • Like
Reactions: Xon
The bb_code() function in the templater has had its $user argument changed to $content.
Where can i read about the arguments to pass?
Can i tell bbcode() to translate [attachments?
 
Last edited:
Top Bottom