Drupal 8 Tip: How To Patch A Module Via Composer

In my case I was using the Entity Auto Term module, which issued a patch fixing a known issue. The patch i’m trying to apply is https://www.drupal.org/files/issues/2018-09-28/no-duplicate-terms-2945343-5.patch and part of it looks like this:

To apply it, you have to edit your composer.json located at your website root, pictured here via Filezilla FTP:

I right click view/edit to edit it in Notepad++ here:

I will need to add the red part below. You will most likely have the green part already present, so just edit the red “patches” section to fit your needs.

"extra": {

"installer-paths": {


"web/core": ["type:drupal-core"],


"web/libraries/{$name}": ["type:drupal-library"],


"web/modules/contrib/{$name}": ["type:drupal-module"],


"web/profiles/contrib/{$name}": ["type:drupal-profile"],


"web/themes/contrib/{$name}": ["type:drupal-theme"],


"drush/contrib/{$name}": ["type:drupal-drush"]


},

"patches": {

"drupal/eat": {


"Drupal EAT fix duplicate terms": "https://www.drupal.org/files/issues/2018-09-28/no-duplicate-terms-2945343-5.patch"


}


}


}

Next run Composer Update, and the output should look like this:

That’s it you should be all set.

‘The following module is missing..’ Drupal Error Messages After Update To 7.50

After updating your Drupal site from 7.44 to 7.50 you might see this message when you check your status report.

This happened to me. Below image explains that the admin should install the ‘webform’ module.

1

On another site, I also received the same message, this time looking for the ‘bestreply’ module. But since the error messages are set to ‘NONE’, it only displayed in the logs.

2

This also shows up when you use Drush:

3

Why is this happening?

According to the supporting page for this issue, there are three possible reasons:

  1. You removed a module from the file system without disabling and uninstalling it.
  2. You moved the module inside your Drupal installation.
  3. There is a bug in a module installed on your site.

Like most developers I do a lot of experimentation with modules I am not familiar with and in my case no. 1 definitely applied (you removed a module from the file system …). Sometimes I get confused with the number of attempts I do and I may delete a module without disabling it.

Why is this Necessary?

Removing a module without disabling it leaves a lot of ‘garbage’, eg. code that the module installed but is not necessary anymore. This may become a security risk. Third party modules are maintained independently from the core Drupal files and if the creators / people in charge of that module stop working on it, which occasionally happens, the code eventually becomes outdated and may allow malicious hackers access to other files or even the database.

It’s therefore appropriate to remove modules correctly by disabling it first. To learn more, read the part on the Changelog under ‘Improved performance (and new PHP warnings) when Drupal is trying to find a file that does not exist’

What to do?

The solution is very simple. Merely google the missing module and download it into the /sites/all/modules directory. In my case I didn’t even have to activate it and after checking the status page again the error message went away.

Conclusion

Always properly remove modules. And always read the Changelogs and Blogposts if any, to understand why things are happening the way they are. Version 7.44 to 7.50 represents a major jump as indicated by skipping over .45, .46, etc.. You should be at least even a little curious why that is so reading the Blogpost is extra important to keep updated and avoid surprises.

Drupal 7 Tutorial: Styling Comments Using Views

The default Recent Comments view in Drupal 7 lays out comments in this fashion:

1

Essentially it’s an unordered list (ul) featuring a clickable title of the comment followed by a comma, then a timestamp.

But what if you want the comment to include the name of the author and the name of the node as well, and to rearrange it?

Here’s how:

Step 1.

First, think of how you want the comment to look like and write it down. In the example below we are going to use in the following order:

  1. comment author followed by an
  2. @ sign, then the
  3. title of the node, a
  4. colon punctuation mark, followed by
  5. 96 characters of the comment (linked to the comment), then a
  6. timestamp with ‘ago’ appended.

Step 2.

Clone the ‘Recent Comments’ view in /admin/structure/views.

2

Step 3.

The default ‘Recent Comments’ only has the fields

‘Comment: Title’ and
‘Comment: Updated Date’.

We will add

‘Comment: ID’
‘Comment: Author’
‘(Content) Content: Title’
‘Global: Custom Text’

