How to set PHP memory limit and max execution time in your Dockerfile

If you want to set the PHP memory limit and/or max execution time to something other than the default, you can do this in your container during build. Use following in your Dockerfile:

RUN cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini && \
sed -i -e "s/^ *memory_limit.*/memory_limit = 4G/g" 
-e "s/^ *max_execution_time.*/max_execution_time = 0/g" 
/usr/local/etc/php/php.ini

The RUN commands above will copy the default production ini file, and then will modify the memory_limit and set it to 4 gigabytes in the ini file. It also sets the max_execution_time to zero, meaning there is no max.

Modify Search API sort order in Drupal using a hook

If you need to change the sort order of the Drupal 7 Search API using code, here is an example using hook_search_api_query_alter:

function MYMODULE_search_api_query_alter(SearchApiQueryInterface $query) {
    $query->sort('my_field_name', 'DESC');
}

Published
Categorized as Drupal

How to use a relative path to your JS and CSS in Drupal 7

By default, Drupal uses an absolute path, and will insert your domain name into the path to your JS and CSS files.

You can override this, in template.php, like so:

function YOURTHEME_process_html(&$vars) {

  //convert absolute URLs (https://www...) into relative (/some/path) for JS and CSS only
  foreach (array('scripts','styles') as $replace) {
      if (!isset($vars[$replace])) {
          continue;
      }

      $vars[$replace] = str_replace("https://stage.example.com", '', $vars[$replace]);
      $vars[$replace] = str_replace("https://www.example.com", '', $vars[$replace]);
  }

}
Published
Categorized as Drupal

Drupal: How to use the Context Module to include javascript on specific pages

I needed a solution which allowed me to include Optimizely’s A/B testing snippet on certain pages, and have the ability to change those page rules without modifying code.

I do this using the Context module, I apply a class to the body for a node with the path “demo”, like so:

Then, in html.tpl.php, in the <head> of my document, I have the following code:

<?php 
  if (!empty($classes)) {
    if (strpos($classes, 'has-optimizely') !== false) {
      print '<script src="https://cdn.optimizely.com/js/xxxx.js"></script>';
    }
  }
?>
Published
Categorized as Drupal

Images in Drupal RSS Feed, without additional modules

There is an easier way to include the image associated with your node in a Drupal Views RSS feed. No additional modules are required.

Firstly you need to add the Media RSS namespace to your views-view-rss.tpl.php:

<rss version="2.0" xml:base="<?php print $link; ?>"<?php print $namespaces; ?> xmlns:media="http://search.yahoo.com/mrss/">

Secondly, in the row style template for your RSS feed (mine is called views-view-row-rss–market-news-rss-feed–feed.tpl.php), you need add a media element, and enter your image field name, your image style, and your dimensions:

<?php

/**
 * @file
 * Default view template to display a item in an RSS feed.
 *
 * @ingroup views_templates
 */
?>
  <item>
    <title><?php print $title; ?></title>
    <link><?php print $link; ?></link>
    <description><?php print $description; ?></description>
    <media:content url="<?php print image_style_url('news_old_style__300x250_', $node->field_image['und'][0]['uri']); ?>" type="image/jpeg" medium="image" height="250" width="300" lang="en" />
    <?php print $item_elements; ?>
  </item>

Lastly, make the field data available to the template above by adding the following to your template.php

function nadex_preprocess_views_view_row_rss(&$vars) {
  $view     = &$vars['view'];
  $options  = &$vars['options'];
  $item     = &$vars['row'];
 
  // Use the [id] of the returned results to determine the nid in [results]
  $result = &$vars['view']->result;
  $id   = &$vars['id'];
  $node   = node_load( $result[$id-1]->nid );
  $vars['node'] = $node;
}

Thanks to these guys for the inspiration:

Published
Categorized as Drupal, RSS

Drupal: How to access fields in html.tpl.php

When developing my AMP subtheme for Drupal 7, I wanted to only include the amp-youtube extension if the current page actually contained a YouTube video. The amp-youtube extension javascript can only be included in the HEAD of the HTML document, so in Drupal, your html.tpl.php must know about content which is usually only available at node.tpl.php level. Here is the solution:

In your template.php

function MYTHEME_preprocess_html(&$vars) {
//we need to know if the page contains a YouTube video, so we create the variable below and reference it in html.tpl.php
if ($node = menu_get_object()) {
$vars['youtube_video_id'] = $node->field_youtube_video_id;
}
}

in your html.tpl.php

<?php
//include amp-youtube extention if page contains a YT video
if ($youtube_video_id):
?>
    <script async custom-element="amp-youtube" src="https://cdn.ampproject.org/v0/amp-youtube-0.1.js"></script>
<?php endif;?>

 

Published
Categorized as AMP, Drupal

Curata and Drupal Integration

