Recent Blog Posts

Localized number format in Drupal 8

By Ronald van Belzen | July 14, 2016

When building this blog I decided to use the core module statistics to display the view count on blog posts. Because some of my older blog posts have had a lot of views, the counter on those blog post views had grown quite large. For making those large numbers more readable it would be nice that those numbers would be displayed with thousands-seperators, just as can be accomplished with the PHP function number_format() or, even better, with the NumberFormatter class. The statistics module does not do that.

As it turns out Drupal 8 core does not support that either, and a sole module that offers this functionality has no Drupal 8 version. I decided to make a solution specifically for the statistics module. That module implements the hook hook_node_links_alter() in the statistics.module file to add the view count to the list of node links (as text). So I set out to create a copy of this hook that would override this particular hook.

The module to which I will add this hook will be named mystatistics:

# mystatistics.info.yml
name: 'My Statistics'
type: module
description: 'Module to override the display of the Statistics module.'
package: Other
version: '1.0'
core: '8.x'
dependencies:
  - statistics

In the mystatistics.module file I added the following code:

Change the PageUtility class into a service

By Ronald van Belzen | May 1, 2016

In the previous article of this series we concluded writing a class that will take care of the pagination, sorting and filtering of data in a tabular display. Next we are going to transform this class into a service. For this we are going to rename the class and place it in the proper directory in accordance with the namespace for this new class that will be:

namespace AppBundle\DependencyInjection;

For coming up with a new class name let's consider what the service will actually do. It will provide the data to be displayed on a page. For this reason I will call the new class PageDataProvider. With this name we can add the service to our "services.yml" that is imported by the configuration file of our application:

services:
    page.data.provider:
        class: AppBundle\DependencyInjection\PageDataProvider
        arguments: ["@request_stack", "@service_container"]

As you can see we pass the RequestStack and the ContainerInterface as arguments for the class constructor. These parameters do not coincide with the constructor parameter of the PageUtility class. So, let's change the constructor of our new class accordingly:

<?php
namespace AppBundle\DependencyInjection;

use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\DependencyInjection\ContainerInterface as Container;

class PageDataProvider {
    protected $requestStack;
    private $request;
    private $em;
    private $entityName;

    // ...
    
    public function __construct(RequestStack $requestStack, Container $container) {
        $this->requestStack = $requestStack;
        $this->em = $container->get('doctrine')->getManager();
    }

In the constructor we set the new variable $requestStack and set the enity manager $em. We now need a function in which we can set the entity name for which the data need be be delivered:

Adding sorting and filtering to tabular data display in Symfony2

By Ronald van Belzen | April 28, 2016

In the previous article I described how to add pagination to tabular data display. Here I will describe how to add sorting and filtering, which will result in the following end result:

Symfony2 pagination

Sorting

The request parameter sort will receive a value that both contains the name of the field and the sort direction seperated by a dot. This value is included in the parameters passed to the twig file "list.html.twig" together with a value for the request of the reverse sort direction ("pager.sort_reverse") and the name of the current sort field ("pager.sort_field") and sort direction ("pager.sort_order") seperately. In the twig file we first change the table header to the following:

Create pagination, sorting and filtering of tabular data display in Symfony2

By Ronald van Belzen | April 26, 2016

The addition of pagination, sorting and filtering to a tabular display of data is a relatively simple task. No doubt there is more then one bundle in Symfony2 that tackles this task for you (e.g. KnpLabs/KnpPaginatorBundle for a SEO friendly paginator). Here I will demonstrate the relative ease in which you can combine pagination, sorting and filtering of tabular data display. For this example I will use the well known User table. In this case the User table created by the FOSUserBundle to which I added the field fullname.

<?php 
namespace AppBundle\Entity;

use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="app_user")
 */
class User extends BaseUser {
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
	
    /**
     * @ORM\Column(type="string", length=100, nullable=true)
     */
    private $fullname;

    /**
     * Set fullname
     *
     * @param string $fullname
     *
     * @return User
     */
    public function setFullname($fullname)
    {
        $this->fullname = $fullname;

        return $this;
    }

    /**
     * Get fullname
     *
     * @return string
     */
    public function getFullname()
    {
        return $this->fullname;
    }
}

The controller class function to which I will add pagination looked like this:

<?php 
namespace AppBundle\Controller;

use AppBundle\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class AdminController extends Controller {
    /**
     * Handle the user listing display
     */
    public function listAction(Request $request) {
        $em = $this->getDoctrine()->getManager();
        
        $users = $em->getRepository('AppBundle:User')
            ->createQueryBuilder('t')
            ->orderBy('t.username', 'ASC')
            ->getQuery()
            ->getResult();
		
        return $this->render('admin/list.html.twig',[
            'users' => $users,
        ]);
    }
    
    // Other functions.
    
}	

And the twig file ("list.html.twig") for the display of the data in a tabular format looked like this:

Add configuration to a custom module in Drupal 8

By Ronald van Belzen | April 4, 2016

In a previous blog post I showed how to build a simple module. The only thing the module was supposed to do is produce an empty front page. The reason behind this was that no content will be published on the front page of the blog that I build. But when there is no content Drupal 8 displays a text on the frontpage that explains that there is no front page content. I wanted to suppress that behaviour.

There is a module that does exaclty what I needed, but that module is not available for Drupal 8, yet. So, I built my own solution. But what if I wanted to share my solution with others; what would I need to change? The documentation on the Drupal 8 site helps with that. We skip the part that a module name needs to be unique for now, and concentrate on the best practice of making your module configurable.

In the simple My Empty Front Page module there is no question about what can and must be configurable. The path that invokes the empty front page is the only thing we will need to change in a different environment in which the hard-coded path "/empty" has already been taken to produce some other content for that site.

A configuration field

First I create a new subdirectory "module\custom\my_empty_front_page\config\install" in my module directory and in that subdirectory I place the file "my_empty_front_page.settings.yml" with the following content:

empty_front_page_path: '/my_empty_front_page/empty'

This tells Drupal 8 that there is a setting parameter with the name "empty_front_page_path" for the module with the default value of "/my_empty_front_page/empty" (I decided that "/empty" would not be that unique, so I change the default value to a more unique path name). Now we also need to tell Drupal what the format of this variable is, because Drupal will save this variable for us and needs to know the format.

For this reason I create the new subdirectory "module\custom\my_empty_front_page\config\schema" in my module directory and in that subdirectory I place the file "my_empty_front_page.schema.yml" with the following content: