1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

How activate xen tags (not include in template) when injecting code inside templates

Discussion in 'XenForo Development Discussions' started by cclaerhout, Apr 29, 2012.

  1. cclaerhout

    cclaerhout Well-Known Member

    My title is not the best one, I know. A simple example will be better. What I'm trying to do in the template hook listener:

    PHP:
    $mystring ="This is {xen:phrase myphrase}"//It's just an example, this string is inside the database, I would like to avoid to capture the tag, then use PHP to activate the phrase
    $template->setTemplate('MyVirtualTemplate'$mystring);
    $templateObject $template->create('MyVirtualTemplate', array());
     
    //Then I would like to render my Virtual Template, but It doesn't want
    $final $templateObject->render();
    I've got different kinds of errors: when xen tags used in $mystring:
    Code:
    Parse error: syntax error, unexpected ':' 
    Otherwise:
    Code:
    Parse error: syntax error, unexpected $end
    All in "library/XenForo/Template/Abstract.php".

    I've also tried with the XenForo_Template_Compiler, but nothing happens.

    Is there a way, or to be parsed a xen tag must be in template first and can't be injected after?
     
  2. lms

    lms Well-Known Member

    Use
    Code:
    $mystring ="This is ". new XenForo_Phrase('myphrase'); //It's just an example, this string is inside the database, I would like to avoid to capture the tag, then use PHP to activate the phrase
    $template->setTemplate('MyVirtualTemplate', $mystring);
    $templateObject = $template->create('MyVirtualTemplate', array());
     
    //Then I would like to render my Virtual Template, but It doesn't want
    $final = $templateObject->render();
    
    Salud2
     
  3. cclaerhout

    cclaerhout Well-Known Member

    That what I didn't want to use ^^ see the explanation at the right of the code. But thank you for your answer.
     
  4. Rob

    Rob Well-Known Member

    Im not so sure you are going the right way about this. If you are populating your own database table with template code would it not just be easier to progmatically add a template? Same difference right but less headache, surely?
     
    cclaerhout likes this.
  5. infis

    infis Well-Known Member

    As example I wrote simple addon. This addon is fully work, but is not good idea. The best solution is create permanent template and render it with parameters.
     

    Attached Files:

    cclaerhout likes this.
  6. cclaerhout

    cclaerhout Well-Known Member

    I had done the first line for compiler, but I was missing the three following ^^ Thank you very much for the code.

    I already create templates with parameters, but this time I need a solution to parse phrase. My next addon will be the integration of a new editor to XenForo. I've done an admin interface with a button management system, which can deal the button command (it uses javascript). A command can for example inserts text in the editor. And if this text can support phrase management for language, it would be better. I can use my own tags to allow users to create their own phrases (regex to catch the phrase part then, "new XenForo_Phrase('capture')"), but I would have preferred a full automatic solution.

    In my addon previous version, I was using one template for each button, but the management wasn't good enough. That's why I've chosen the Db solution which is... really good now ^^ Except for this phrase problem.


    Infis, you say that it's "not a good idea", may I ask you why? Is it bad for performance?


    P.S: another question, why do you use try and catch commands?
    Edit: Oh I think I understand, it's faster than to do a if(isset$variable)) {} ; nice way !
     
  7. Rob

    Rob Well-Known Member

    I still dont understand why you just dont progmatically add templates to the template system as opposed to using your own tables.
     
  8. cclaerhout

    cclaerhout Well-Known Member

    Because it's not really a template... All those commands are a small part of a big JS code that I need to build inside the listener. Then inject inside the template. Same thing for CSS by the way.
    Let's take an example of the URL button set code:
    Code:
    {name:'Link', key:'L', openWith:'[url=[![Url]!]]', closeWith:'[/url]', placeHolder:'Your text to link here...'},
    This code can change, except the first "name:......", I can"t create a template with parameters to deal with all this.
     
  9. infis

    infis Well-Known Member

    Of course, the compilation is "on the fly" will be less productive than the pre-compilation. XenForo stores compiled templates just for this. It also allows multiple templates to use without sacrificing performance.
    You can try to conclude a stored template, for example, in every post. And then do the same with the template generated "on the fly". Compare the page generation time.
    I do not remember why. Perhaps it had to be treated with a "guest".
     
    cclaerhout likes this.
  10. cclaerhout

    cclaerhout Well-Known Member

    Done.... you're absolutely right... The loaded time is multiply by 2... I'm going to forget this ^^ But thank you for the explanation ! It was very interesting.

    Edit: nope, not by 2 sorry. => a connexion pb.
    Edit2: i've check my previous code... my first line wasn't good too ^^ My bad.
     
  11. infis

    infis Well-Known Member

    Poor performance of this solution was an obstacle to that, to allow further refinement of this addon. While this addon can be done without the use of syntax XenForo templates. For simple cases, such as inserting counter codes and other stuff in the hooks - only clear HTML code. I wrote it to get rid of writing addons for simple insertions into the hooks.
    If we build upon it, then you need to write a good procedure to generate a list of hooks to choose rather than typing the name of the hook. I think that such a simple addon (without the use of syntax XenForo) will be quite popular. The main thing that is not abused by the use of hooks, which are in themselves degrade performance.
    In general, such a addon is a different discussion thread :)
     
  12. cclaerhout

    cclaerhout Well-Known Member

    I've done tests again, and finally I don't see any differences. But I only do it to one short code (7000 characters once minified) whereas in your addon you did it for every hooks and with many foreach. May be it's why the performance are degradating.

    So to use your solution with the first example give above, here the final code:

    PHP:
     
                $mystring 
    "This is {xen:phrase myphrase}";
     
                
    $style_session $template->getParam('visitorStyle');
                
    $style_id $style_session['style_id'];
                
    $visitor XenForo_Visitor::getInstance();
                        if (empty(
    $visitor['language_id']))
                        {
                            
    $options XenForo_Application::get('options');
                            
    $lang_id $options->defaultLanguageId;
                        }
                        else
                        {
                            
    $lang_id $visitor['language_id'];
                        }
     
                
    $compiler = new XenForo_Template_Compiler(html_entity_decode($mystring));
                
    $parsed $compiler->lexAndParse();
                
    $compiled $compiler->compileParsed($parsed'MyTemplateAddedToContent'$style_id$lang_id);
                eval(
    $compiled);
               
                
    $mystring $__output;
     
     
    By the way, you've made a small error inside your code with the third parameter of the compileParsed function:
    Code:
    compileParsed($segments, $title, $styleId, $languageId
    You put twice the languade id.
     
  13. infis

    infis Well-Known Member

    For one call this method is with minimal difference between permanent and "on the fly" templates. But for many calls this method is bad.
    Oh, yes. Thank you for this bug.
     
  14. cclaerhout

    cclaerhout Well-Known Member

    A little update to the "final code" of post #12

    I've noticed that if the string has "options" variables ($xenOptions), these variables were not retrieved. For example:
    PHP:
    $mystring "This is {xen:phrase myphrase} coming from {$xenOptions.boardTitle}"
    So here is a basic and easy solution to solve the problem:

    PHP:
    class MyClass
    {
      public static function 
    MyFunction()
      {
                
    $mystring "This is {xen:phrase myphrase} coming from {$xenOptions.boardTitle}";
     
                
    $mystring preg_replace_callback('#(?:{)?\$xenOptions\.([0-9a-z_]+)(?:\.)?([0-9a-z_]+)?(?:})?#i''MyClassName::MyRegexCallBackFunction'$Params['XenforoSet']);
     
                
    $style_session $template->getParam('visitorStyle');
                
    $style_id $style_session['style_id'];
                
    $visitor XenForo_Visitor::getInstance();
                        if (empty(
    $visitor['language_id']))
                        {
                            
    $options XenForo_Application::get('options');
                            
    $lang_id $options->defaultLanguageId;
                        }
                        else
                        {
                            
    $lang_id $visitor['language_id'];
                        }
     
                
    $compiler = new XenForo_Template_Compiler(html_entity_decode($mystring));
                
    $parsed $compiler->lexAndParse();
                
    $compiled $compiler->compileParsed($parsed'MyTemplateAddedToContent'$style_id$lang_id);
                eval(
    $compiled);
         
                
    $mystring $__output;
      }
     
      public static function 
    MyRegexCallBackFunction($matches)
      {
            
    $options XenForo_Application::get('options');
       
            if (isset(
    $matches[2]))
            {
                return 
    $options->$matches[1][$matches[2]]; // I'm not sure about this, but this part of code should be useful in some forms (ie: active state)
            
    }
            else
            {
                return 
    $options->$matches[1];   
            }
      }
     
    }
     
     
     

Share This Page