After some rearranging your fields should look like this:

3

Step 4.

  1. Click ‘Comment: ID’, then click ‘Exclude from Display’. Press Apply.
  2. Click ‘Comment: Title’ then click ‘Exclude from Display’. Press Apply.
  3. Click ‘Comment: Author’ then click ‘Exclude from Display’. Press Apply.
  4. Click ‘(Content) Content: Title’ then click ‘Exclude from Display’. Press Apply.
  5. Click ‘Comment: Updated date’ then click ‘Exclude from Display’. In the Date Format, choose ‘Time Span (with ‘ago / hence’ appended)’. Press Apply.
  6. Click ‘Comment: Comment’ then click ‘Exclude from Display’. Click ‘Rewrite Results’ and in the Link Path box, type ‘/comment/[cid]#comment-[cid]‘ like this:

    4

    Scroll down further and click ‘Trim this field to a maximum length’, and enter ’96’ at the Maximum Length box. Optionally, also click ‘Trim only on a word boundary’ and ‘Add an ellipsis’: Press Apply.

    8

  7. Click ‘Global Custom text’, and enter the following in the ‘Text’ box ‘[name]@[title]:</br>[comment_body]</br>[timestamp]‘ like this:5

Press Apply. The preview should now appear like this:

6

Click Save.

With some CSS styling you can come up with a snazzy looking sidebar comment list like this:

7

Drupal 8 Installation On a VPS

This was done on an Ubuntu 14.04 laptop (named groundcontrol). For all intents and purposes it is similar to a VPS. Just like a VPS it has MySQL, Php and Apache running a virtual host, all current versions as of this time.

This tutorial assumes you have set up your VPS appropriately, with the proper directories prepared, hosts file and DNS ready, etc.

I. Download and un-compress.

Go to Drupal.org, click ‘Download & Extend’

1

Click Drupal 8, right click the latest Drupal core 8.x and select ‘copy link address’.

2

Via SSH, login your VPS and go to the directory you set up for the installation. Here I used ‘/srv/www/d8’.

  • Enter ‘sudo wget’ then right-click your mouse to paste the address on the command line, ie.
sudo wget https://ftp.drupal.org/files/projects/drupal-8.1.1.tar.gz

The latest compressed drupal 8 files will download.

  • Uncompress the file
ghm33@groundcontrol /srv/www/d8 $ sudo tar xvzf drupal-8.1.1.tar.gz

The files will decompress into a folder called drupal-8.1.1.

  • Move all the compressed files in the new drupal-8.1.1 directory into public_html.
