2

My custom module: - Plugin/Ziektes.php array returns to hook_theme

public function build() {

$letter_path = 'B';
$path = base_path();
$current_url = Url::fromRoute('<current>');
$current_path = $current_url->toString();

// Query for newest articles and return max 3 results.
$query = \Drupal::entityQuery('node');
$news = $query->condition('type', 'ziekte')
  ->condition('status', 1)
  ->condition('title', $letter_path, 'STARTS_WITH' )
  ->sort('created', 'ASC')
  ->execute();

// LoadMultiple News in $nodes variable
$nodes = Node::loadMultiple($news);

// Return $nodes variable with name items to the module.
return array(
  '#theme' => 'mytheme_ziektes',
  '#items' => $nodes,
  '#path'  => $path,
  '#url'   => $current_path,
);

I have an alphabetical pagination printedn in twig like this: enter image description here

Below this pagination there are the results of nodes for example in the letter 'B' there are nodes from content-type 'ziektes' that starts with the letter B.

As you can see in my module Ziektes.php file its not dynamic it uses

$letter_path = 'B'; ->condition('title', $letter_path, 'STARTS_WITH' ).

When there is clicked on a letter it goes to ziektes/'theletter' for example ziektes/b so that I can get the letter from the url and make the query dynamic.

But at page ziekte/*anyletter I get an 404 page not found so I've made a Controller and a routing:

Routing:

myroutingname.settings:
  path: '/ziektes/{letter}'
  defaults:
    _controller: '\Drupal\myblocksroute\Controller\ZiektesController::ziekte'
    _title: 'Routing Ziektes'
  requirements:
    _permission: 'access my routing ziektes'

Controller:

namespace Drupal\myblocksroute\Controller;

class ZiektesController
{
  public function ziekte($letter) {
    return [
      '#title' => $letter
    ];
  }
}

This returns the letter that is clicked, that's good! But Its only a new page with the as title the letter 'b' for example, I can't keep the twig template and the EntityQuery are not reachable from here. It suppose to stay at /ziektes form template but the url is /ziektes/b, so that the query will check the letter after the ziektes/ where I can make my $letter_path dynamic.

How can I do this?

  • Your controller needs to extend ControllerBase, for starters. From there, entity query service could be injected and available to use. The namespace also needs to be uniform, i.e. the name of your module. – Kevin Apr 18 '17 at 13:39
  • 1
    You can probably do this without a plugin and your hook_theme is still usable. Your controller has to return a renderable array with the #theme function set. The reason you only see $letter output is because thats all you're passing to the rendering layer. – Kevin Apr 18 '17 at 13:45
1

As I alluded to in my comment, you are close, I believe. Here are some changes to get you in the right direction which begins by extending ControllerBase:

class ZiektesController extends ControllerBase
{

  // set any scope/variables here

  public function __construct($args...) {
    // set your injected dependencies to local variables
  }

  public static function create($args...) {
    // here you inject dependencies you need
  }

  public function ziekte($letter) {    
    return array(
     '#theme' => 'mytheme_ziektes',
     '#items' => $this->queryNodes($letter),
     '#path'  => $path,
     '#url'   => $current_path,
    );
  }

  protected function queryNodes($letter) {
    // the following code can be refactored
    $letter_path = 'B';
    $path = base_path();
    $current_url = Url::fromRoute('<current>');
    $current_path = $current_url->toString();

    // Query for newest articles and return max 3 results.
    $query = \Drupal::entityQuery('node');
    $nodes = $query->condition('type', 'ziekte')
      ->condition('status', 1)
      ->condition('title', $letter_path, 'STARTS_WITH' )
      ->sort('created', 'ASC')
      ->execute();

    return count($nodes) ? $this->entityTypeManager->getStorage('node')->loadMultiple($nids) : array();
  }
}

ControllerBase should inject everything you need already, like entityTypeManager. That can be used to load nodes, as shown above. You don't need to call Node, and you likely don't have to do the same for Url either.

You can bring in your query as a helper method and you can inject entityQuery into your controller, see this comment on how to do that. That way, you're not using the global static container (\Drupal::). Then your code becomes:

    // Query for newest articles and return max 3 results.
    $query = $this->entityQuery->get('node');
    $nodes = $query->condition('type', 'ziekte')
      ->condition('status', 1)
      ->condition('title', $letter_path, 'STARTS_WITH' )
      ->sort('created', 'ASC')
      ->execute();

I am not sure why you need path and url though - every filter link will be routed to '/ziektes/{letter}'.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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