So you want to integrate Curata with your Drupal site? Here’s how:

  1. Install BlogAPI, and Services modules
  2. Enable the above modules, and also “MetaWeblog Provider” and “Old Blogger Provider” for Blog API, and the Services, “Services XMLRPC Server”.
  3. Under Home » Administration » Structure » Services create a new endpoint of type XMLRPC, both name and endpoint URL should be “curata”.
  4. Under the resources tab of your newly created service, check all boxes under “blogger” and “metaWeblog” sections.
  5. At this point you might want to create a new content type for articles published from Curata, it should only contain title, body, image* fields. Having fields other than these, which are required fields, is a problem because will be left blank and therefore prevent Curata from being able to publish. I created a content type called “Curata Article” and referenced it in the step below.
  6. Next you need to create a Role within Drupal, the only permissions it requires are “Manage content with BlogAPI”, “Administer content”, “Curata Article: Create new content”, “Curata Article: Edit any content”, “Curata Article: Delete any content”. Now create a user with this role assigned.
  7. In Home » Administration » Configuration » Web services  » BlogAPI, set the default provider to “Blogger” and select the content type you will allow Curata to publish to, probably the “Curata Article” content type you created in step 5.
  8. Now you’re ready to hook up Curata. Login and go to CCS. Under the share menu, click on CMS then “Add CMS channel”.
  9. Enter your Drupal website URL, the “discover” feature will fail because, unlike WordPress, XMLRPC is not advertised to the world.
  10. Enter your endpoint URL, should be https://www.example.com/curata and provide the credentials for the user account you created in step 6.
  11. Click the authenticate button and Curata will connect and get a list of Content Types it can publish to, as defined in step 7.
  12. The rest of the Curata settings are down to your personal preference. Save all changes and then share some of your approved content from within CCS, ensure it appears in Drupal and you’re all set.

* I have not been able to get Curata to publish images directing into Drupal. To get around this you can edit your “Post Body” field in the Article Display settings within Curata. Here is my post body template:

{% if ARTICLE_PICTURE_URL_FULL %}
<div itemprop="image" itemscope itemtype="https://schema.org/ImageObject">
<figure>
<img src="{{ ARTICLE_PICTURE_URL_FULL }}" alt="{{ ARTICLE_TITLE }}">
<figcaption>{{ ARTICLE_TITLE }} <cite>{{ PUBLISHER_NAME }}</cite></figcaption>
</figure>      
</div> 
{% endif %}

<div class="curata-article-body">
{{ ARTICLE_FULL_HTML }}
<a target="_blank" href="{{ ARTICLE_URL }}">Read the source article at {{ PUBLISHER_NAME}}</a>
</div>

 

Running Acquia DevDesktop under a different user account

So I recently found, due to corporate IT policy, my local admin/elevated privileges had been removed, and therefore I was unable to run Acquia Dev Desktop.

After having corporate IT support enter their administrative credentials, i found my local Drupal site was displaying the “Install Drupal” screen, rather than my local website. This screen is usually displayed when the local database is empty, but after checking my PHPMyAdmin, i could see this was not the case.

Maybe the new username account used to launch Dev Desktop didnt have permission to access the database, or could even see it? Correct, here’s my solution:

I copied this file:

C:\Users\My_Username\.acquia\DevDesktop\DrupalSettings\loc_[sitename]_dd.inc

…to the folder for the new user who has permission to launch DevDesktop:

C:\Users\New_User\.acquia\DevDesktop\DrupalSettings\loc_[sitename]_dd.inc

(The above folder was previously empty)

And, BOOM, now the local Drupal site runs successfully.

 

Published
Categorized as Drupal

Drupal and CKEditor, setting default values in the image properties dialog

Copy this file to the root of your theme directory:

/sites/all/modules/ckeditor/ckeditor.config.js

Edit the file and add the following code which will give a default value to HSpace, VSpace and ensure Bootstrap’s “img-responsive” class will be added to all images:

CKEDITOR.on( 'dialogDefinition', function( ev )
  {
    var dialogName = ev.data.name;
    var dialogDefinition = ev.data.definition;
 
    if ( dialogName == 'image' )
    {
      //set the margins
      var infoTab = dialogDefinition.getContents( 'info' );
      var hspaceField = infoTab.get( 'txtHSpace' );
      var vspaceField = infoTab.get( 'txtVSpace' );
      hspaceField['default'] = '10';     
      vspaceField['default'] = '10';

      //set the default class for images
      var advTab = dialogDefinition.getContents( 'advanced' );
      var stylesheetClassesField = advTab.get( 'txtGenClass' );
      stylesheetClassesField['default'] = 'img-responsive';
    }
  });

Lastly, edit your CKEditor profiles and set “Load ckeditor.config.js from theme path” to “Yes”:

/admin/config/content/ckeditor/edit/Advanced

Done.