Vanilla 1 is no longer supported or maintained. If you need a copy, you can get it here.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

Blogging Extension Question

I'm working on an extension (theme?) to make Vanilla look more like a blog (actually want to make an aggreagator). I've taken a look at Mr. K's site and code samples for his implementation. My first step is trying to get the discussions view to display the first n characters of the first comment (i.e. initial post).

I'm a total noob to PHP and Vanilla, but I do have lots of web dev experience. Looking through the code, it didn't look like the body of the first comment was a property of the Discussion class so I figured out how to insert a function call into the DiscussionManager PreGetDiscussionList delegate point to add a join to that query to get the first comment. I'm pretty sure it's working because the errors stopped happening once I figured out the right way to use the sqlbuilder class ;-)

It still doesn't seem to be a property of the Discussion class when I try and output it with a custom theme, and I didn't see any delegation points in the Discussion class. I could hack the Discussion class, but that's against the rules right? Not sure how to procede here.

Assuming I get that working, I've got a question about how something should be done. Like I mentioned before, I'm trying to output my new CommentBody column in a custom theme. That would make my theme dependendent on my extension wouldn't it? That seems less than ideal. Is there another way to do it?

Any help is much appreciated!

Comments

  • Took a look at the docs again. Looks like I could add my new CommentBody property to the discussion class by extending it and using the Object Factory. But the docs also say that using the ObjectFactory makes for brittle add-ons, and that just about anything can be done in extensions without the ObjectFactory. Is there another way?
  • I got something to work. I hacked the core Discussion class' GetPropertiesFromDataSet function to get the CommentBody column I included in the sql query and set it to a CommentBody property of the Discussion class. From what I understand I can extend Discussion to do this rather than hack the core file, then use ObjectFactory to tell Vanilla to use my version instead. But again, due to the warnings around using ObjectFactory in the docs, I'm wondering if there's another way. And I'm still concerned that I have to use a custom theme to output the new field. A theme that requires an extenstion that can break other extensions seems like a really bad idea to me.
  • I'm just talking into the void here :-) Are my questions totally noobish? Did I miss something obvious in the docs or code? Am I totally on the wrong track? ANY feedback is much appreciated.
  • This is in regards to putting a summary of the first post in the discussion grid... don't see why it couldn't be used for what you are trying to accomplish: http://lussumo.com/community/discussion/2642/#Item_7 There might be another note on this... looking...
  • Nope, can't find it, but that note looks doable. Might have to try this out myself... if I find time.
  • aha! thanks WallPhone!

    No, you can do this no problem. It might require that I add a delegate or two to the source, but that's not a problem either.
    quote from Mark:
    Basically you attach to a delegate in the discussionmanager class and alter the GetDiscussionBuilder method so that it joins to the comment table on the FirstCommentID (as bergamot said). Then you'd attach to a delegate on the DiscussionGrid control to render that extra bit of information for each discussion, and finally you'd add a stylesheet to style your new bit of xhtml.

    I'm pretty sure you'd need a new delegate in the themes/discussion.php template file, but there should already be a delegate for you to use in the DiscussionManager class.



    looks like I'm on the right track. Do I really need a delegate in the DiscussionGrid class? That just seems to hand off actuall discussion rendering to the discussion.php template. I don't see any delegates in the themes/discussion.php file. I think I would need a Delegate in the DiscussionClass to add the new property to that class, that would be better than using the ObjectFactory right?
  • okie dokie, first thing I did was pretend that somebody added a delegate for me in the Dicussion class:

    // Retrieve properties from current DataRowSet function GetPropertiesFromDataSet($DataSet, $Configuration) { $this->DelegateParameters["DataSet"] = &$DataSet; $this->DelegateParameters["Configuration"] = &$Configuration; $this->CallDelegate('PreGetPropertiesFromDataSet'); ...

    then I added this call to the delegate in my extension default.php...

    $Discussion = $Context->ObjectFactory->NewContextObject($Context, "Discussion"); function Discussion_SetFirstCommentBody(&$Discussion) { $d = &$Discussion->DelegateParameters['DataSet']; $Discussion->CommentBody = @$d['CommentBody']; } $Context->AddToDelegate("Discussion", "GetPropertiesFromDataSet", "Discussion_SetFirstCommentBody");

    I understand all the concepts here, but I think my lack of knowledge in the PHP language is killing me...
    For example: I'm not sure I need the "$Discussion = $Context->ObjectFactory->NewContextObject($Context, "Discussion");" line, I'm just copying what I did in my delegate call to the DiscussionManager class that already works.
  • I don't think we need to pretend that the delegate is there... I may be barking up the wrong tree, but my best guess would be the
    PreGetDiscussionList
    (line 231 in Vanilla.Class.DiscussionManager) delegate, and write an
    addSelect->LUM_Comment.Body
    into the extension.

    I think the proper way to refrence the table names is with the configuration settings, set in appg/database.php and config.php: $Configuration['DATABASE_TABLE_PREFIX'] . $DatabaseColumns['Comment'] . '.' . $DatabaseColumns['Comment']['Body']which should evaluate to
    LUM_Comment.Body
    Then we need to do the same thing for the delegate in the discussion grid class to show the extra information that is being selected.

    Really odd we are the only ones in this thread.
  • I'm here he he... but I've been working on the Invision Conversion first
    I'm interested to see how you guys get this working
  • edited July 2006
    WallPhone, yeah, that's exactly what I did early on, and it works. I needed to pretend (i.e. hack) the Discussion class. Getting the DiscussionManager to modify the query to return the first comment body was pretty easy, but then I was left with: "Where is it?" it's not a property of the Discussion object, so how do I get it? The only way I could think to do it was add a delegate into the Discussion class like I showed above.

    Here's the code to add the first comment body to the sqlbuilder:

    $DiscussionManager = $Context->ObjectFactory->NewContextObject($Context, "DiscussionManager"); function DiscussionManager_GetFirstCommentBody(&$DiscussionManager) { $s = &$DiscussionManager->DelegateParameters['SqlBuilder']; //AddJoin($NewTable, $NewTableAlias, $NewTableField, $ExistingAlias, $ExistingField, $JoinMethod, $AdditionalJoinMethods = '') $s->AddJoin('Comment', 'com', 'CommentID', 't', 'FirstCommentID', 'left join'); $s->AddSelect('Body', 'com', 'CommentBody'); } $Context->AddToDelegate("DiscussionManager", "PreGetDiscussionList", "DiscussionManager_GetFirstCommentBody");

    This one works, it's the previous bit where I try and get the Discussion class to set a new CommentBody property that fails. Looking at it again, I would probably need to put a delegate up in vars section where all the props are declared, and in the clear method as well. Bleck! (do all Class properties need to be declared in the head of the class for them to work?)

    Maybe I should go with the object factory...

    And yes, it is odd we're the only ones here, I keep wondering if I've made some kind of faux pas.
  • edited July 2006
    ugh... I know nothing about the object factory...

    Here is an idea: what if we hack the data into a field thats already there? I.E. make it output <a href='blah?discussionID=xxx'>Title <div>This is the first x words of the post </div></a>... then we just have to text-decoration: none on the div, and we get a bonus of a larger click area for the blog post...

    Kind of a ugly hack tho. Why don't you edit your first post and put 'DELEGATE REQUEST:' in front of the title, that would surely get Mark's attention.

    However, If you extend the existing class, you will inherit the existing properties and just need to specify the new data field... I think we would still have trouble getting the data out of the class.
  • ToivoToivo New
    edited July 2006
    "actually want to make an aggregator ..." what do you mean by this? what will the thing do & look like? any samples?
  • content aggregator:

    bring together various xml feeds of different kinds of content around one theme and present them all together. Blogs, News Feeds, Social Bookmarks, YouTube vids, Google Calendars, Amazon Products, etc.

    Add community tagging and rating to help it self-organize and voila!

    My first step is to import rss/atom feeds into Vanilla as Discussions.
  • ToivoToivo New
    edited July 2006
    could you show some example of bigger portals that do so already? for example if I add feed from blog A and blog B ... what server will fetch these feeds. I mean if it grows and will become bigger there could be some perfomance issues.
This discussion has been closed.