Planet Drupal

Subscribe to Planet Drupal feed - aggregated feeds in category Planet Drupal
Updated: 59 min 30 sec ago

Michael J. Ross: RESTful Web Services Module Basics

Thu, 01/01/2015 - 17:01
A Solution for Working with Entities over the Network


This article was published in the print magazine Drupal Watchdog, Volume 4 Issue 2, 2014-09, on pages 30-33, by Tag1 Publishing. The magazine was distributed at Drupalcon Amsterdam 2014, 2014-09-29.

Drupal 7 does not have built-in support for representational state transfer (REST) functionality. However, the RESTful Web Services module is arguably the most efficient way to provide resource representations for all the entity types, by leveraging Drupal's powerful Entity API. Unmodified, the module makes it possible to output the instances of the core entity types — node, file, and user — in JSON or XML format. Further entity type resources and formats are possible utilizing hooks in added code.

As with any REST solution, the RESTful Web Services module supports all four of the fundamental operations of data manipulation: create, read, update, and delete (CRUD). The corresponding RESTful API HTTP methods are POST, GET, PUT, and DELETE, respectively.

Anyone hoping to learn and make use of this module — especially for the first time — will likely be frustrated by the current project documentation, which is incomplete, uneven, and lacking clear examples. This article — a brief overview — is intended to introduce what is possible with this module, and help anyone getting started with it.

We begin with a clean Drupal 7 installation (using the Standard profile) running on a virtual host with the domain name "drupal_7_test". After installing and enabling the module, we find that it does not have the configuration user interface one might expect. In the demonstration code below, we focus on the node entity type for brevity.

Nabbing a Node

The simplest operation — reading an entity instance — is performed using a simple GET request containing the machine name of the entity type and the entity's ID.

