Recent Blog Posts

Build a blog with Drupal 8: Part 1

By Ronald van Belzen | March 23, 2016

A blog might not be the most challenging CMS type that you can build, but for that reason it might be the best first introduction to a new CMS. Not that I would not need a blog. In fact I want to replace my existing blog and at the same time want to get to know Drupal 8. Having a blog already, that I want to replace, makes it easy to define the requirements for the blog Let's write them down and see how Drupal 8 is able to deliver.

Blog requirements

  1. Create blog posts with title, subject and an optional featured image.
  2. The ability to categorize and browse through content by topics.
  3. Basic search functionality.
  4. A tool for authoring content with a WYSIWYG editor that also supports the display of coding examples.
  5. Listing teasers of the blog posts on the front page sorted by date posted; with a pager (showing 5 topics per page)
  6. Browse the blog posts by category.
  7. Visitors must be able to comment on blog posts.
  8. The blog site needs to be responsive.

Now let's see how Drupal 8 meets these requirements.

Installing Drupal

I am not going to describe how to install Drupal. It is just beyond the scope of this blog post. You can find an installation guide on the Drupal site. The operating system, webserver and database you choose do not really matter for this article. But just in case you are curious: I used Windows 7, IIS 7.5 and MySQL 5.6.

I also assume you can find out how to install themes and modules yourself. You can find this information also on the Drupal site.

Drupal 8 comes with the theme called Bartik installed. The first thing I did was to download, install and set as default the Bootstrap 3 for Drupal theme. I will show how to make a sub-theme based upon this theme lateron, but for now I have met requirement 8 without having to build my own theme.

Categorizing blog topics

For meeting requirements 2 and 6 we are going to use taxonomy (which is part of the Drupal 8 core).

CLinkPager and first page and last page display

By Ronald van Belzen | February 7, 2015

When showing content with CGridView or CListView a pager is included. This pager shows the navigation for 10 pages and a next page and a previous page link.

What is not shown by default are the first and last page links. The simplest way of displaying these links, when you need them, is by overriding the class associated to these links. Below an example is shown for a CListView.

<?php 
$this->widget('zii.widgets.CListView', array( 
  'id'=>'bbiiTopic', 
  'dataProvider'=>$dataProvider, 
  'itemView'=>'_topic', 
  'template'=>'{pager}{items}{pager}', 
  'pager'=>array('firstPageCssClass'=>'previous', 'lastPageCssClass'=>'next'), 
)); ?>

The firstPageCssClass and lastPageCssClass are the values that are overridden.

This is very much a short cut. The proper way to do it is to overwrite the CSS yiiPager.first and yiiPager.last and not to override the pager in a CListView or CGridView at all.

RESTful PHP server API

By Ronald van Belzen | October 12, 2013

There are plenty of manuals on how to make your own RESTful PHP server on the web. One that I found particularly useful was Create a REST API with PHP. It explains the nuts and bolts of how to create a RESTful server with the use of PHP and in some aspects it goes beyond the example I am going to show here, which was inspired by that approach.

Even more useful I found the "RESTful Service Best Practices" manual that can be downloaded from http://www.restapitutorial.com/resources.html.

The index.php file

It is good practice to rewrite the request that needs to be handled by the index.php script. In this approach I placed the index.php file in its own subdirectory (I named that directory "api") together with the following .htaccess file:

RewriteEngine on 
RewriteRule ^images/.*$ - [L] 
RewriteRule ^js/*.js$ - [L] 
RewriteRule ^css/*.css$ - [L] 

# if a directory or a file exists, use it directly 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 

# otherwise forward it to index.php 
RewriteRule ^(.*)$ index.php/$1 [L,QSA]

When you are not using an Apache server, or an alternative that can handle .htaccess, modern PHP offers a solution as I hinted at in a previous blog. I admit, the blog post does not explain how php.ini can mimic .htaccess functionality, but it can. Although, I have to admit, I have never experimented with that myself.

The rewrite rule in the above .htaccess file will cause requests like http://localhost/api/test to be rewritten to http://localhost/api/index.php/test. So let's start with the index.php that needs to handle this request.

Passing data to the CButtonColumn click event

By Ronald van Belzen | July 20, 2013

One of the limitations of the click event of an CButtonColumn is that it does not take data from the CGridView. But passing row specific data to a Javascript on clicking the button is precisely what is needed in many cases.

The simplest workaround is to use jQuery to deliver the required data:

$this->widget('zii.widgets.grid.CGridView', array( 

  // omitted parameters

  'columns'=>array( 

    // omitted columns 

    array( 
      'class'=>'CButtonColumn', 
      'template'=>'{view}', 
      'buttons' => array( 
        'view' => array( 
          'url'=>'$data->id', 
          'click'=>'js:function() { viewPost($(this).attr("href"));return false; }', 
        ), 
      ) 
    ), 
  ), 
));

The trick is that the data is passed to the url and $(this).attr("href") passes it to the function called by the click event. Of course, the click event should return false to prevent the web browser from visiting the url. All navigation (if any) should be triggered by the Javascript in this solution.

Adding Fancybox to an Yii application

By Ronald van Belzen | June 15, 2013

After showing how to add AD Gallery to an application I am showing here how to use Fancybox in an Yii application for the display of an image gallery. "FancyBox is a tool for displaying images, html content and multi-media in a Mac-style "lightbox" that floats overtop of web page." It is capable of showing much more then just images. In fact the Yii module Gii uses Fancybox to display the generated code in a lightbox. But in this example I am just going to show how to use Fancybox with images to show how it can be used to produce an image gallery.

As with AD Gallery Fancybox is not overly complicated, but it is different. In order not to repeat the former blog post too much I am adding pagination to the example, which is useful when using extremely large sets of images. The controller used in the previous example will be changed to look like this:

class OverviewController extends Controller { 
  const PAGE_SIZE = 50;

  // other action functions 

  public function actionView($id) { 
    $model=Gallery::model()->findByPk($id); 
    if($model===null) 
      throw new CHttpException(404,'The requested page does not exist.'); 

    $criteria = new CDbCriteria; 
    $criteria->condition = "gallery_id = $id"; 

    $count = GalleryImage::model()->count($criteria); 
    $pageCount = ceil($count/self::PAGE_SIZE); 
    $pager = new CPagination($pageCount); 
    $pager->pageSize=1; 

    $criteria->order = 'sort ASC'; 
    $criteria->limit = self::PAGE_SIZE; 
    $criteria->offset = self::PAGE_SIZE*$pager->currentPage; 
    $models = GalleryImage::model()->findAll($criteria); 
    $this->render('view', array( 
      'gallery'=>$model, 
      'models'=>$models, 
      'pager'=>$pager, 
    )); 
  } 
}

The class constant PAGE_SIZE represents the number of thumbnail images that will be displayed on a page. The variable $pageCount contains the number of pages that are needed for pagination and is passed to the CPagination class constructor. The page size for CPagination is set to 1, which is not related to the number of images on a page but chosen to make the offset calculation simpler.