Feed aggregator
DrewPull - The Drupal Blog: Drupal 7 Field API sample
Recently I had to create a custom field for a project I am working on. The field was not difficult to implement, it only had to store two values in the database, but I didn't found a sample tutorial for that so I want to share my experience with you.
If you take a look at the Examples module, you can find a sample field that stores one value in the database, but this sample will show you how to store more data. In fact this field will store two values retrieved from The Internet Chuck Norris Database. One numeric value that represents the joke identificatior and a text value that holds the joke itself, for example:
Chuck Norris once ordered a Big Mac at Burger King, and got one.
First step to create our custom field is to create the database structure to store the data. This can be done using the hook_field_schema in the .install file of your module.
/** * Implements hook_field_schema(). */ function field_chuck_field_schema($field) { $columns = array( 'id' => array( 'type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE ), 'joke' => array( 'type' => 'varchar', 'length' => 2048, 'not null' => FALSE ), ); return array( 'columns' => $columns, ); }You can create as many columns as you want to store your data. Just take into account the supported types.
Next step is to create a .module file to hold the field specifications starting with the hook_field_info:
/** * Implements hook_field_info(). * Provides the description of the field. */ function field_chuck_field_info() { return array( 'field_chuck' => array( 'label' => t('Chuck Norris Joke'), 'description' => t('Creates a field for Chuck Norris jokes.'), 'default_widget' => 'field_chuck', 'default_formatter' => 'chuck_norris_joke', ), ); }In this hook we create our field name "field_chuck" and the default widget and formatter names. Then we describe the field widget with hook_field_widget_info telling Drupal the name of the widget, a label for it and for what field types it's designed:
/** * Implements hook_field_widget_info(). * Expose Field API widget types. */ function field_chuck_field_widget_info() { return array( 'field_chuck' => array( 'label' => t('Chuck Norris Joke'), 'field types' => array('field_chuck'), ), ); }Also we must tell Drupal the field widget structure with hook_field_widget_form:
/** * Implements hook_field_widget_form(). * Return the form for a single field widget. */ function field_chuck_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { $element += array( '#type' => $instance['widget']['type'], '#default_value' => isset($items[$delta]) ? $items[$delta] : '', ); return $element; }This hook implementation is different than the one in the Examples module but I guess this is more customizable because we can use hook_element_info to implement our own Form API element types with their values:
/** * Implements hook_element_info(). * Declare the field Form API element types and specify their default values. * @see field_chuck_field_process(). */ function field_chuck_element_info() { $elements = array(); $elements['field_chuck'] = array( '#input' => TRUE, '#process' => array('field_chuck_field_process'), ); return $elements; }Now we can create the field Form API elements in the #process callback function:
function field_chuck_field_process($element, $form_state, $complete_form) { $element['submit'] = array( '#type' => 'markup', '#markup' => t('Go!'), '#prefix' => '<div id="field-chuck-submit"><h2>', '#suffix' => '</h2></div>', '#attached' => array( 'js' => array(drupal_get_path('module', 'field_chuck') . '/field_chuck.js'), ), ); $element['joke'] = array( '#type' => 'textfield', '#title' => t('Chuck Norris Joke'), '#default_value' => isset($element['#value']['joke']) ? $element['#value']['joke'] : '', '#prefix' => '<div id="field-chuck-joke">', '#suffix' => '</div>', '#maxlength' => 2048, '#size' => 100, ); $element['id'] = array( '#type' => 'textfield', '#title' => t('Joke ID'), '#default_value' => isset($element['#value']['id']) ? $element['#value']['id'] : '', '#prefix' => '<div id="field-chuck-id">', '#suffix' => '</div>', '#size' => 4, ); // To prevent an extra required indicator, disable the required flag on the // base element since all the sub-fields are already required if desired. $element['#required'] = FALSE; return $element; } The final steps are:- Create the implementation of hook_field_load if we want to process the data before loading it in the field widget.
- Don't forget that the implementation of hook_field_validate and hook_field_is_empty are required for a correct field validation.
- Also we can implement hook_field_presave if we want to alter the data before storing it in the database.
- Create the custom field formatter using hook_field_formater_info and hook_field_formatter_view as I explained in a previous post.
The full example code can be downloaded from my Drupal sandbox and includes the javascript to fetch the Chuck Norris jokes, so I hope you will enjoy it :)
Tags: drupal 7fieldwidgetformatterDrupal PlanetAdvomatic: SASS + Compass + Modernizr and browser information detection
Jack, my co-themer here at Advomatic, and I will be doing a series of articles about how we use SASS and Compass on our projects. There are plenty of articles out there on what it is and how to get started, so we wanted to dig a little deeper, and share a few tips and ideas.
Credit: mccun934
Today I'll talk about Modernizr, which is a javascript library that will check to see if your browser supports HTML5 and CSS3 features. We use it on every project now to make sure we aren't serving unsupported stuff to browsers that can't handle it. One thing Modernizr does is add classes to your HTML tag, like "cssgradients" or "no-cssgradients," or "textshadow" or "no-textshadow" as the case may be. Combined with SASS, this can be a very simple way to limit your CSS3 work.
Here's an example of how we now apply any of our css3 theming, using the way SASS allows you to check for parent classes, and the nice CSS3 includes of Compass.
h1.title { // A double border, for browsers that support box shadows; single border for those that don't.border-bottom: 1px solid #c3c3bf;
.boxshadow & {
@include box-shadow($white 0 1px);
}
}
Here's a slightly more elaborate example:
#footer {background-color #114163: // a baseline background color
.lt-ie10 & { // dirty proprietary filter for IE9 and below
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#2074b1', endColorstr='#114163');
}
.cssgradients & { // gradient for CSS3-supporting browsers
@include background-image(linear-gradient(#2074b1, #114163));
}
}
By the way, that handy ".lt-ie10" class on the html tag is standard now in Drupal's Zen base theme. It's very handy. While we try to avoid it, we also will add in classes for .mac, .pc, .chrome, .firefox and .safari, if we have some extremely browser-specific problems, which is rare. If you are curious, here's the javascript we use to add that information to the html tag.
Drupal.behaviors.targetBrowsersOS = {attach: function (context, settings) {
// Check to see which operating system we're using.
if (navigator.appVersion.indexOf("Mac")!=-1) {
$('html').addClass('mac');
}
else {
$('html').addClass('pc');
}
// Check to see if the browser is Safari and doublecheck that it is not Chrome.
if (navigator.userAgent.indexOf('Chrome') > -1) {
$('html').addClass('chrome');
}
if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
$('html').addClass('safari');
}
if (navigator.userAgent.indexOf('Firefox') > -1) {
$('html').addClass('firefox');
}
if (navigator.userAgent.indexOf('MSIE') > -1) {
$('html').addClass('ie');
}
}
}
So, as you can imagine, this gives you the ability to customize what css various browsers are served, and leaner, cleaner experience all around. Stay tuned for more SASS/Compass tips and tricks!
Phase2: Ready, Set, Go! Spin Up An Omega Layout in 45 Minutes Flat!
Last night I presented at the SFDUG Meetup (you can find my slides on the Phase2 slideshare). There were some great questions and Drupal theming discussion at the end of my presentation. Here are a few of those questions that came up, as well as the answers:
Q: How does Omega compare to a simpler Drupal theme in terms of performance?A: There are trade-offs as with anything. Phase2 has used Omega for a number of large site projects including Georgia.gov and Fema.gov. There are scaling concerns with any complexity in a system but it is by no means a road block.
Q: Is Delta only used for Omega?A: Delta was made by the same people who wrote Omega, so this will be your best compatibility, but it is compatible with other themes as well.
Q: Can we use custom grid systems with Omega 3?A: Yes, you can. You have to write some custom code to handle compatibility. There is documentation you can refer to if you interested in trying it out.
To experience the full session experience, check out this recording of my session:
Omega from Download to Layout from Phase2 on Vimeo.
Thanks to the San Francisco Drupal Users Group for inviting me to talk!
Drupal Association News: Sponsored blog post: Drupal: the wonder CMS
Open Source software, namely Drupal, can be leveraged to accommodate the technology needs of numerous corporations across a vast spectrum of private and public sectors. The constant collaboration of the Drupal community gives users the freedom to rapidly deploy new innovations in a way that a closed proprietary system does not allow. Here at Achieve we are constantly trying to increase Drupal adoption by developing new solutions to help new stakeholders in new arenas.
Personal blog tags: DrupalCMSHealthcareSina Salek Official Site: Drupal Module : Calendar Systems needs your help
Calendar system requires a very tiny core patch to fully work, The patch was already proposed to core by a fellow developer, so i rewrote it to meet core requirements and set it to needs review (Thanks to Gaelan and wuinfo for helping in completing the patch). The good thing is that the patch is not only for Calendar Systems it's a generic patch that introduces a new hook to make it possible for third-party modules to alter format_date function. If we can get it into core it might even be possible to back port it to Drupal 7
You can read more about the history of calendar system module and even what a calendar system is
WebbyKat: Grouping by year (or month and year) in a view
Views offers a neat grouping mechanism that allows you to list content with matching criteria under said criterion. For example, if you had 3 press releases from 2011 and 2 from 2010, you could display them like this:
2011- Press Release #5 (April 1, 2011)
- Press Release #4 (March 31, 2011)
- Press Release #3 (January 25, 2011)
- Press Release #2 (December 3, 2010)
- Press Release #1 (June 1, 2010)
To do this, you create a view with three fields:
- Title (linked to node)
- Date (in Month Day, Year format)
- Date (in Year format; exclude this from display) -- if you want to save yourself some confusion later, open this field, go to the "More" section, and enter "Year (grouping header)" to make it clear why this field is there even though it's not shown
Next to your view format (unformatted list, HTML list, etc.), click Settings, and then pick your second date field as the grouping header under "Grouping field Nr.1". Check off "Use rendered output to group rows." Save.
I've done this quite a few times, but on my current site, I found that even when I told it to group by year, it was coming out like this:
2011- Press Release #5 (April 1, 2011)
- Press Release #4 (March 31, 2011)
- Press Release #3 (January 25, 2011)
- Press Release #2 (December 3, 2010)
- Press Release #1 (June 1, 2010)
This makes a little sense, since the dates all technically are different, but it's supposed to be grouping by the rendered output, which is just 2011 and 2010. I dug around and found that even though it looked like just "2011" to the naked eye, the code was actually <span class="date date-display-year" property="dc:date" datatype="xsd:dateTime" content="2011-04-01T05:00:00-05:00">2011</span>. The month, day, and even time values were still being stored even though they weren't visible.
To fix this, I opened the year field, went to the Rewrite Results section, and checked "Strip HTML tags." This gets rid of the code that differentiates the values from each other, leading to the expected grouping behavior. If you wanted to do the same thing for month and year grouping headers (e.g. December 2010), all you'd need to do is change the format of your grouping field to use the month and day instead of the year.
For more on date formats, see Modifying the page display for a monthly archive view (the "Three steps, for reusing" section).
Forum One: The Dream of Drupal is Alive in Portland
Like the ’90s, Drupal really is alive in Portland, the city made popular again from the much-watched TV show, Portlandia. Portland is the homebase for the Drupal Association and host for this year’s DrupalCon, Drupal’s largest North American conference.
This will be Forum One’s biggest presence at DrupalCon since we went to our first conference in Washington, DC, in 2009. We’ll have 17 web developers, project managers, and strategists attending the event from our offices in San Francisco, Seattle, and DC. We can’t wait to meet more Drupalers, share our experiences, and explore Portland!
During our Day Stage session, EPA.gov: Building a Sustainable Drupal Platform, we’re excited to share the challenges and successes we faced in migrating EPA’s large web presence to Drupal. In a “game-show” style session, we’ll investigate how we navigated the unique needs of a large government agency, share project challenges, champion our successes, and provide best practices for other large organizations considering moving to Drupal.
Another highly anticipated session is What Users Want (or Why Webpages are Dead) by Nam-ho Park and Stein Setvik. They’ll dive deep into real questions about the future of websites in the face of the rise of mobile and explore the implications for Drupal.
Each year, it is encouraging to see Drupal growing. With 613 active distributions and more than 25,000 contributors, Drupal is now the largest and most recognized open-source community. It will be interesting to see how keynotes from Dries Buytaert, Karen McGrane, and Michael Lopp address the sheer size of the project and how to get Drupal to even more users.
If you’re going to be in Portland next week, stop by our booth. We’ll have free “Nodetoriusly” awesome T-shirts that will be sure to take you back to the golden age of hip-hop. Plus, we’ll raffle off an iPad mini. And if you have a big heart and bright mind, consider joining our team by checking out our career openings. Come talk to us and help us keep the dream alive at Portland DrupalCon!
Like the ’90s, Drupal really is alive in Portland, the city made popular again from the much-watched TV show, Portlandia. Portland is the homebase for the Drupal Association and host for this year’s DrupalCon, Drupal’s largest North American conference.
Drupal Commerce: Commerce Module Tuesday: Commerce Product URLs
Welcome to another Commerce Module Tuesday! Today we are looking at Commerce Product URLs, maintained by Maciej Zgadzaj who is a senior developer at Commerce Guys. This project almost doesn’t require a video. If you’re running Commerce 1.6 or later, just go download this, enable it, and love yourself for making the world a better place. Actually, enabling the module, by default, doesn’t do anything, but the magic is there. And that’s where the video takes the next step. It shows us how to hack the URL to link directly to specific products.
thedavidmeister.info: Track Drupal page load times easily with the Google Analytics module
If you're a Drupal developer who's worked on a project with any real complexity I'm sure you've experienced some (or maybe a lot) of slow pages due to some kind of performance bottleneck in your code. Drupal is flexible enough that there's usually quite a few options available to help speed up slow pages, from the "one click" caching solutions provided by core, to third party cache tools like Entity Cache, through to targeted profiling and code refactoring on the level of individual functions with a dedicated PHP tool like xhprof.
In this post I'm not going to discuss fixing performance issues; I just want to talk about an easy way to detect that you have a problem in the first place.
So many times when I've heard somebody complain about a slow site (or section within a site) I see them click around a bit, maybe the cache kicks in and then they say "oh, it's not so bad" or maybe part of the site is only slow in a particular browser or maybe mobile devices are hanging on that cool javascript animation you wrote or maybe your audience doesn't live in the same country as your server. Whatever the situation, the performance you should be interested in is not what you or your clients see on a development setup but the page load times the users of your production site are experiencing.
Did you know that Google Analytics tracks page load times out of the box?
Well... not quite. "Out of the box" Google Analytics only tracks the page load times of 1% of your total page impressions. From Google's own API documentation:
"If you have a relatively small number of daily visitors to your site, such as 100,000 or fewer, you might want to adjust the sampling to a larger rate."
If you're anything like me though, you'll probably want to start weeding out slow pages long before your traffic is averaging anywhere near 100,000 hits a day - unless you like thrashing your server and making your users wait. For a new site that 1% might translate to just a handful of data points that are unlikely to be related or help diagnose anything, really.
Since the sample rate is adjustable we can just continue to push it up until we get meaningful data - Google's daily cap is 10k so if you're getting fewer hits than that each day you can safely push the sample rate right to 100%.
Configuring the Google Analytics Site Speed sample rateUnfortunately the sample rate can't be set through the Google Analytics UI, we need to add the following line to the tracking script embedded in the site we want to track:
// Sets the Google Analytics Site Speed sampling rate to 100%. _gaq.push(['_setSiteSpeedSampleRage', 100]);If you haven't worked with the Google Analytics API directly before even a relatively simple snippet like this could be confusing out of context (you might be wondering what _gaq is, for example?)
Luckily the Drupal Google Analytics module has a convenient way to handle dropping in custom GA snippets like this one into the right place for you.
On the Google Analytics module's configuration page, inside the "Advanced settings" fieldset, open the "Custom JavaScript code" fieldset and paste the above snippet into the textfield labeled "CODE SNIPPET (BEFORE)". Save the form and you should be done!
Like most changes to Google Analytics, new data will start tracking immediately but won't become available in a useful format in the dashboard for about 24 hours.
To find the site speed statistics in the Google Analytics UI navigate to Content->Site Speed through the left hand side bar. If you haven't configured the sample rate as per the instructions above this section might look completely "broken", depending on your current traffic levels.
Now that you've tweaked your sample rate for your site, you might want to read up on how to interpret your awesome new data.
Syndicate: planet drupalWeb Wash: Using Mozilla Persona In Drupal 7
Mozilla Persona is a single sign on system that allows you to login into websites with a single registered email address. To register an email address head over to login.persona.org and sign up. Once signed up you can login to any website that offers Persona with your email address.
Short video explaining Mozilla Persona Beta 2.
The Mozilla Persona module for Drupal allows you to offer Persona as a login option for your users. You can configure the module to be the only sign in method or have it as a second option.
Unimity Solutions Drupal Blog: Image style token, itok & Drupal
Drupal 7.20 brought a security fix that prevents DDoS attack on servers.
Rootwork.org: A world-class frontend track at Drupalcon Portland
The big news at Drupalcon Portland is that, for the first time at a Drupalcon, we're having separate frontend and user experience (UX) tracks. That means we were able to offer even more sessions targeted directly at frontend developers, and as the local track chair for frontend, I'm really excited about what we've ended up with!
Groundbreaking frontend featured speakers[[wysiwyg_imageupload:4:]]First and foremost, of course, we have Jonathan Snook presenting on his concept (and book) Scalable and Modular Architecture for CSS.
[[wysiwyg_imageupload:6:]]SMACSS has had a big impact on a lot of frontend developers and themers — and in fact it's had a huge impact on Drupal itself. The Zen base theme, the most-downloaded Drupal theme out there, has adopted a SMACSS approach.
And Drupal itself is moving toward SMACSS with a re-organization of its CSS in the upcoming Drupal 8 release.
Join Jonathan Snook at Drupalcon Portland on Tuesday, May 21 at 4:30 PM.
Drupal 8 and TwigOh yeah, so there's this new version of Drupal coming out pretty soon.
Among the many, many awesome things happening with Drupal 8, one of the most relevant to frontend developers is the adoption (with a little luck) of the Twig templating engine.
Twig, a component of Symfony — a framework being adopted by Drupal 8 — will enable themers to write much cleaner (and safer!) code, and enable module developers to simplify the theming components of their modules.
No joke, at the BADCamp 2012 Twig session, there were literally gasps in the audience as we all saw how cool it was. If you're a themer or a frontend developer, don't miss this!
And so much more!I've just touched on two of the featured sessions at Drupalcon Portland. In the coming week I'll be posting more about some of the other sessions, but you can browse the frontend sessions right now and start planning to attend your favorites! (Don't forget the User Experience sessions too.)
And if you don't yet have your ticket to Drupalcon Portland, there's still time! Grab your ticket by this Friday and save $50 off the on-site ticket price.
I can't wait to see everyone here in Portland!
Join Rootwork on Twitter, Facebook and SlideShare.
Learn about Rootwork's services for nonprofits and social change.
Drupal core announcements: Drupal core security release window on Wednesday, May 15
The monthly security release window for Drupal 6 and Drupal 7 core will take place on Wednesday, May 15.
This does not mean that a Drupal core security release will necessarily take place on that date for either the Drupal 6 or Drupal 7 branches, only that you should prepare to look out for one (and be ready to update your Drupal sites in the event that the Drupal security team decides to make a release).
There will be no bug fix release on this date; the next window for a Drupal core bug fix release is Wednesday, June 5.
For more information on Drupal core release windows, see the documentation on release timing and security releases, and the discussion that led to this policy being implemented.
Isovera Ideas & Insights: Allow Advanced (Lucene) Solr Syntax using Search API Views
By default, the Search API Views sub-module does not allow you to specify the "direct parse" mode when configuring an exposed Fulltext filter. Instead, it always uses the "terms" parser which removes special characters and breaks the phrase into terms based on spaces.
This behavior prevents users from really leveraging the simple but robust Lucene query syntax that Apache Solr's default Dismax parser supports:
Mediacurrent: Georgia High School Association Goes Mobile with Drupal 7 Upgrade
Drupal sites have a life cycle. Module support shifts from one version of Drupal to the next. New solutions are identified, and old solutions are refined.
For GHSA.net, updating to D7 meant improving mobile support and implementing a cleaner, more regular presentation, and simplifying content management workflows.
This is a discussion of techniques used throughout the project, challenges, and lessons learned.
Microserve: Drupal is Rubbish (Apparently!)
I was recently in a meeting with a design agency who had to use Drupal for one of their websites and they hadn’t heard good things about it. The points they raised were common ones so I thought I would cover them here. This blog post isn’t a bash against Drupal, we are clearly huge Drupal fans! It aims to cover some of the issues people raise when they say that ‘Drupal is Rubbish’.
Drupal sites are a huge complicated mess!One of the most common problems that people run into with Drupal is they underestimate its complexity and the knowledge you need to develop a sophisticated site with it. Sometimes people decide they want to use Drupal for all the right reasons, then they go to a web developer and ask them to build the site in Drupal. The web developer looks at Drupal and thinks ‘well, how hard can it be?’ and gets to work. It is a bit like going to your GP and asking them to perform surgery. In this example your GP would say no and refer you to a surgeon, but most developers have an overly optimistic attitude and sometimes it’s just hard to say no to the offer of work. Disaster follows, and often Drupal gets the blame rather than the web developer. Drupal is a fully fledged CMS, built and designed to compete with some of the biggest commercial platforms out there and it requires specialist knowledge to build a well-designed, stable website.
Drupal has to be complex in order to deliver the advanced functionality you need from a high level CMS platform and you’ll hear the phrase ‘steep learning curve’ regularly. This is one of the reasons that as an agency we only work with Drupal as we find that you need to be a specialist to get the best out of Drupal. Even if you are a senior developer with 5 years Drupal experience, you’ll still be learning something new every day. If a developer says they can build sites in WordPress, Joomla! MODX and Drupal, it doesn’t mean they can take on a complicated Drupal build and we would suggest avoiding developers with non-specialist experience for complicated builds.
The admin section is too complicated for our usersTo a certain degree, the administration section can appear exceptionally complicated. This is also mainly due to it's extreme flexibility, in Drupal, the admin section will allow the user the ability to do more than a usual CMS administration menu. Luckily, it's very easy to set up different user levels to show less complicated administration screens to some users. Full access to the admin section is suited to users who like to be at super-user level access or to those who have been trained on how to use it. Drupal management and content administration training is something that we can offer and will allow us to take users from basic screens into more complicated task management.
Before starting a project, doing a quick check to see whether your users are going to need the scalability and flexibility of a large Drupal solution is a good idea, it may be that your solution doesn't need that level of flexibility and a simpler platform like Wordpress may be a better option.
Drupal is slowThis is possibly the most difficult claim to refute because quite frequently, if you haven’t set up Drupal properly, then yes, it can be slow. It is usually quickly remedied though, and there are a number of posts on the Drupal.org site which can provide you with more information on how to do this. Alternatively you can check out our high availailitity posts by our very own Mark Pavlitski - High performance in Drupal Part 1: Give your site a boost and High performance in Drupal Part 2: Lightning fast code. This comes back to the flexibility of Drupal and corresponding complexity, if your developers are not Drupal specialists, then ensuring that basic speed processes such as caching, memory optimisation and well written SQL could be missed.
We feel that given that some of the world’s biggest sites are written and run in Drupal (www.whitehouse.gov, www.louvre.fr, mtv.co.uk), we’re not too worried about the speed allegations.
Module dead endsOne of the reasons for Drupal’s success are the 24,000 or so developers that contribute code to the community, who produce a wide range of modules that every Drupal user can benefit from. Whenever something new appears, i.e. Twitter, Pinterest, an enterprising Drupal developer will bring out a module for it. Usually this happens well before the commercial CMS companies with their limited development teams and fixed development roadmaps can respond.
Sometimes, that enterprising developer who spent time writing a module, decides that continuing to support the module or upgrading it to work with the latest Drupal release is not something he or she wants to do any more. Hence module dead ends.
There are a few options for you out there if this happens: replacing it with a different module can often be quick and easy, taking over the maintenance of the module can be easily done and you can then assume control of that module. Evaluating whether a module is going to be developed long term can be an art form for Drupal developers so keep an eye out for an article coming soon on this site about the Top 5 factors to look for when choosing a module.
SummaryDrupal is a very flexible system and can be limitless in its opportunities and potential but this has to come with a level of complexity, a level that can make it unsuitable for developers without the required experience. The possibilities for doing exciting things like module customisations to fine tune Drupal to work perfectly for your site are endless, we just suggest that you employ developers with the best experience possible for your needs.
LevelTen Interactive: Icons and Drupal: These are the Years of our Lives
The title alone says it all. If you're reading this post, it probably is because you desire an easier way to insert a simple icon into your Drupal site. Many times this involves adding an icon library into your theme and doing some pretty undesirable pre-processing or template overrides to insert them where you want.
What are icons?They're images right? Well, technically yes. Icons are a visual representation of some intended object or action - a pictogram essentially (think of a stop sign). What I'm really asking though is:... Read more
Drupal core announcements: Getting the Twig initiative done
Per Dries's post about Drupal 8 release risk, this post outlines a plan jointly developed by the Drupal core maintainers (Dries, webchick, catch, and alexpott) for getting Twig into core safely. See that post for more background information.
What's up with Twig?The Twig template engine was originally committed to Drupal 8 live on stage at BADCamp in November 2012, to wild fanfare. Since then, the team has been working on converting all templates and theme functions in Drupal core to use Twig. Thanks to valiant effort by numerous contributors, the PHPTemplate conversions currently stand at ~30% RTBC, and another ~45% at needs review. This is great progress!
Why aren’t the core committers committing?The short answer is release risk. We are in the “clean up” phase of the Drupal 8 release cycle (http://drupal.org/core/release-cycle#clean-up-phase). Each commit we make should take us one step closer to a Drupal release. In effect, committing an individual Twig patch to core takes us one step further into uncharted territory. At the moment all of our templates are PHPTemplate and hence each conversion commit moves us further away from a release. We obviously can't ship with two theme systems, so unless 100% of templates are converted, we leave Drupal 8 in an unreleasable state.
SolutionWe plan to merge all the PHPTemplate to Twig conversions into one patch. Once complete, we will commit this patch into the mainline 8.x branch. The patch will convert all the .tpl.php files to .twig and remove the functionality that allows Drupal 8 to run both theme engines at the same time. This means that Twig commits will not take the 8.x branch further away from a release, and it gives us an exit strategy if they are not complete by code freeze.
A meta issue has been created to track the merged patch.
The Twig team will:
- Finish converting all the templates.
- Provide benchmarking evidence on each issue that the conversion conforms to the acceptance criteria. If other patches are required to be applied in order to meet this requirements then these should added to both the conversion issue and the meta issue.
Core committers will:
- Review each individual patch and
- Comment: "+1. Ready for [#1987510]"
- Status: "closed (duplicate)"
- Title: prepend '[READY] '
- Commit the merged patch once all templates have been converted and acceptance criteria have been met.
- If a Twig patch is isolated to the current Twig code in 8.x then the core committers will commit it immediately. For example: Allow and test for NULL and integer 0 values in Twig templates
The following are necessary in order to perform the final merge of conversions into 8.x:
- 100% Twig conversions are completed
- 8.x-twig performance is comparable with 8.x PHPTemplate performance, bearing in mind the issues with D8 performance testing - see https://drupal.org/node/1888424#comment-7345926
- there are no critical Twig follow ups
Once the patch is committed further Twig work should continue on 8.x to:
- Convert theme functions to Twig
- Gain the security benefits on Twig
- Further performance enhancements made possible by moving to Twig
Important: It is in everyone’s interest that the conversions are finished as soon as possible. In an ideal world, the merge will take place during Drupalcon Portland.
Rollback criteriaIf by 17th June the acceptance criteria are not met, then (with regret) an issue will be created to remove Twig from Drupal 8.x. This gives enough to time to create and test the rollback patch before code freeze on 1st July.
Help wanted!The Twig team has been doing a tremendous job, and we know the front-end community is very excited about this initiative. The time is definitely here to jump in and help the team push this initiaitve past the finish line! Particularly needed are patch reviews (see http://www.youtube.com/watch?v=Bv4PY_ZEP4Q for a helpful screencast on how to do so!), since most issues have patches but can't be RTBCed by people who worked on them.
So grab an issue to review and/or drop by #drupal-twig on IRC if you'd like to help. It's a great way to learn about Drupal 8, meet awesome people, and vastly improve Drupal for front-end developers at once!
Web Omelette: How to use the Drupal Form API #prefix and #suffix to arrange your fields
In this tutorial I am going to show you a way you can leverage the power of the Drupal Form API to display form fields in the layout you want. To illustrate this, I will alter a form (the comment form) and arrange the Name and Subject fields in two columns.
Padraig O'Sullivan: Local Development with Ariadne
I recently started a new development position with Blink Reaction so I needed to get somewhat serious about setting up a local Drupal development environment.
AriadneI was leaning towards making use of Vagrant for managing local development environments so I can easily switch between different projects or branches. I also believe Vagrant makes it easier to have as close a mirror to production locally as possible.
I discovered a very interesting project from MyPlanet Digital named vagrant-ariadne. Ariadne is a customized implementation of Vagrant and allows for easy deployment of Drupal installation profiles to a local VM. Another nice feature is that it attempts to emulate Acquia’s infrastructure. This is useful as a lot of Blink’s clients are deployed on the Acquia Cloud.
Assuming you have Vagrant, rvm and a ruby environment installed on your workstation, installing Ariadne is pretty straightforward:
j vagrant gem install vagrant-vbguest vagrant-hostmaster vagrant-librarian [sudo] gem install librarian rake knife-solo git clone https://github.com/myplanetdigital/vagrant-ariadne.git cd vagrant-ariadne bundle install bundle exec rake setupEverything is now configured to boot a virtual box. Ariadne comes with a simple example that can be deployed:
j project=example vagrant upOnce that command finishes running, the site can be viewed at http://example.dev/ (Ariadne uses vagrant-hostmaster for managing /etc/hosts entries).
A more involved cookbook is a cookbook for deploying the Web Experience Toolkit available on github also. If we wanted to deploy the master branch of this site, we could do:
bundle exec rake "init_project[https://github.com/wet-boew/ariadne-wet-boew-drupal]" project=wet-boew-drupal branch=master vagrant up
And that’s it!
Another nice feature of these deployed environments is that they are configured to allow remote debugging (relevant when setting up an IDE as mentioned later) and the actual site code is shared as an NFS mount. For example, the contents of my /etc/exports file after booting a box with Ariadne looks like:
# VAGRANT-BEGIN: 7ac1cf50-4498-4e49-bd66-edac4a9b2d7e "/Users/posullivan/vagrant-ariadne/tmp/apt/cache" 33.33.33.10 -mapall=501:20 "/Users/posullivan/vagrant-ariadne/tmp/drush/cache" 33.33.33.10 -mapall=501:20 "/Users/posullivan/vagrant-ariadne/data/html" 33.33.33.10 -mapall=501:20 # VAGRANT-END: 7ac1cf50-4498-4e49-bd66-edac4a9b2d7eThus, if I navigate to the ~/vagrant-ariadne/data/html directory or import that in my IDE, I can edit the code deployed on the vagrant box.
Drupal Core from gitAnother use I’ve found for ariadne is building a local environment for the latest drupal core. To accomplish this, I created a role file named roles/core.rb with the following contents:
name "core" description "Install requirements to run Drupal core." run_list([ "recipe[mysql::server]", "recipe[mysql::client]", "recipe[php::module_mysql]", "recipe[php::module_curl]", "recipe[php::module_gd]", "recipe[php::module_apc]", "recipe[drush::utils]", "recipe[drush::make]", "recipe[php::write_inis]", ]) default_attributes({ :drush => { :version => "5.8.0", }, :mysql => { :server_debian_password => "root", :server_root_password => "root", :server_repl_password => "root", :bind_address => "127.0.0.1", :tunable => { :key_buffer => "384M", :table_cache => "4096", }, }, })j
Next, I created a new cookbook project named core and created a simple default.rb recipe for this cookbook. This recipe looks like:
branch = node['ariadne']['branch'] git "/mnt/www/html/drupal" do user "vagrant" repository "http://git.drupal.org/project/drupal.git" reference branch enable_submodules true action :sync notifies :run, "bash[Installing Drupal...]", :immediately end bash "Installing Drupal..." do user "vagrant" group "vagrant" code <<-EOH drush -y si \ --root=/mnt/www/html/drupal \ --db-url=mysqli://root:root@localhost/drupal \ --site-name="Drupal Core Installed from Git" \ --site-mail=vagrant+site@localhost \ --account-mail=vagrant+admin@locahost \ --account-name=admin \ --account-pass=admin EOH end site = node['ariadne']['host_name'].nil? ? "#{node['ariadne']['project']}.dev" : node['ariadne']['host_name'] web_app site do cookbook "ariadne" template "drupal-site.conf.erb" port node['apache']['listen_ports'].to_a[0] server_name site server_aliases [ "www.#{site}" ] docroot "/mnt/www/html/drupal" notifies :reload, "service[apache2]" endWith all of the above in place, its quite simple to create a local VM based on the latest in the 7.x branch of drupal core:
project=core branch=7.x vagrant upThe above command simply needs to have the branch name modified to deploy a different branch. Once the above command completes, a site will be available at core.dev and I can log in as the admin user using the credentials specified in my cookbook.
Private RepositoriesMost repositories for client projects are stored in private repositories. Thankfully, thats not an issue with ariadne. Ariadne uses agent forwarding to forward the host machine’s ssh session into the VM, including keys and passphrases stored by ssh-agent. What this means is that your VM will have the same Git/SSH access that you enjoy on your local machine. I’ve not had a problem checking out code stored in private repositories on bitbucket for example.
IDEFor an IDE, I’ve been an Eclipse user in the past for Java projects I’ve worked on so Aptana seemed like a good fit for my needs at the moment. A few existing articles already exist on configuring Aptana for Drupal development so I’m not going to go into too much details here.
Installation is very straightforward with the binary downloaded from the site. A ruble exists for Drupal so its pretty natural to install that:
git clone git://github.com/arcaneadam/Drupal-Bundle-for-Aptana.git ~/Documents/Aptana Rubles/Drupal-Bundle-for-AptanaNext item is to configure Aptana to adhere to the Drupal coding standards. I used an existing profile for Aptana that could be imported for this.
The final thing I needed to configure was a debug configuration. To do this, I created a new PHP web page configuration. First, a new PHP server needs to be added. In this example, lets assume I am using the example box I mentioned in the Ariadne section whose hostname is example.dev. The web server configuration dialog when configured with this hostname and appropriate directory for the site root looks like:
Once a PHP server has been added, the rest of the information to fill in for the debug configuration is pretty straightforward as shown below:
I like to select the break at first line option to make sure the debug configuration works correctly.
With this in place, any visit to example.dev will result in the breakpoint being hit.
ConclusionI’ve still not settled on this combination for my development environment but I was definitely pretty excited upon discovering the Ariadne project. The drawbacks that I see to using Ariadne are: 1) the need to create a cookbook for each project you want to work with, 2) the project is still in beta stage so documentation is fairly lacking (fair enough for a beta project though), and 3) if you are not familiar with chef, using Ariadne may prove challenging (although it provides the perfect excuse to become familiar with chef).
PHPStorm is the IDE that seems to be pretty popular when I ask what other people are using for an editor but given there is a license fee associated with it, I didn’t want to splurge on that just yet. Aptana looks to work just fine for me and satisfies my needs nicely.