Drupal 8: Reviewing and updating diff module

I do not paint things, only the difference between things.

-Henri Matisse

Introduction

How many times you have used the command diff or  git diff  to compare files?. In the simplest case, diff compares and analyzes the content of two files and prints the lines that are different. Essentially, it outputs a set of instructions for how to change one file in order to make it identical to the second file.

However, in some determined cases (e.g. wikis and collaborative documentations) we could need to maintain revisions of the content in our site (a.k.a. revisions). Examples of this are Wikipedia and the Drupal.org site.

19.diff-wikipedia

20.diff-drupal

The module diff

Diff adds a tab for sufficiently permissioned users. The tab shows all revisions like standard Drupal but it also allows pretty viewing of all added/changed/deleted words between revisions.

This module has stable versions for Drupal 6 & 7 but there’s not one for Drupal 8. However Lucian Hangea (@lhangea) have been porting this module as his project for Google Summer Of Code (GSoC). Along this post I will discuss about my experience with it.

Making it work

As you noticed, the last submitted work in GSoC page was on August 26th, 2014 and and as part of Drupal 8 development, it has been changing constantly, so it would have been too much work making all changes, so I started to searching a bit more and found his sandbox repository. I noticed that the last submit was 3 month ago in the branch refactor_to_plugins, so I downloaded using git.

git clone --branch refactor_to_plugins git://git.drupal.org/sandbox/lhangea/2269693.git

That was a good point to start because I also realized that there are too many differences between the version in GSoC page and this, however it still needed some adaptations, so I go ahead doing it and I created an issue and left my patch. I recommend you to download and apply it in order to make it work.

Reviewing the project

Now, here we are. It’s time to start working with the module and to start we need to install it first, so move the folder of the project (with the patch applied) inside ./modules, rename the folder by diff and install it in the path /admin/modules as well as using drush.

drush en diff

Enabling revisions
At this instance we need to enable new revisions for every article content type edit. So, configure it in /admin/structure/types/manage/article and enable the following option
1.active-new-revision

It’s time to add a new article.
2.add-node

3.node-created

And edit it

4.node-edited

You will notice that there is a new tab “Revisions” in the article

5.new-tab-revisions

Click on it and get this

6.revisions-page

Here we have the two revisions of our article and if we look at the diff, we’ll get the following

7.diff-classic-1

Just to see the different options, select Markdown. With this we’re going to see just the text and not the HTML markup

8.diff-classic-2

Do you like the way that github makes diffs?
So, go to the general configuration page of the module in /admin/config/content/diff/general and change the CSS option

9.0.change-for-github

 

And test it

Standard
9.diff-github-1

Markdown
10.diff-github-2

At the moment we can just see the differences in the title and body between the article revisions, but we can add more fields of the node entitie in /admin/config/content/diff/entities/node

11.add-entities

Now, let’s change the publishing status of our article

13-save-unpublished

Compare the last revision with the first and noticed that the publishing status will be detected

14.diff1

We can also configure what field types we want to compare or not in the /admin/config/content/diff/fields. For example, let’s change Text (formatted, long, with summary) (text_with_summary) value by Don’t compare and save the form

15.disable-body

Because our body field belong to this field type, the diff won’t appear

16.diff2

The main issue to solve

I have been making all this proofs just passing values as parameters manually, that is because the module can not alter the view of the entity list.

17.issue-revisions

This is the way that the module allow us select the revisions in Drupal 7

18.how-would-be

I emailed @lhangea asking if he could get this behavior in his previous versions but he hasn’t emailed back yet. However if we look at the code in the file diff.module at line 14 we will see a @todo saying // @todo Follow this issue: https://www.drupal.org/node/1728788. That issue is about create hooks that allow modules alter the view, submit and validation of an entity list building.

Changes in the patch

This is a description of the main changes that my patch updates in the project.

Attaching assets as libraries
The first change done was using libraries in order to add assets (in our case, CSS). This is the part of the patch

new file mode 100644
index 0000000..7cc0893
--- /dev/null
+++ b/diff.libraries.yml
@@ -0,0 +1,17 @@
+diff.general:
+  version: 1.x
+  css:
+    theme:
+      css/diff.general.css: {}
+
+diff.default:
+  version: 1.x
+  css:
+    theme:
+      css/diff.default.css: {}
+
+diff.github:
+  version: 1.x
+  css:
+    theme:
+      css/diff.github.css: {}

So, I changed all $variable['#attached']['css'][] = drupal_get_path('module', 'module_name') . '/path/to/css/diff.general.css'; by $variable['#attached']['library'][] = 'modulename/libraryname'

// Add the CSS for the diff.
-      $build['#attached']['css'][] = drupal_get_path('module', 'diff') . '/css/diff.general.css';
+      $build['#attached']['library'][] = 'diff/diff.general';
       $theme = $this->config->get('general_settings.theme');
       if ($theme) {
         if ($theme == 'default') {
-          $build['#attached']['css'][] = drupal_get_path('module', 'diff') . '/css/diff.default.css';
+          $build['#attached']['library'][] = 'diff/diff.default';
         }
         elseif ($theme == 'github') {
-          $build['#attached']['css'][] = drupal_get_path('module', 'diff') . '/css/diff.github.css';
+          $build['#attached']['library'][] = 'diff/diff.github';
         }
       }
       // If the setting could not be loaded or is missing use the default theme.
       elseif ($theme == NULL) {
-        $build['#attached']['css'][] = drupal_get_path('module', 'diff') . '/css/diff.github.css';
+        $build['#attached']['library'][] = 'diff/diff.github';
       }

 

Callback
I also modified the .routing.yml in order to change the _content key line by _controller

--- a/diff.routing.yml
+++ b/diff.routing.yml
@@ -1,13 +1,14 @@
 diff.revisions_diff:
   path: '/node/{node}/revisions/view/{left_vid}/{right_vid}/{filter}'
   defaults:
-    _content: '\Drupal\diff\Controller\NodeRevisionController::compareNodeRevisions'
+    _controller: '\Drupal\diff\Controller\NodeRevisionController::compareNodeRevisions'
     _title: Diff General Settings
     filter: 'raw'

 

Passing Url objects

And finally, I passed Url objects to l() methods.

@@ -243,12 +243,12 @@ class NodeRevisionController extends EntityComparisonBase {
       $row[] = array(
         'data' => $this->l(
           $this->t('< Previous difference'),
-          'diff.revisions_diff',
+          Url::fromRoute('diff.revisions_diff',
             array(
               'node' => $nid,
               'left_vid' => $vids[$i - 1],
               'right_vid' => $left_vid,
             )
+          )
         ),

Conclusion

Having a good management of our nodes revisions can help us to revert to any previous or posterior revision. This behavior is really useful if we want to build a wiki or a collaborative documentation. However, the needs of knowing what have changed among revisions is really necessary.

To achieve this in Drupal, we have the diff module that allows us see the differences between two revisions, however this module is just release for Drupal 7 & 6 and it’s time to start working with Drupal 8. Indeed, @lhangea, a Google Summer of Code 2014 Student have been working to port it to Drupal 8, but the last commit was 3 month ago, so I took the task of updating this module to the beta 4 and show up how the module works.

 

Final Note

This work have been done for a task in Google Code-In (GCI) 2014. Google Code-in is a contest for pre-university students (e.g., high school and secondary school students ages 13-17) with the goal of encouraging young people to participate in open source.

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s