ghm33@groundcontrol /srv/www/d8 $ sudo cp -rv drupal-8.1.1/* public_html/

Enter the command ‘ls public_html/’ and you will now see all the drupal 8 directories and files properly laid out.

4

II. Prepare database.

Still in the terminal, login mysql.

sudo mysql -u root -p
  • Enter password to login mysql shell.
  • Create a database:
    create database d8;
  • Create a user and grant privileges to that user on d8:
    grant all on d8.* to 'd8user' identified by 'password';
  • flush priviliges;
  • quit

8

You now have an empty database (d8) and a database user (d8user). List this down.

III. Set up Drupal 8.

Open your browser and enter the url where you placed the drupal 8 files. This should appear:

9

After choosing a language, click ‘standard installation’ in ‘choose profile’.

10

A few errors appear.

  • Fix the clean URLs issue (the .htaccess file was not included when we copied it over).
 sudo cp -rv /srv/www/d8/drupal-8.1.1/.htaccess /srv/www/d8/public_html/
  • Fix the File System issue:
sudo mkdir -p /srv/www/d8/public_html/sites/default/files
  • Fix the Settings file issue:
sudo cp -rv /srv/www/d8/public_html/sites/default/default.settings.php /srv/www/d8/public_html/sites/default/settings.php

Refresh the page. You will probably see these messages:

11

  • Fix the file system issue:
 sudo chmod -R 777 /srv/www/d8/public_html/sites/default/files/
  • Fix the settings file issue:
sudo chmod 777 /srv/www/d8/public_html/sites/default/settings.php
  • Refresh your browser and proceed. Enter the database details prepared earlier.

12

Wait.

13

This message will appear:

14

Enter the ff. commands to fix these:

sudo chmod 444 /srv/www/d8/public_html/sites/default/settings.php

sudo chmod -R 755 /srv/www/d8/public_html/sites/default/files/

You should now have a working Drupal 8 installation.

15

Visit the ‘admin/reports/status’ page first and deal with any issues you find there. We will cover file and directory permissions in another post.

How To Rearrange Drupal Zen Theme Sidebars

Here’s how to rearrange sidebars on any Drupal v7.x website using the Zen theme 7.x.

After installing the Zen theme you will need to put some content onto a block and arrange it in admin/structure/block to appear on either sidebar left or right. In this example below I placed the Navigation Menu on the left sidebar region and the Search Box and Main Menu blocks in the Right sidebar region. By default the main content will appear in the middle:01_before

Let’s say you want to rearrange the layout so that from the left the main content will appear first, followed by the left sidebar and then the right sidebar. Here’s how to do it:

In the following examples we are editing a fixed layout, so you will edit the ‘themes/yourcustomtheme/css/layouts/fixed.css’ (Note: If you are using a responsive layout you will open the ‘themes/yourcustomtheme/css/layouts/responsive.css’).

In this image below, my theme name is ‘momex’, and I am using Notepad++ as my text editor.

02

Go to line 124, under the lines ‘Span 3 columns, starting in 2nd column from left’:

03

There are 3 elements:

  1. .two-sidebars #content selector shows attributes for the main content area.
  2. .two-sidebars .region-sidebar-first selector has attributes for the first sidebar and
  3. .two-sidebars .region-sidebar-second has attributes for the second sidebar.

Since we want the main content to appear on the left of the layout first, we switch the contents of item 1. (‘.two-sidebars #content”) and item 2. (‘.two-sidebars .region-sidebar-first’), like this. Don’t touch item 3 just yet.

04a

The result is like this:

05z

It looks awful yes, but at least we have the main content appearing on the leftmost column first, the ‘left sidebar’ appearing on the 2nd column and the third column where we want it to be.

We can now focus on the width of the left sidebar and the main content.

First we change item 1 (.two-sidebars) width from 176px to 568px, and item 2 (.two-sidebars .region-sidebar-first) from 568px to 176px:

06

Now there’s a huge gap between the first and second sidebar. This is because of the margin-widths of both the first and second sidebars.

So for item 2 (.two-sidebars .region-sidebar-first) we change margin-left from 0 to 196px and margin-right from -196px to -392px.

And for item 3. (.two-sidebars .region-sidebar-first) we change margin-left from 784 to 392px and retain margin-right at -930px.

Voila.
07

Here’s the final css for the FIXED layout code:

/* Span 3 columns, starting in 1st column from left. */
.two-sidebars #content {
 float: left;
 width: 568px;
 margin-left: 0px;
 margin-right: -196px;
 
}

/* Span 1 column, starting in 1st column from left. */
.two-sidebars .region-sidebar-first {
 float: left;
 width: 176px;
 margin-left: 196px;
 margin-right: -392px;
 background-color:#e0e0eb;
}

/* Span 1 column, starting in 5th column from left. */
.two-sidebars .region-sidebar-second {
 float: left;
 width: 176px;
 margin-left: 392px;
 margin-right: -980px;
 background-color:#cbd1d1;
}

And as a BONUS, here is final css for a RESPONSIVE layout with same results, starting on line 249 in the /themes/yourcustomtheme/css/layouts/responsive.css

/* Span 3 columns, starting in 1st column from left. */
 .two-sidebars #content {
 float: left;
 width: 60%;
 margin-left: 0%;
 margin-right: -20%;
 }

/* Span 1 column, starting in 1st column from left. */
 .two-sidebars .region-sidebar-first {
 float: left;
 width: 20%;
 margin-left: 20%;
 margin-right: -40%;
 background-color:#e0e0eb;
 }

