Call/load a hard coded block's controller manually

Permalink
Hey guys!
I have hardcoded a block into a page type. The block displays well, <!-- but the block controller looks like it is not run automatically --> but the controller's on_page_view() method is not run automatically, like if it was put in an area normally through the concrete5 front-end. There are some header items that should be included, which is done inside the block controller's on_page_view() method - but as I stated above, this method does not seems to be called. Anyone knows a solution? I tried getting the controller and including the header items ($block_type->getController()->addHeaderItem()) but nothing happens. :C



I should also add, that I am doing a modification for the Theme Switcher block. I had written a custom template for it. The controller does some cookie setting, which is in fact the heart of the whole plugin, so the point would be to somehow I dunno, include the controller into the actual view of whatever. I don't fully understand C5 MVC, but maybe you get what I'm trying to say. :)


$theme_switcher = BlockType::getByHandle('theme_switcher');
$theme_switcher->render('templates/floater/view');


EDIT (2013-03-01):
I've tried calling the controller's on_page_view method() manually, after getting the controller from the block type object. It is successfully called, but does not seem to produce the output. Empty style and script tags are inserted at the point where the respective addHeaderItems() calls are made.

EDIT (2013-03-01) / 2:
As stated above, header items were not outputted. After some backtracking I figured out a simple solution: header items must be added before the
Loader::element('header_required');
call. I don't know if this is a good practice or not, but it seems, that header items added manually, are outputted after the systemwide headers, like jQuery, so it seems safe enough for me. Adding header items after this call would not produce (automatic) output, but another call for adding header items would output all the core header items again. A call to the automatic outputting of block specific headers would not work for hardcoded blocks (as far as I understand), because the method relies on database entry information, but without one, fails.

sample code:
$theme_switcher = BlockType::getByHandle('theme_switcher');
$cnt = $theme_switcher->getController();
// add header items here with $cnt->addHeaderItem() calls
Loader::element('header_required');


The on_page_view() method mentioned in the discussion however is not called automatically! You would have to do a call for that yourself. I recommend using the controllers runTask() method against a simple call for that method.

Simple as pie!

 
ScottSandbakken replied on at Permalink Reply
ScottSandbakken
How are you rendering the block to make it display? Can you post your code?
szucslaszlo replied on at Permalink Reply
Hi! I edited the post.
ScottSandbakken replied on at Permalink Reply
ScottSandbakken
I don't think you need the /view in the render function.
$theme_switcher->render('templates/floater');


However, I know from experience that this will not bring in the style sheet. I recommend moving your styles for this block into your theme's default style sheet. That should solve your problem.
szucslaszlo replied on at Permalink Reply
You may be right, but the block displays well with the /view in the argument. Anyway, my issue is not to display the block, but that the controller has an on_page_view method, which is not run, when the page is viewed. I figured, that the problem migh be, that adding hard coding a block this way does run the controller, when the page is run, or something like that. :/
ScottSandbakken replied on at Permalink Reply
ScottSandbakken
I just ran a test where I call an autonav block in a manor similar to what you are doing, and I see that the on_page_view() method is being loaded.

Basically, I modified the autonav controller to add the on_page_view() method like this:

public function on_page_view() {
   $html = Loader::helper('html');
   $this->addHeaderItem('<script>//here i am</script>');
}


Then, I generate the block like this:

<?php
$pid = 127;
$subNavBlock = BlockType::getByHandle('autonav');
$subNavBlock->controller->displayPages = 'custom';
$subNavBlock->controller->displayPagesCID = $pid;
$subNavBlock->controller->displaySubPages = 'all';
$subNavBlock->controller->displaySubPageLevels = 'all';
$subNavBlock->controller->orderBy = 'display_asc';
$subNavBlock->render('templates/sub_nav');
?>


When I load the page, I can clearly see the
<script>//here i am</script>

added by the controller.

I am not familiar with the theme switcher add-on, but it should work the same.
melat0nin replied on at Permalink Reply
melat0nin
Hello NetJunky

How did you override the controller, and where did you put it in the site's structure? Which class did you declare to extend the core class?

I am having problems with overrides in 5.6.1 as it's a bit of a new way of thinking.
ScottSandbakken replied on at Permalink Reply
ScottSandbakken
As this was just a test, I didn't over-ride the controller. I modified it directly.

However, if I were to over-ride the core class for the autonav controller, I would create a controller.php file in [root]/blocks/autonav that is setup like this:

<?php defined('C5_EXECUTE') or die("Access Denied.");
class AutonavBlockController extends Concrete5_Controller_Block_Autonav {
   public function on_page_view() {
      $html = Loader::helper('html');
      $this->addHeaderItem('<script>//here i am again</script>');
   }
}
// Need to include this as well since it is required by the AutonavBlockController and listed in the core file.
   class AutonavBlockItem extends Concrete5_Controller_Block_AutonavItem { }
szucslaszlo replied on at Permalink Reply
After further investigation it turned out, that indeed, on_page_view() is called, but the headers were not outputted. I don't know exactly how should this work, but I noticed, that header items are outputted once, before the Theme Switcher's on_page_view() adds the header items, and that is why it is not outputted. If I manually call outputHeaderItems, it works as expected - it outputs ALL header items, including the ones printed once before. So I ended up with simply including them. Also, after having spent a day on this issue, the final blow was that the view did not receive some variables properly, that is, in the view context of the block, $this-action() did not function properly, because it was working with a block type object, rather than a block object. So this issue is pretty much dead by now. :/. Thanks for your advices anyway!