4

I am trying to get to grips with Drupal 8s layout and and architecture.

Having worked with Drupal 6 for the last 2 years I have become used to its procedural style, so I am finding the OOP approach takes a little getting used to.

This is what Im trying to achieve.

My Module has a block which displays content The content of that block is refreshed every 5 seconds This is done with an Ajax call to the server which overwrites the content of the block with the freshly acquired Ajax HTML

So I have gotten the block to display my content on the page easily enough. My problem is now how do I get to the content to refresh. The logic for building the content is contained in functions in my Block class.

I have tried to set up a route in my .yml file to call these functions again to refresh my content via ajax, but I get fatal errors, and also it does not feel like the right approach to access my block class. I feel I should be routing to the controller.

but then, how do I get at the functions that I have written to build the content for the block in the first place?

Should I have written all my logic in my Controller? and if so, how do I access it from my block?

UPDATE

Attempting the solution suggested by Daniel Wehner below I receive the following error:

    Call to undefined method Drupal\livequotes\Controller\LivequotesController::getEntityManager() 
in <b>C:\Work\excel-8\modules\livequotes\lib\Drupal\livequotes\Controller\LivequotesController.php

I guess this is because I need to extend my controller or to implement the class that defines getEntityManager()

any ideas on how to do this?

UPDATE 2

Following on the suggestion in comments from Daniel Wehners answer I have attempted to use dependency injection to give access to EntityManager from my controller.

This is the code for my controller:

    namespace Drupal\livequotes\Controller;

    class LivequotesController{

    protected $entity;

    public function __construct(EntityManager $em) {
        $this->entity = $em;
    }
    /**
     * Re-render a specific block (yeah if we do something it should be generic).
     */
    public function livequotesShowBlock() 
    {
        $block = $this->entity->getStorage('block')->load($block_id);
        return $this->entity->getViewBuilder('block')->view($block);
    }
}

The following error is received when I try and access function livequotesShowBlock() from my ajax call:

Recoverable fatal error: Argument 1 passed to Drupal\livequotes\Controller\LivequotesController::__construct() must be an instance of Drupal\livequotes\Controller\EntityManager, none given

UPDATE 3

Following the link to an example of Dependency injection into a Controller class, drupal.org/node/2168121 provided by Daniel Wehners comment in his answer my Controller now looks like this:

namespace Drupal\livequotes\Controller;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Controller\ControllerBase;

/**
 * Controller routines for livequotes routes.
 */

class LivequotesController extends ControllerBase{

    protected $entity;

    public function create(Container $container) 
    {
        return new static($container->get('entity'));
    }

    public function __construct(EntityInterface $em) {
        $this->entity = $em;
    }

    public function livequotesShowBlock() 
    {
        $block_id = "livequotes_content";
        $block = $this->entity->getStorage('block')->load($block_id);
        return $this->entity->getViewBuilder('block')->view($block);
    }
}

Unfortunately though, I am now getting the following error:

Fatal error: Cannot make static method Drupal\Core\Controller\ControllerBase::create() non static in class Drupal\livequotes\Controller\LivequotesController in C:\Work\excel-8\modules\livequotes\lib\Drupal\livequotes\Controller\LivequotesController.php on line 16

UPDATE 4

Changing the signature to static

    namespace Drupal\livequotes\Controller;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Controller\ControllerBase;

/**
 * Controller routines for livequotes routes.
 */

class LivequotesController extends ControllerBase{

    protected $entity;

    public static function create(Container $container) {
        return new static($container->get('entity'));
    }

    public function __construct(EntityInterface $em) {
        $this->entity = $em;
    }
    /**
     * Re-render a specific block (yeah if we do something it should be generic).
     */
    public function livequotesShowBlock() 
    {
        $block_id = "livequotes_content";
        $block = $this->entity->getStorage('block')->load($block_id);
        return $this->entity->getViewBuilder('block')->view($block);
    }
}

results in the following error:

Declaration of Drupal\livequotes\Controller\LivequotesController::create() must be compatible with Drupal\Core\DependencyInjection\ContainerInjectionInterface::create(Symfony\Component\DependencyInjection\ContainerInterface $container)

1 Answer 1

1

The proper way is probably to re-render the block in your controller:

<?php
class ExampleController extends ControllerBase {

  /**
   * Re-render a specific block (yeah if we do something it should be generic).
   */
  public function renderBlock($block_id) {
     $block = $this->getEntityManager()->getStorage('block')->load($block_id);
     return $this->getEntityManager()->getViewBuilder('block')->view($block);
  }

}
11
  • This looks very promising. Seems like what I need to do to access block via my controller. Please see the update in my question that shows the results of attempting your approach Commented Apr 18, 2014 at 18:16
  • In this case you don't extend the COntrollerBase class ... in that case you can also inject the entity manager directly Commented Apr 18, 2014 at 21:26
  • Ive tried to use DI for my EntityManager, but with little success. Update 2 above shows the error I received. Commented Apr 19, 2014 at 10:28
  • drupal.org/node/2168121 shows an example Commented Apr 20, 2014 at 12:11
  • 1
    Still not getting it I'm afraid. I've updated my answer to show where I'm at but I can't seem to get any further. Commented Apr 21, 2014 at 19:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.