/* Span 1 column, starting in 5th column from left. */
 .two-sidebars .region-sidebar-second {
 float: left;
 width: 20%;
 margin-left: 40%;
 margin-right: -100%;
 background-color:#cbd1d1;
 }

Notes:

  • The standard width of the fixed layout is 960px, and this value is key to figuring out the margin-widths.
  • Issuing unique background-colors to your sidebar css helps greatly in distinguishing one from the other.
  • Doing same for a responsive theme is similar if not easier because it uses percentages rather than pixels.

 

 

 

Fastest Way To Batch Change Authors On Drupal 7

Step 1.

import ‘batch_change_content_author’ view from here, or cut and paste the code below. Required modules are Views and Views Bulk Operations:

$view = new view();
 $view->name = 'batch_change_content_author';
 $view->description = '';
 $view->tag = 'default';
 $view->base_table = 'node';
 $view->human_name = 'Batch change content author';
 $view->core = 7;
 $view->api_version = '3.0';
 $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
 /* Display: Master */
 $handler = $view->new_display('default', 'Master', 'default');
 $handler->display->display_options['title'] = 'Batch change content author';
 $handler->display->display_options['use_more_always'] = FALSE;
 $handler->display->display_options['access']['type'] = 'perm';
 $handler->display->display_options['cache']['type'] = 'none';
 $handler->display->display_options['query']['type'] = 'views_query';
 $handler->display->display_options['exposed_form']['type'] = 'basic';
 $handler->display->display_options['pager']['type'] = 'full';
 $handler->display->display_options['pager']['options']['items_per_page'] = '50';
 $handler->display->display_options['style_plugin'] = 'table';
 /* Relationship: Content: Author */
 $handler->display->display_options['relationships']['uid']['id'] = 'uid';
 $handler->display->display_options['relationships']['uid']['table'] = 'node';
 $handler->display->display_options['relationships']['uid']['field'] = 'uid';
 /* Field: Bulk operations: Content */
 $handler->display->display_options['fields']['views_bulk_operations_1']['id'] = 'views_bulk_operations_1';
 $handler->display->display_options['fields']['views_bulk_operations_1']['table'] = 'node';
 $handler->display->display_options['fields']['views_bulk_operations_1']['field'] = 'views_bulk_operations';
 $handler->display->display_options['fields']['views_bulk_operations_1']['label'] = '';
 $handler->display->display_options['fields']['views_bulk_operations_1']['element_label_colon'] = FALSE;
 $handler->display->display_options['fields']['views_bulk_operations_1']['vbo_settings']['display_type'] = '1';
 $handler->display->display_options['fields']['views_bulk_operations_1']['vbo_settings']['enable_select_all_pages'] = 1;
 $handler->display->display_options['fields']['views_bulk_operations_1']['vbo_settings']['force_single'] = 0;
 $handler->display->display_options['fields']['views_bulk_operations_1']['vbo_settings']['entity_load_capacity'] = '10';
 $handler->display->display_options['fields']['views_bulk_operations_1']['vbo_operations'] = array(
 'action::node_assign_owner_action' => array(
 'selected' => 1,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 ),
 'action::views_bulk_operations_delete_item' => array(
 'selected' => 0,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 ),
 'action::views_bulk_operations_delete_revision' => array(
 'selected' => 0,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 ),
 'action::views_bulk_operations_script_action' => array(
 'selected' => 0,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 ),
 'action::flag_node_action' => array(
 'selected' => 0,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 ),
 'action::node_make_sticky_action' => array(
 'selected' => 0,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 ),
 'action::node_make_unsticky_action' => array(
 'selected' => 0,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 ),
 'action::views_bulk_operations_modify_action' => array(
 'selected' => 0,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 'settings' => array(
 'show_all_tokens' => 1,
 'display_values' => array(
 '_all_' => '_all_',
 ),
 ),
 ),
 'action::views_bulk_operations_argument_selector_action' => array(
 'selected' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 'settings' => array(
 'url' => '',
 ),
 ),
 'action::node_promote_action' => array(
 'selected' => 0,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 ),
 'action::node_publish_action' => array(
 'selected' => 0,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 ),
 'action::node_unpromote_action' => array(
 'selected' => 0,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 ),
 'rules_component::scheduler_remove_publish_date_component' => array(
 'selected' => 0,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 ),
 'rules_component::scheduler_remove_unpublish_date_component' => array(
 'selected' => 0,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 ),
 'action::node_save_action' => array(
 'selected' => 0,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 ),
 'action::system_send_email_action' => array(
 'selected' => 0,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 ),
 'rules_component::scheduler_set_publish_date_component' => array(
 'selected' => 0,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 ),
 'rules_component::scheduler_set_unpublish_date_component' => array(
 'selected' => 0,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 ),
 'action::node_unpublish_action' => array(
 'selected' => 0,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 ),
 'action::node_unpublish_by_keyword_action' => array(
 'selected' => 0,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 ),
 'action::pathauto_node_update_action' => array(
 'selected' => 0,
 'postpone_processing' => 0,
 'skip_confirmation' => 0,
 'override_label' => 0,
 'label' => '',
 ),
 );
 /* Field: Content: Title */
 $handler->display->display_options['fields']['title']['id'] = 'title';
 $handler->display->display_options['fields']['title']['table'] = 'node';
 $handler->display->display_options['fields']['title']['field'] = 'title';
 $handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
 $handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
 /* Field: User: Name */
 $handler->display->display_options['fields']['name']['id'] = 'name';
 $handler->display->display_options['fields']['name']['table'] = 'users';
 $handler->display->display_options['fields']['name']['field'] = 'name';
 $handler->display->display_options['fields']['name']['relationship'] = 'uid';
 $handler->display->display_options['fields']['name']['label'] = 'Current author';
 /* Sort criterion: Content: Post date */
 $handler->display->display_options['sorts']['created']['id'] = 'created';
 $handler->display->display_options['sorts']['created']['table'] = 'node';
 $handler->display->display_options['sorts']['created']['field'] = 'created';
 $handler->display->display_options['sorts']['created']['order'] = 'DESC';
 /* Filter criterion: Content: Published */
 $handler->display->display_options['filters']['status']['id'] = 'status';
 $handler->display->display_options['filters']['status']['table'] = 'node';
 $handler->display->display_options['filters']['status']['field'] = 'status';
 $handler->display->display_options['filters']['status']['value'] = 1;
 $handler->display->display_options['filters']['status']['group'] = 1;
 $handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
 /* Filter criterion: Content: Author uid */
 $handler->display->display_options['filters']['uid']['id'] = 'uid';
 $handler->display->display_options['filters']['uid']['table'] = 'node';
 $handler->display->display_options['filters']['uid']['field'] = 'uid';
 $handler->display->display_options['filters']['uid']['value'] = '';
 $handler->display->display_options['filters']['uid']['exposed'] = TRUE;
 $handler->display->display_options['filters']['uid']['expose']['operator_id'] = 'uid_op';
 $handler->display->display_options['filters']['uid']['expose']['label'] = 'Filter by author';
 $handler->display->display_options['filters']['uid']['expose']['operator'] = 'uid_op';
 $handler->display->display_options['filters']['uid']['expose']['identifier'] = 'uid';
 $handler->display->display_options['filters']['uid']['expose']['remember_roles'] = array(
 2 => '2',
 1 => 0,
 4 => 0,
 3 => 0,
 17 => 0,
 7 => 0,
 6 => 0,
 8 => 0,
 9 => 0,
 10 => 0,
 11 => 0,
 12 => 0,
 13 => 0,
 14 => 0,
 15 => 0,
 16 => 0,
 );
 /* Display: Page */
 $handler = $view->new_display('page', 'Page', 'page');
 $handler->display->display_options['path'] = 'admin/content/batch-change-author';
 $handler->display->display_options['menu']['type'] = 'normal';
 $handler->display->display_options['menu']['title'] = 'Batch change content author';
 $handler->display->display_options['menu']['name'] = 'management';
 $translatables['batch_change_content_author'] = array(
 t('Master'),
 t('Batch change content author'),
 t('more'),
 t('Apply'),
 t('Reset'),
 t('Sort by'),
 t('Asc'),
 t('Desc'),
 t('Items per page'),
 t('- All -'),
 t('Offset'),
 t('« first'),
 t('‹ previous'),
 t('next ›'),
 t('last »'),
 t('author'),
 t('- Choose an operation -'),
 t('Title'),
 t('Current author'),
 t('Filter by author'),
 t('Page'),
 );

