Recent Blog Posts

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:

Build a blog with Drupal 8: Part 3

By Ronald van Belzen | March 25, 2016

I installed Bootstrap 3 for Drupal as the theme for my blog, but I want to change and add some minor things to that theme. For that purpose Drupal 8 offers the sub-theming mechanism. A sub-theme is a theme based upon another theme. Because I will base my sub-theme upon Bootstrap, I will call my sub-theme "My Bootstrap".

My Bootstrap sub-theme

In the directory "themes", in which I had already installed the Bootstrap theme, I create a new subdirectory "themes\mybootstrap". In that subdirectory I create a new empty file "mybootstrap.theme" and a file "mybootstrap.info.yml" with the following content:

name: 'My Bootstrap'
type: theme
description: 'My adaptation of the Bootstrap 3 theme.'
core: 8.x
base theme: bootstrap

regions:
  navigation: 'Navigation'
  navigation_collapsible: 'Navigation (Collapsible)'
  header: 'Top Bar'
  highlighted: 'Highlighted'
  help: 'Help'
  content: 'Content'
  sidebar_first: 'Primary'
  sidebar_second: 'Secondary'
  footer: 'Footer'
  page_top: 'Page top'
  page_bottom: 'Page bottom'

The line "base theme: bootstrap" tells Drupal that this theme is a sub-theme of bootstrap. The regions contain exactly the same regions as the Bootstrap theme on which it is based. This sub-theme is now an exact copy of Bootstrap.

The first thing I want to change is to add some CSS files to the sub-theme. For this I downloaded and saved the fontawesome toolkit to sub-theme subdirectory and in the new subdirectory "themes\mybootstrap\css" I placed a new empty file "mybootstrap.css" for later use.

To make fontawesome and my (still empty) css file available to the sub-theme I add the following to the "mybootstrap.info.yml" file:

libraries:
  - 'mybootstrap/font-awesome'
  - 'mybootstrap/mybootstrap-theme'

The locations of these libraries are defined in the file "mybootstrap.libraries.yml" in the subdirectory "themes\mybootstrap":

font-awesome:
  css:
    theme:
      css/font-awesome.css: {}
mybootstrap-theme:
  css:
    theme:
      css/mybootstrap.css: {}

We are going to use these css files to facilitate some of the changes in the sub-theme.

Build a blog with Drupal 8: Part 2

By Ronald van Belzen | March 24, 2016

I concluded the previous part of this blog with the message that we are not finished yet.

One of the first problems that I am going to tackle is to not display the friendly message of Drupal that "No front page content has been created yet". I would like to install the module Empty Front Page, but it is not available for Drupal 8 yet at the moment of this writing. For that reason I am going to build my own solution by building my own module. I have decided to call that module "My Empty Front Page".

My Empty Front Page

The directory in which I will place the sources is a subdirectory of the module directory: "module\custom\my_empty_front_page". In that directory I first create a file "my_empty_front_page.info.yml" that will provide the Extend page in the Administration section of my site with information about this module.

name: 'My Empty Front Page'
type: module
description: 'My empty front page for Drupal 8 (removes all front end page content when Default front page points to /empty)'
package: Other
version: 1.0
core: '8.x'

Next I need to inform Drupal what controller function to call by creating a routing file with the name "my_empty_front_page.routing.yml" in the same subdirectory.

my_empty_front_page.content:
  path: '/empty'
  defaults:
    _controller: '\Drupal\my_empty_front_page\Controller\MyEmptyFrontPageController::emptyContent'
  requirements:
    _permission: 'access content'

The routing file tells Drupal that for the path '/empty' the controller "MyEmptyFrontPageController" function "emptyContent" needs to be called. The permission tells that the same access permission as for viewing content is to be used. I still need to program that controller in the file "MyEmptyFrontPageController.php" that will be placed in the subdirectory "module\custom\my_empty_front_page\src\Controller".