To allow an anonymous user to read the node using REST, it is insufficient to grant that role the "View published content". Moreover, the "Bypass content access control" permission has no effect. Rather, the module establishes an "Access the resource" permission for each entity type, which also must be enabled for anonymous users. (When testing anonymous access from a web page, be certain you're not logged into the website in the same browser, because then you are already authenticated.)

In this example, we read the fields in the first page in the Drupal database (node/1), which has a title of "Page Title" and a body field of only "Body text". To display the information in JSON format, in a web browser, the URL would be: http://drupal_7_test/node/1.json

The results are, as expected, in JSON:

{"body":{"value":"\u003Cp\u003EBody text.\u003C\/p\u003E\n","summary":"","format":"full_html"},"nid":"1","vid":"1","is_new":false,"type":"page","title":"Page Title","language":"und","url":"http:\/\/drupal_7_test\/node\/1","edit_url":"http:\/\/drupal_7_test\/node\/1\/edit","status":"1","promote":"0","sticky":"0","created":"1402821494","changed":"1403394617","log":"","revision":null,"comment":"1","comments":[],"comment_count":"0","comment_count_new":"0"}

If you get an HTTP 403 error ("Forbidden"), verify the two required permission settings for anonymous users accessing nodes.

To display the same information as XML, we need only alter the path extension: http://drupal_7_test/node/1.xml

The information is the same, but in a substantially different format:

<node> <body> <value> Body text </value> <summary/> <format>full_html</format> </body> <nid>1</nid> <vid>1</vid> <is_new/> <type>page</type> <title>Page Title</title> <language>und</language> <url>http://drupal_7_test/node/1</url> <edit_url>http://drupal_7_test/node/1/edit</edit_url> <status>1</status> <promote>0</promote> <sticky>0</sticky> <created>1402821494</created> <changed>1403394617</changed> <log/> <comment>1</comment> <comments/> <comment_count>0</comment_count> <comment_count_new>0</comment_count_new> </node>

To get all of the nodes — or at least the first 100, by default — remove the entity ID: http://drupal_7_test/node.json

If we again want to access that first node only, but not use a URL, then we can employ cURL on the commandline:

curl -X GET http://drupal_7_test/node/1.json

More descriptive options, such as --request GET, can be chosen. To see details of operations that may be helpful for debugging, add the -v option (a.k.a. --verbose).

If you do not want anonymous REST requests to have access to your website's content, use HTTP authorization. Apparently, the simplest way to do so is to enable the Basic Authentication Login submodule (restws_basic_auth). Connect by utilizing a username that has the appropriate "Access the resource" permission and begins with the (mandatory lowercase) string "restws". Assuming that the user "restws_user" has a password of "password", then we can display the first node with this command:

curl -X GET http://drupal_7_test/node/1.json -u restws_user:password

The aforesaid username pattern could be represented as the regular expression /^restws.*/. That pattern can be customized in the website's settings.php file. For instance, to grant authorization only to those usernames beginning with the string "WS_", one adds the following (case-sensitive) regex to the settings.php file:

$conf[ 'restws_basic_auth_user_regex' ] = '/^WS_.*/';

Authentication is a substantial topic unto itself, and here we will not delve into cookie and session handling.

Creating or Changing a Node

Rather than using the conventional content management UI for adding an entity resource, we can do it with REST — specifically, a POST request. There are several ways to accomplish this: using the core function drupal_http_request(), or cURL PHP code, or cURL on the commandline, which we will use. Returning to the XML format, we can use a file based upon the one output earlier, containing only those elements needed to create a new node with some content in the body field:

<node> <type>page</type> <title>New Page Title</title> <body> <value> New body text </value> </body> </node>

Assuming that the file is named create.xml, we can create a new node with this command:

curl -X POST -H "Content-Type: application/xml" -d @create.xml http://drupal_7_test/node -u restws_user:password

Assuming the AUTO_INCREMENT value of the nid field in the node table is 1, for example, then the output in the command window would indicate that a second node, node/2, had been created:

<?xml version="1.0" encoding="utf-8"?> <uri resource="node" id="2">http://drupal_7_test/node/2</uri>

If the XML file were missing an essential element, such as the node type, then we would receive an error message such as: 406 Not Acceptable: Missing bundle: type

Modifying an existing node is similar, but instead of using the POST method, use PUT and specify a node ID. The XML file needs even fewer elements:

<node> <title>Modified Page Title</title> <body> <value> Modified body text </value> </body> </node>

The cURL command is straightforward:

curl -X PUT -H "Content-Type: application/xml" -d @modify.xml http://drupal_7_test/node/2 -u restws_user:password

The output will not include any <uri> element containing the node ID, since no new one was created.

Nuking a Node

To remove any entity resource — in this case, the first node in the database — use the DELETE method:

curl -X DELETE http://drupal_7_test/node/1 -u restws_user:password

The baffling yet correct output is merely:


Using this module, one can also: filter the results when querying for multiple resources (by specifying the user ID or taxonomy ID); sort by one of the properties (either in ascending or descending direction); change the default limit of 100 resource references. For debugging purposes, you can enable the logging of the details of all web service requests to a specified file, with a simple addition to the Drupal settings.php file, for example:

$conf[ 'restws_debug_log' ] = DRUPAL_ROOT . '/restws_debug.log';

If in your own explorations, you discover additional techniques and pitfalls, please consider publishing them, as there appears to be both interest and confusion as to how to leverage this module fully.

Copyright © 2014 Michael J. Ross. All rights reserved.

Categories: Elsewhere

Larry Garfield: Building Bridges: 2015 Edition

Wed, 31/12/2014 - 22:11

As most who have met me know, building collaborative communities is a minor passion of mine. 2 years ago, I called on the Drupal community to Get off the Island and connect with other communities.

That call was part of a larger movement within the PHP community to interact more, connect more, and collaborate more than ever before. The PHP Renaissance has been driven in no small part by that greater collaboration between many different PHP communities.

To close out 2014, I spoke with Jeff "JAM" McGuire of Acquia Podcast fame about Drupal and community building, and what it means to be the "Drupal Community" when so much of Drupal isn't Drupal.

And as a final capstone, I made a challenge to the entire PHP community: Don't just talk to each other, build with each other. Get out of your comfort zone and learn something new, from someone else.

Happy New Year, PHP. Let's Build Something Good together.

read more

Categories: Elsewhere

Larry Garfield: 2014: A Year of Travel

Wed, 31/12/2014 - 20:58

As 2014 draws to a close, I look back at the year and realize... holy crap I traveled a lot! I hadn't actually done a fully tally yet, but here's the full rundown:

Sunshine PHP - Miami, FL - February
Drupal South - Wellington, New Zealand - February
Florida Drupal Camp - Orlando, FL - March
MidCamp - Chicago, IL - March
Museums and the Web - Baltimore, MD - April
Lonestar PHP - Dallas, TX - April
Drupal Association Webinar - Online - May
php[tek] - Chicago, IL - May
DrupalCon Austin - Austin, TX - June
Refactor::Chicago (User group) - Chicago, IL - May
Nomad PHP (User group) - Online - June
Crafting Code Tour - Minneapolis, MN; Milwaukee, WI; Cincinnati, OH - July
Design 4 Drupal - Boston, MA -July
Twin Cities Drupal Camp - Minneapolis, MN - August
Madison PHP - Madison, WI - September
DrupalCon Amsterdam - Amsterdam, The Netherlands - September
Symfony Live - New York, NY - October
Higher Ed Web - Portland, OR - October
BADCamp - San Francisco, CA - November
php[world] - Washington, DC - November

In all, I flew 64,082 miles (103,130 kilometers for the metric fans in the audience), presented 29 times, with 13 distinct presentations at 20 conferences and user groups across 3 continents, and spent 82 days on the road (not counting non-conference travel). You know what that means?

It means I created about 10 metric tonnes of carbon pollution.

read more

Categories: Elsewhere

Blink Reaction: Principles of Technical Excellence

Wed, 31/12/2014 - 18:01

Stephen R. Covey wrote in his Seven Habits of Highly Effective People about the concept of being effective in attaining goals by aligning oneself to what he calls "true north" principles. I’ve long been a fan of his teachings and, over the years, have developed an idea of these principles that we apply at Blink whenever we engage a new technical challenge.

Categories: Elsewhere

InternetDevels: Events 2014 sum up

Wed, 31/12/2014 - 17:27

This year was rich in different IT-events of any kind. InternetDevels company also doesn’t stay aside the movements and trends taking place in Drupal community. We care about Drupal development and about the system itself, that’s why we sponsored and took part in different Drupal events all around the world.

Special attention goes out to DrupalCons, of course. There were two of them this year:

Read more
Categories: Elsewhere

Drupal Watchdog: The Drupal 6 to 8 Upgrade Challenge - Part 3

Wed, 31/12/2014 - 17:14

Nathaniel Catchpole , the Drupal 8 release maintainer and Tag1 Senior Performance Engineer, suggested that Drupal shops everywhere could support the release of Drupal 8 by upgrading their own sites and addressing the issues they find along the way. This series chronicles the journey from Drupal 6 to Drupal 8. Part 2: Preparing to Migrate.

Part 1: Readiness Assessment | Part 2: Preparing to Migrate

Part 3: Migrating D6 to D8

I first tried running this migration back in November at BADCamp, where I was able to work with Migrate architect and Tag1 Senior Performance Engineer, Károly “ChX” Négyesi. As a result of our work, there are a few patches I’m using to solve issues I’m still encountering. Before running the migration, I pulled the latest commits to 8.0.x. Everything I describe below took place with Drupal core at commit 3359738e0fe, which contains all the commits through December 24. I re-created a migration manifest as described in Part 2: Preparing to Migrate. I briefly reviewed known issues with the D6 > D8 migration path and followed along with Migrate’s Inline module which allows users to display uploaded files and images inline and it has no 8.x version, I’ll disable the migration and use core’s wysiwyg to replace images.

Migration d6_file Severity Serious Error failed to open stream: No such file or directory EntityFile.php:70 Solution Disable file migration in the manifest Issue/s Blocks

The block migration produced PHP Fatal error: Call to a member function uuid() on a non-object. This is a straight-up bug. I worked with chx, who showed me how to use PHPStorm and xdebug to track down the issue, and we made a patch back at BADCamp, but it still needs work before it’s ready for core. In the meantime, it solved the issue for me, so I used it.

Migration d6_blocks Severity Fatal Error Call to a member function uuid() on a non-object in core/modules/migrate_drupal/src/Plugin/migrate/process/d6/BlockPluginId.php on line 87 Solution Patch: Issue/s Menu Links

This migration was problematic and the patches referenced below didn’t solve the problem. For this simple site, the best recourse was to rebuild the menu system by hand, but this presents a serious issue for any site with complex menus.

Migration d6_menu_links Severity Serious Error PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'menu_name' cannot be null' in core/lib/Drupal/Core/Database/Statement.php:61 Solution Removed the migration from the manifest Issue/s Book Module

I hadn’t bothered removing migrations that were irrelevant. For example, I didn’t have any book content and the module was uninstalled on both sites. Even so, it was still in the manifest, and I hit the following error:

Migration d6_book Severity Trivial Error exception 'Drupal\Component\Plugin\Exception\PluginNotFoundException' with message 'The "book" plugin does not exist.' Solution Removed the migration from the manifest Issue/s Node Setting Promote

The promotion options on the nodes have values, but the labels, Promote and Sticky, as well as their descriptions are not displayed.

Migration d6_node_setting_promote Severity Normal Error base_field_override entity with ID already exists. (drupal/core/lib/Drupal/Core/Entity/EntityStorageBase.php:391) Solution Unsure Issue/s Expand FieldConfig/BaseFieldOverride with methods Vocabulary Migration Errors

I hit errors with respect to the “forum” vocabulary. We’re not using Forums, so I uninstalled it from the D6 site. This removed the error, but nodes were still not associated with their terms.

Migration d6_vocabulary_field_instance
d6_vocabulary_entity_display d6_vocabulary_entity_form_display Severity Serious Error Vocabularies and terms are migrated but are not applied to the nodes Missing bundle entity, entity type <em class="placeholder">node_type</em>, entity id <em class="placeholder">forum</em>. (core/lib/Drupal/Core/Entity/EntityDisplayBase.php:166) Solution Relink The Moment of Truth

Once I’d resolved (or avoided) all the fatal errors and the migration ran cleanly, I visited my new site. On first glance it was a little disconcerting. I’d already run into many of these issues when I ran the migration at BADCamp, and they were still happening. More disconcerting, however, was the discovery that I can’t add new content nor edit any content.

Front Page Not Loading

The first view of the site looked broken, and rebuilding the cache with drush didn’t help either. Still, a lot of things happened with the migration, so I figured I’d try logging in: The login page looked proper, and I went straight back to the home page. Even without even logging in, the theme looked normal. That’s easy enough to cope with. I added this to the Known issues.

Couldn’t Edit Nodes

I couldn’t edit the nodes that had been migrated. I initially lost some time on this because “Recent log messages” referenced reported “Missing filter plugin: filter_null.” which turned out to be irrelevant, but made me suspect the migration. When I verified that the problem occurred with core and not just migrations, I finally checked my Apache error logs, which revealed what I needed to know - I had a local configuration issue:

Migration N/A - Local configuration issue unrelated to migrate Problem Adding or editing nodes led to a white screen. Error PHP Fatal error: Maximum function nesting level of '100' reached, aborting! in /var/www/eight/drupal-beta4/core/vendor/twig/twig/lib/Twig/Node.php on line 141 Solution In php5/apache2/php.ini, I set the xdebug.max_nesting_level = 500 Issue/s Aliases Not Working

I’d encountered this problem at BADCamp and it was still happening: none of the content was loading by URL alias. I looked at the values in the url_alias table, and saw no langcode was set.

MariaDB [tag1six]> select * from url_alias limit 10; +-----+------------------+------------------------------------------------------------+----------+ | pid | source | alias | langcode | +-----+------------------+------------------------------------------------------------+----------+ | 1 | node/9 | blog/jeremy/Achieving_Optimal_MySQL_Performance_for_Drupal | | | 2 | tagadelic | tags | | | 3 | node/12 | performance_checklist | | | 4 | node/16 | Improving_Page_Load_Times | | | 5 | taxonomy/term/11 | Dries_Buytaert | | | 6 | taxonomy/term/7 | Drupal | | | 7 | taxonomy/term/3 | performance | | | 8 | taxonomy/term/10 | scalability | | | 9 | taxonomy/term/9 | Tag1_Consulting | | | 10 | taxonomy/term/14 | ab | | +-----+------------------+------------------------------------------------------------+----------+

I set the value in the database with update url_alias set langcode ='en' and nodes loaded by their alias.

Migration d6_url_alias Problem Nodes wouldn’t load by URL alias Solution Apply patch before migrating or fix in the database after migrating: update url_alias set langcode = 'en'; Issue/s Couldn't Edit Users

Trying to edit users resulted in the errors below., and until all the profile fields were removed, users couldn't be edited at all.

Migration - d6_user_profile_entity_display
- d6_user_profile_entity_form_display
- d6_user_profile_field
- d6_user_profile_field_instance Problem Editing the user resulted in the following: Recoverable fatal error: Argument 5 passed to Drupal\Core\Field\WidgetBase::__construct() must be of the type array, null given, called in /var/www/tag1/eight/drupal/core/lib/Drupal/Core/Field/WidgetPluginManager.php on line 130 and defined in Drupal\Core\Field\WidgetBase->__construct() (line 55 of ore/lib/Drupal/Core/Field/WidgetBase.php). Notice: Undefined index: third_party_settings in Drupal\Core\Field\WidgetPluginManager->createInstance() (line 130 of core/lib/Drupal/Core/Field/WidgetPluginManager.php). Solution None yet. There is work in progress on profile fields. I opted not to migrate the user profiles since we’ll be doing extensive work on them anyway. Issue/s Node Authors not Migrated

During the BADCamp migration, I saw that node authors weren’t being set. I experimented with putting the user migrations before the node migrations, which worked, but a more proper approach is in under development and a patch available at

Migration d6_node d6_node_revision Problem Node authors weren’t being set Solution Patch: Issue/s

This concludes what was reasonably possible with Migrate this week. I think it bears repeating that Migrate is NOT a requirement for a Drupal 8 release candidate, nor for Drupal 8 itself. With more than 85 critical core issues, it’s likely that Migrate won’t be ready for site builders for quite some time. Developers, however, can pitch in!




Site comments



- d6_block
- d6_block_content_body_field
- d6_block_content_type
- d6_custom_block

Blocks need to be placed within the theme, but migrate fine.



- d6_cck_field_revision
- d6_cck_field_values
- d6_field
- d6_field_formatter_settings
- d6_field_instance
- d6_field_instance_widget_settings

No visible problems.



- d6_comment
- d6_comment_entity_display
- d6_comment_entity_form_display
- d6_comment_entity_form_display_subject
- d6_comment_field
- d6_comment_field_instance
- d6_comment_type

These migrated seamlessly.



- d6_file
- d6_file_settings

Files are a work-in-progress. See


Input Filters

- d6_filter_format

These migrated fine, but I preferred to update to the filter formats provided with Drupal 8.



- d6_menu
- d6_menu_settings
- d6_menu_links

Hierarchical menu links were problematic. Single level menus migrated successfully.



- d6_node
- d6_node_revision
- d6_node_setting_promote
- d6_node_setting_status
- d6_node_setting_sticky
- d6_node_settings
- d6_node_type

Nodes migrated successfully with the small exception of the labels for Promote to Front Page and Sticky.


System Settings

- d6_syslog_settings
- d6_system_cron
- d6_system_file
- d6_system_filter
- d6_system_image
- d6_system_image_gd
- d6_system_logging
- d6_system_maintenance
- d6_system_performance
- d6_system_rss
- d6_system_site




- d6_taxonomy_settings
- d6_taxonomy_term
- d6_taxonomy_vocabulary
- d6_term_node
- d6_term_node_revision
- d6_vocabulary_entity_display
- d6_vocabulary_entity_form_display
- d6_vocabulary_field
- d6_vocabulary_field_instance

Vocabularies and terms migrated. Freetag terms weren’t associated with their nodes.



- d6_upload
- d6_upload_entity_display
- d6_upload_entity_form_display
- d6_upload_field
- d6_upload_field_instance

Uploads didn’t migrate.



- d6_user
- d6_user_contact_settings
- d6_user_mail
- d6_user_picture_entity_display
- d6_user_picture_entity_form_display
- d6_user_picture_field
- d6_user_picture_field_instance
- d6_user_picture_file
- d6_user_profile_entity_display
- d6_user_profile_entity_form_display
- d6_user_profile_field
- d6_user_profile_field_instance
- d6_user_role
- d6_user_settings
- d6_profile_values

User profile fields and pictures didn’t migrate properly, but users did.



- d6_action_settings
- d6_date_formats
- d6_dblog_settings
- d6_locale_settings
- d6_search_page
- d6_search_settings
- d6_simpletest_settings
- d6_statistics_settings
- d6_text_settings
- d6_update_settings
- d6_url_alias
- d6_view_modes

These either migrated successfully or weren’t significant values on the site


Not run

#- d6_aggregator_feed
#- d6_aggregator_item
#- d6_aggregator_settings
#- d6_book
#- d6_book_settings
#- d6_forum_settings
#- d6_contact_category
#- d6_contact_settings

There was no need to run these

Categories: Elsewhere

Palantir: Explaining Panels: An Overview for Drupal Developers

Wed, 31/12/2014 - 16:54

In my time as a Drupal developer I've had plenty of long and— and sometimes heated— conversations about Panels module. Is it good? Is it too complex? Does it make a site faster or slower? Those are all fine questions to debate; after first agreeing what is Panels?

First, when people talk about "Panels" there are numerous submodules and supporting projects they might be referring to as well. To understand where the lines are drawn between the modules I like to look at which existing Drupal concepts each module augments.

Panels module is a User Interface on top of theme() and hook_theme()

I suspect the common introduction to Panels is something like:

It's very easy to get overwhelmed by the number of options, buttons and links. So let's start simpler: a two column layout.

The code needed to declare that this two column layout exists at all is really small. Browse around the directory declaring it. There is not much there. An info array tells us most importantly that we have left and right regions.

  'regions' => array(
    'left' => t('Left side'),
    'right' => t('Right side')


And there's a template file that prints the left and right regions.

<div class="panel-display panel-2col clearfix" <?php if (!empty($css_id)) { print "id="$css_id""; } ?>>
  <div class="panel-panel panel-col-first">
    <div class="inside"><?php print $content['left']; ?></div>
  <div class="panel-panel panel-col-last">
    <div class="inside"><?php print $content['right']; ?></div>


The simplicity of this layout plugin (aside from its love for divs and css classes) makes it easy to forget that it is an abstraction layer on top of the hook_theme() and theme(). When most Drupalers think about the theme system, they think about the complexity.

Not many people in the world completely understand this diagram. Source:

At the heart of this complexity, is the simple idea that you use hook_theme() to tell Drupal that there's a type of thing that you would like to print in the future (like a two column layout). And that thing will require some variables (like ‘left' and ‘right'). Then at any time theme() can be asked to print a two column layout and all that it needs is to be told are the values of ‘left' and ‘right'.

So how do we figure out what is actually supposed to go in ‘left' and ‘right'? Panels answers that question in a way that is fundamentally different from nearly all Drupal Core usages of hook_theme()/theme(). Core's node module uses hook_theme() to say "Hey, in the future I'm going to ask to you print a ‘node' and I'll give you is a variable called ‘node'". And what it really means is "Oh, yeah, and I'm going to need a ton of preprocessing to derive some variables that can actually be printed in a template." When that Panels layout plugin says "I really only need ‘left' and ‘right'", it can do so because Panels has a separate subsystem for building up those variables.

If you wanted Core to print a node into two columns then you would likely rely on preprocessing and template overrides to figure out what goes where inside theme(‘node'). Panels can take a node and follow instructions for splitting it into ‘left' and ‘right' before calling theme(‘twocol').

This somewhat academic distinction opens up a different mental model for developers. Core encourages you to think "I'm rendering a node and I'll alter and override what that means once I start doing it." Panels encourages you to think "I know I want a two column layout and here is the configuration to split up this node accordingly." In an upcoming blog post I will explain why I prefer the second way of thinking.

Page Manager is a UI on top of hook_menu() and hook_menu_alter()

The response you get when visiting a URL on a Drupal site is determined largely by hook_menu(). When you go to the user register page you see a registration form because the user module told hook_menu() that a registration form belonged there. Other stuff may appear in Blocks in sidebars, footer and headers that are outside the knowledge of hook_menu(). hook_menu() primarily controls the main response that shows up in the "content" region of page.tpl.php

If you're on a music website that has a Taxonomy term of "Jazz" you might see a listing of every node on the site tagged in Jazz. That's what taxonomy module tells hook_menu() to put in the response for a taxonomy term page. On the other hand, if I were running a music website I would probably want my page for Jazz to be a little more customized than a simple listing of everything on the site tagged in Jazz. Let's step up the complexity just a little and imagine that the term pages for music genres should separately group musical artists, albums and songs.

Here the distinction between Panels and Page Manager becomes cloudy. Page Manager tells Drupal "I know taxonomy module told you how term pages look, but I am overriding that. Use this Panels configuration instead." Page Manager changes the way Drupal responds to existing paths as well as telling Drupal about new ones.

Panels is not even necessary to use Page Manager. Out of the box, Page Manager gives you the option to override existing URL paths just to change the HTTP response code (for that rare case where you want node/%node to respond with a 403 for anonymous users but don't want to use the node access system). There are even other modules like Contextual Adminstration which use Page Manager to add more administrative options.

To go over that Jazz use case one more time, Page Manager:

  • Overrides the normal ‘list all nodes' behavior declared by Taxonomy module.
  • Replaces it with a package of Panels configuration which
    • Declares the layout it wants
    • Contains instructions for populating the regions of that layout based on the given "context" (the taxonomy term "Jazz")
Panels Everywhere is a UI alternative to page.tpl.php and Blocks UI

I just mentioned above that Page Manager is the way to control the the "content" region inside page.tpl.php. Panels Everywhere is meant to entirely replace your typical page.tpl.php customizations and the Block configurations that feed that file.

The Core block system encourages a "global" mindset.

This block will show up on every page except those the pages whose URL paths match a certain pattern.

Blocks can also be restricted by user role.

This model implicitly asks you to think "all of my Blocks are going to show up all of the time except for when I tell them not to show up." You can simultaneously think in the inverse of "this Block will never show up except for this one page." That model can put too much in the site builder's head at once; especially when there is another way to change what happens at this global, Block level. With Core's tools you can always override page.tpl.php with something like page--front.tpl.php. That template can change the overall markup of the front page as well as change what regions will actually print their Blocks. Now you have another independent paradigm to keep in mind when asking yourself "should I expect this block to print?"

Panels Everywhere allows for those two concepts to be united. Decide on your layout first and then pull in the contents of the layout regions. Core will load Blocks even if an override of page.tpl.php has nowhere to print them.

With Panels Everywhere, just like Core, you will have to figure out if a given element should be controlled by main page response (hook_menu()/Page Manager) or if the element is a more global decoration (Blocks/Panels Everywhere). An advantage of the Panels Everywhere / Page Manager combo is that the same workflows and concepts apply in both places.

Categories: Elsewhere

Evolving Web: Creating a Multilingual Install Profile for Drupal

Wed, 31/12/2014 - 16:53

Drupal allow you to set up installation profiles to fast-track creating a website. Rather than starting from scratch each time you create a site, you can select an install profile that does some initial configuration for you. This is super useful if you make a lot of websites that start the same way. I think multilingual websites are a good example, since there's a lot of configuration that gets repeated.

read more
Categories: Elsewhere

Acquia: 2014 greatest hits – Drupal 8 means better business – Michael Schmid

Wed, 31/12/2014 - 15:53
Language Undefined

I am looking back on a great year of events and conversations with people in and around Acquia, open source, government, and business. I think I could happily repost at least 75% of the podcasts I published in 2014 as "greatest hits," but then we'd never get on to all the cool stuff I am lining up for 2015! Nonetheless, here's a recording from one of my favorite moments from 2014: Drupal Dev Days in Szeged Hungary, where more than 300 contributors went wild working together on Drupal, I was honored to be the keynote speaker, and where Adam Juran and Campbell Vertesi debuted their now-legendary "Coder v Themer" ultimate smackdown grudge-match. In this podcast, Michael "Schnitzel" Schmid and I talk Drupal 8 from his perspective as a service provider.

Categories: Elsewhere

Code Karate: Using Drupal views pager feature to display users

Wed, 31/12/2014 - 14:16

From time to time we get a question that we feel would be beneficial to more than just the person

Categories: Elsewhere

Mediacurrent: Understanding the Value of a Drupal-centric Agency

Tue, 30/12/2014 - 22:52

Over the last 7+ years, I’ve talked to hundreds of prospects and customers regarding their strategy for ongoing Drupal-based website support. Most organizations tend to agree that their web presence is the single most important marketing tool they can leverage to engage their target audiences.

Categories: Elsewhere

Open Source Training: Drupal File Access for Specific User Roles Only

Tue, 30/12/2014 - 21:26

By default, Drupal file fields have very limited permission options.

So, if you want to make some files available only to certain user groups, you'll need an extra module.

For some simple examples, we recommend the Private files download permission module.

In this tutorial, we'll show you how to use that module to allow only logged-in users to download a file.

  • Go to Configuration > File system.
  • Here you can enter a folder which is only for private files. This means that files in this folder will not be publicly available on the internet.

Some notes on this folder for private files:

  • You will have to create this folder manually. Drupal will tell you if there are any problems with this folder.
  • You must also click "more information about securing private files". That page will give you instructions on making sure your folder is private.

Now you can set up added permissions for your files.

  • Install the Private files download permission module.
  • Enter a path for this set of file uploads. In this example I used "loggedin_files" because that folder will be for files accessible only to logged in users.
  • Under "Enabled Users" and "Enabled Roles", choose who can download these files.
  • Go to Structure > Content types > Manage fields
  • Create a new field using the "File" type.
  • Enter the file directory that you choose in the previous step:
  • Save the field.
  • Create a test content item using the File field:
  • Logged in users should now be able to see and access the file.
  • Visitors who are not logged in will be able to see the file, but when they click on it, they'll get an "Access denied" message:
Categories: Elsewhere

Open Source Training: Date and Time Formats in Drupal

Tue, 30/12/2014 - 20:02

One of our members had this question for us:

"I'm using the Date module and I would like it to display morning as AM and evening as PM. At the moment it shows 15:00, but I'd like it to show 3 PM".

In this tutorial we'll answer that question and show you how to set up Date and Time formats in Drupal.

Categories: Elsewhere

Cheeky Monkey Media: A Quick Look Back at BADCamp 2014

Tue, 30/12/2014 - 18:00

This year, I was invited to attend BADCamp 2014. No, I know what you are thinking, but this is not a camp for bad web developers. In fact, its quite the opposite. Badcamp stands for Bay Area Drupal Camp. This is a four day, annual event held in the San Francisco Bay area. Basically, its a gathering of like-minded web developers discussing and learning about Drupal.

Having never been to a major Drupal event, I jumped on the opportunity to go. It was a fun trip full of learning, networking and maybe an after...Read More

Categories: Elsewhere

Drupalize.Me: Drupal 8 Upgrade Path

Tue, 30/12/2014 - 15:00

All this excited talk of Drupal 8 has a lot of people dreaming of the day they get to start working with it. Some people get to build new sites from scratch all the time, but a lot of Drupal work out there is maintaining and upgrading existing sites. How will the Drupal 8 upgrade path work, and will it be as shiny as Drupal 8 itself? Well, upgrades will be radically different in Drupal 8, and I'd say it has all the shiny you could possibly want.

Categories: Elsewhere

Open Source Training: Google Maps in Drupal with the GMap Module

Tue, 30/12/2014 - 02:04

Several times in the last few weeks, OSTraining students have asked us about maps in Drupal.

The students wanted to set up directories that would show Google maps for each location.

They also wanted to create larger maps that would display multiple locations at once.

We recommended that the students use the GMap module. However, although that module is powerful, it is poorly documented and can be confusing to use.

So, here's a beginners guide to the GMap module.

Categories: Elsewhere

Code Karate: Drupal 7 Draggable Captcha - a more friendly way to prevent Spam

Mon, 29/12/2014 - 01:50
Episode Number: 187

The Drupal 7 Draggable Captcha module is not like most captchas. A captcha is a way to catch or capture spam and prevent a bot from completing a form. This is one of the most widely used ways to prevent SPAM on a website. Drupal has many different types of captchas available and the Draggable Captcha is one of the more fun and easy ones.

Tags: DrupalDrupal 7Drupal PlanetSpam Prevention
Categories: Elsewhere