To import a new view, go to ‘/admin/structure/views/import‘, enter any view name and paste the code above.

1

Once imported you will now have the new view.

2

Step 2.

Just visit the path indicated in the Page Settings, which would be admin/content/batch-change-author.

Step 3.

Perform the steps as needed to change the author of your content.

3z

Notes:

  • Views Bulk Operations (VBO) along with Views are required modules for above operation to work.
  • Changing authors en masse is a crucial step if you are removing users from your Drupal website. You can individually remove users via admin > People > Cancel > Delete, however that can be taxing if you are removing a lot of users.
  • Drush User Cancel (drush ucan) is a good alternative to removing users albeit one by one although it will not let you choose what will happen to orphaned nodes. By default any nodes authored by the canceled user will be changed to ‘anonymous’.

How To Upload the Drupal Government Web Template (GWT) Via CPanel

The Government Web Hosting Service (GWHS) requires all government agencies to host their websites on their servers and use a standardized Government Web Template. While there is a helpful User’s Manual the instructions to upload are meant for Windows users which is not applicable because the only way to upload is via CPanel. This How – To aims to help solve that issue:

  1. Download the gwt-drupal-3.4.3.tar.gz file meant for Drupal sites at https://github.com/iGovPhil/gwt-drupal/releases. It will be installing two items, the Government Web Template to be placed at ‘/sites/all/themes’, and a helper module to be placed at ‘/sites/all/themes’ (the User’s Manual neglected to mention this important fact for some odd reason).
  2. Login your CPanel and click ‘File Manager’, select ‘Web Root (public_html/www)’, and click ‘Show Hidden Files (dotfiles)’.
    20150825_a
  3. Copy and extract the gwt-drupal-3.4.3.tar.gz file onto the HOME folder.
    20150825_b
  4. Go into the gwt-drupal-3.4.3 directory, and right – click the ‘sites’ folder, then click COPY. On the area where it says ‘Copy File To’, enter ‘/public_html’.
    20150825_c
  5. To check whether it copied, you should now be able to see the gwt_drupal_helper module at ‘public_html/sites/all/modules/gwt_drupal_helper’, and the gwt_drupal theme at ‘public_html/sites/all/themes/gwt_drupal’. Login your website and you should also be able to see the new GWT theme at http://yourwebsite.gov.ph/?q=admin/appearance and the new GWT module at http://yourwebsite.gov.ph/?q=admin/modules.20150825_d

    20150825_e
  6. For theming and customization instructions you may refer to the User Manual mentioned above. You may now also optionally delete the gwt-drupal-3.4.3.tar.gz file and the gwt-drupal-3.4.3 folder it created.

