Not signed in (Sign In)

Categories

Vanilla 1.1.4 is a product of Lussumo. More Information: Documentation, Community Support.

Help keep Vanilla free:
Welcome Guest!
Want to take part in these discussions? If you have an account, sign in now.
If you don't have an account, apply for one now.
    •  
      CommentAuthorsweeney
    • CommentTimeAug 1st 2005
     # 1
    Further to my needs of altering the header HTML of Vanilla, I set about writing myself an extension to help me. I read the documentation, I understood it. I wrote my code. It didn't work.

    As far as I'm aware, the problem lies in something that I'm doing wrong with the

    $Context->ObjectFactory->SetReference("MyNeatClass", "AnotherClass");
    method.

    For outputting HTML head content, the class 'Head' in ./controls/Common.Controls.php is used, around line 322.
    This class loops through scripts, stylesheets and strings added to the header, and then the function Render() is used to render the page, outputting the HTML header.

    Excellent, I thought. I'll just Set a reference (using the above code) so that Vanilla asks for my version of the Head class (which i called ManualHead) and uses my Render() function instead of its own. So I wrote this:

    $Context->ObjectFactory->SetReference("Head", "ManualHead");

    With the class ManualHead being:


    class ManualHead extends Head {
    function Render(){
    $this->Context->Writer->Add("test");
    }
    }


    Which should, with the SetReference method just write the entire head to 'test'.
    This didn't work.

    I tried it with $this->Context->Writer->Write("test"); instead. Nope.

    So I tried copying the entire Head class to ManualHead. I even changed the


    function Head(&$Context) {
    $this->Context = &$Context;
    }


    to


    function ManualHead(&$Context) {
    $this->Context = &$Context;
    }


    I set a class var$Context. I even tried making ManualHead a new object, and a new ContextObject. Nothing worked.

    So, after much playing, and getting annoyed...i've decided to ask the forums. Maybe a php whizz can lend a hand (Mark?) as i've tried my best.

    Here's the code in the simplest format I think should work:


    class ManualHead extends Head {
    function Render(){
    $this->Context->Writer->Add("test");
    }
    }

    $Context->ObjectFactory->SetReference("Head", "ManualHead");


    I'd be most pleased if someone could help me out :-)

    Regards,

    Martin.
    •  
      CommentAuthorlech
    • CommentTimeAug 1st 2005 edited
     # 2
    It might help to know EXACTLY what you're trying to modify in the head area there. Just part of it, the whole thing or inserting something in between it all? Because I want to say if it's replacing the utf-8 and encoding and other general header info, it might not be possible yet because I'm fairly certain mark didn't consider that as necessary to being modified. Maybe in the next revision it should be extension compatible.
    •  
      CommentAuthorsweeney
    • CommentTimeAug 1st 2005 edited
     # 3
    Hokay - here's the code:



    function Render() {
    $this->Context->Writer->Add("<".chr(63)."xml version=\"1.0\" encoding=\"utf-8\"".chr(63).">
    <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
    <html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en-ca\">
    <head>
    <title>".agAPPLICATION_TITLE." - ".$this->Context->PageTitle."</title>
    <link rel=\"shortcut icon\" href=\"/favicon.ico\" />");
    if (is_array($this->StyleSheets)) {
    $StyleSheetCount = count($this->StyleSheets);
    for ($i = 0; $i < $StyleSheetCount; $i++) {
    $this->Context->Writer->Add("\r\n<link rel=\"stylesheet\" type=\"text/css\" href=\"".$this->StyleSheets[$i]["Sheet"]."\"".($this->StyleSheets[$i]["Media"] == ""?"":" media=\"".$this->StyleSheets[$i]["Media"]."\"")." />");
    }
    }
    if (is_array($this->Scripts)) {
    $ScriptCount = count($this->Scripts);
    for ($i = 0; $i < $ScriptCount; $i++) {
    $this->Context->Writer->Add("\r\n<script type=\"text/javascript\" src=\"".$this->Scripts[$i]."\"></script>");
    }
    }
    if (is_array($this->Strings)) {
    $StringCount = count($this->Strings);
    for ($i = 0; $i < $StringCount; $i++) {
    $this->Context->Writer->Add($this->Strings[$i]);
    }
    }
    $this->Context->Writer->Write("</head>
    <body".$this->Context->BodyAttributes."><div id=\"header\"><!-- A menu, a few divs etc --></div>
    ");
    }



    if it's not an essential feature and I can't do it, then how am I to add my own header etc?
    •  
      CommentAuthorlech
    • CommentTimeAug 1st 2005 edited
     # 4
    Well, if you just want to change the DTD, then all you really need to change is


    $this->Context->Writer->Add("<".chr(63)."xml version=\"1.0\" encoding=\"utf-8\"".chr(63).">
    <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
    <html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en-ca\">


    To my knowledge, mark hasn't yet added support to change this yet. However it would be wise in the future for Arabic languages and such.

    For adding just a script, you shouldn't be hacking away directly at the header and core files, instead look at this discussion on how to add a header script as an extension.
    •  
      CommentAuthorsweeney
    • CommentTimeAug 1st 2005 edited
     # 5
    That's not really what i'm after doing...I don't want to change the DTD; I want to add in the bit of HTML near the bottom after the body tag.

    I'm not not planning on hacking away at the header and core files; i'm writing an extension to do it for me so that it's lifespan extends across upgrades.

    I suspect that the order of execution sees the Common.Control.php script being executed after the extensions, which makes my attempt to change the 'Head' class not do anything.
    It's just that I thought I would be able to do this...either that or I'm doing something wrong. Perhaps a php whizz could shed some light on this, or perhaps Mark himself?

    M.
    •  
      CommentAuthorMark
    • CommentTimeAug 5th 2005
     # 6
    Sorry it took me so long to get to this discussion - I've been really busy.

    The problem is that the Head control is instantiated before the extensions are loaded. So by the time you're setting your new reference in the ObjectFactory, the object has already been created and your reference does nothing.

    Now, there *is* an "AddString" method in the Head control that allows you to add *anything you want* to the head. Would that allow you to do what it is you're trying to do?
    •  
      CommentAuthorMark
    • CommentTimeAug 5th 2005
     # 7
    Oh, and by the way, please feel free to send me an email if you've got a pressing code-related question that isn't being answered: support [at] lussumo [dot] com
    •  
      CommentAuthorsweeney
    • CommentTimeAug 5th 2005
     # 8
    Ah ha! As I thought, except the wrong way around! It made sense in my head, just not translated properly into text!

    The AddString method is dandy, but I want to add code outside of the head, before the rest of the Vanilla forum code - so that I can add my own block of 'stuff' - everything which fits in with the rest of the site that I'm making.

    If needs be, I'll just hack about with the core files. Is there any reason why the control classes can't be instantiated after the extensions?

    M.
    •  
      CommentAuthorMark
    • CommentTimeAug 5th 2005 edited
     # 9
    Those five control classes are instantiated before the extensions are loaded so that extension writers can take advantage of their various utility methods like adding things to the head, adding things to the panel, adding things to the body, etc.

    You can always just create your own control and add it to the Head_Render event of the page object if you just want to add something *after* the head.

    $MyObj = $Context->ObjectFactory->NewContextObject($Context, "MyClass");
    $Page->AddControl("Head_Render", $MyObj);


    To be honest, I've never even tried it, but theoretically it should be fine.

    The only thing you might stumble across is that your control gets added before the head control and therefore is rendered before the head control. If that is the case, the quick fix is to add your control to the next event in the page, which is the Menu_Render event.

    If that happens, though - please let me know. I want to make sure that things get executed in the correct order, and I may have to change the page object a bit for the next release to ensure that happens.
    •  
      CommentAuthorsweeney
    • CommentTimeAug 5th 2005 edited
     # 10
    You're an absolute star!

    sweeney kisses Mark on the forehead, Mafia Stylee.

    I had to use the Menu_Render event as you said...


    <?php
    /*
    Extension Name: Change the header
    Extension Url: http://lussumo.com/docs/
    Description: Allows you to manually edit the header of Vanilla forums
    Version: 1.0
    Author: Martin Sweeney
    Author Url: http://martini.me.uk/
    */

    class ManualHead {
    var $Context;

    function ManualHead (&$Context) {
    $this->Context = &$Context;
    }

    function Render() {
    $this->Context->Writer->Write("Hello :-)");
    }

    }

    $ManualHead = $Context->ObjectFactory->NewContextObject($Context, "ManualHead");
    $Page->AddControl("Menu_Render", $ManualHead);

    ?>



    M.
    •  
      CommentAuthorMark
    • CommentTimeAug 5th 2005
     # 11
    Cool - thanks for the heads-up. I'll be sure to fix that order-of-events bug for the next release.

    :)
Add your comments
    Username Password
  • Format comments as