These instructions are for Drupal but they are likely the same for WordPress, Joomla and static files too. If you need help email me at info@kaijuhost.com.

How To Fix the commerce_kickstart directory could not be found within the modules directory Issue

I recently came across this issue whilst trying to update a Commerce Kickstart installation via Drush. Error reads:

The commerce_kickstart directory could not be found within the modules directory at [error]
/srv/www/carmarket.ph/public_html/profiles/commerce_kickstart, perhaps the project is
enabled but has been deleted from disk.

There were several modules that needed updating below, so ./drush -u 1 up seemed the proper drush command to update them all in one go.

carmarket_20150806

Continue reading “How To Fix the commerce_kickstart directory could not be found within the modules directory Issue”

Using elFinder Instead Of IMCE Wysiwyg Bridge

I’ve been using IMCE Wysiwig Bridge on all my Drupal sites as it is the easiest to implement. However it is very un user friendly as its UI tends to intimidate users. So I decided to try elFinder which promises to fix that, however it is the exact opposite of IMCE Wysiwyg, being easier to look at and use BUT so much more difficult to install.

The problem is that elFinder’s installation instructions were mostly meant for standalone Wysiwyg installations and not in a Drupal context. So here’s how I did it.

First, install your Wysiwyg module as usual (in my case I used TinyMCE 3.x, which is compatible with elFinder along with many other popular Wysiwyg modules).

Then, download elFinder 1.x (NOT 2.x) and install at /sites/all/libraries, being careful to rename the folder ‘elfinder’, so you’ll end up with

'../sites/all/libraries/elfinder/elfinder.php.html'

activate the elfinder module. If you did not install elFinder properly you will getting the error

‘elFinder library was not found. Please download it from http://sourceforge.net/projects/elfinder/files/ and install to . (Currently using elFinder Not found)’

Now that you have installed elFinder and TinyMCE, you now have to edit TinyMCE so that it will make use of elFinder to find files for you. The link to do that is here https://github.com/Studio-42/elFinder/wiki/Integration-with-TinyMCE-3.x, however the instructions are for a standalone installation.

I learned how to do it in a Drupal setting by reading this: https://www.drupal.org/node/1714068#comment-6812332

Basically all you have to do is make a module like this in your /sites/all/modules folder:

sites/default/modules/MYMODULE/MYMODULE_tinymce_callbacks.js

Then in it, paste this:

file_browser_callback : 'elFinderBrowser'
 function elFinderBrowser (field_name, url, type, win) {
 var elfinder_url = '../sites/all/libraries/elfinder/elfinder.html'; // use an absolute path!
 tinyMCE.activeEditor.windowManager.open({
 file: elfinder_url,
 title: 'elFinder 2.0',
 width: 900,
 height: 450,
 resizable: 'yes',
 inline: 'yes', // This parameter only has an effect if you use the inlinepopups plugin!
 popup_css: false, // Disable TinyMCE's default popup CSS
 close_previous: 'no'
 }, {
 window: win,
 input: field_name
 });
 return false;
 }

Then you go to /sites/all/libraries/elfinder and create ‘elfinder.html’, then paste this inside it:

 

<!-- Include jQuery, jQuery UI, elFinder (REQUIRED) -->

<!-- TinyMCE Popup class (REQUIRED) -->
 <script type="text/javascript" src="../sites/all/libraries/tinymce/tiny_mce/tiny_mce_popup.js"></script>

<script type="text/javascript">
 var FileBrowserDialogue = {
 init: function() {
 // Here goes your code for setting your custom things onLoad.
 },
 mySubmit: function (URL) {
 var win = tinyMCEPopup.getWindowArg('window');

// pass selected file path to TinyMCE
 win.document.getElementById(tinyMCEPopup.getWindowArg('input')).value = URL;

// are we an image browser?
 if (typeof(win.ImageDialog) != 'undefined') {
 // update image dimensions
 if (win.ImageDialog.getImageData) {
 win.ImageDialog.getImageData();
 }
 // update preview if necessary
 if (win.ImageDialog.showPreviewImage) {
 win.ImageDialog.showPreviewImage(URL);
 }
 }

// close popup window
 tinyMCEPopup.close();
 }
 }

tinyMCEPopup.onInit.add(FileBrowserDialogue.init, FileBrowserDialogue);

$().ready(function() {
 var elf = $('#elfinder').elfinder({
 // set your elFinder options here
 url: 'php/connector.php', // connector URL
 getFileCallback: function(file) { // editor callback
 FileBrowserDialogue.mySubmit(file.url); // pass selected file path to TinyMCE
 }
 }).elfinder('instance');
 });
 </script>

Then, go to /admin/config/content/wysiwyg and click ‘edit’ on TinyMCE operations. Click ‘Buttons and Plugins’. You will need to check the ‘Image’ and ‘elFinder’ boxes, and finally you will have your elFinder.

There are lots of options to explore at ‘admin/config/media/elfinder’. I would start with establishing a Custom Path so as to keep files neat and tidy.

kh20150507a

Easy right? No?

Well you’re right. It is downright confusing which is why I’m writing down how I did it here as well. However if it is important to you for your users to have an easier time uploading images to their articles and blog posts then this should be a good alternative to look at.