Planet Drupal

Creating a Custom Progress Throbber for Drupal

Posted by Chromatic on October 15, 2013 at 6:33pm

Every Drupal site contains the spinning circle of progress – the “throbber”. Click on anything requiring Ajax and you’ll often be greeted by the standard blue Drupal throbber while waiting for results. There have been many times that I didn’t even realize I was using a site built with Drupal until it made an appearance.

Run away!

Seeing the default throbber on an otherwise beautiful site takes away from the magic a bit, doesn’t it? While you’re surely proud your site is built with Drupal, don’t you want to give your visitors a completely unique experience? You’ve worked so hard perfecting every other pixel, why settle now? Go the extra step and create a custom throbber to keep your visitors immersed in the world you’ve created for them. It’s too easy not to!

All you need is:

  • an hour or two
  • Photoshop or a similar gif editor
  • access to your theme’s file system and CSS
  • a bit of patience

Here we go!

Creating your own animated progress throbber graphic

The CHROMATIC mark

First, you’ll want to decide on what your graphic will be. If you have a circular logo or icon that works well at very small sizes, that’s perfect. You can get creative here, but it should continue to convey the same idea of progress while spinning for your visitors. It should also remain visually appealing at very small sizes. For ours, we’re going to use the hexagonal C mark from our logo.

How these throbbers work

Next, you’ll want to gain an understanding of how the default throbber works. The throbber is an animated gif graphic that is strategically positioned with CSS while other elements are loading. If you’ve never looked for it before, locate the root of your Drupal installation and find /misc/throbber.gif (here’s ours).

Open the throbber.gif at /misc/throbber.gif in Photoshop. Notice how there are twelve layers and only one is visible. In the Photoshop menu, navigate to “Window > Timeline”. This window is the magic behind how the gif works and will become your best friend.

The Photoshop Timeline window

In the Timeline window, you’ll see twelve frames, each one corresponding to one of the layers. Click on each frame and you’ll notice a different layer is visible for each. Finally, underneath each sequence you’ll see ‘0.06’. That’s how long (in seconds) that frame will last before moving to the next. They don’t all have to be the same, but it makes sense for them to be in this situation.

Setting up your Photoshop template

The Photoshop Canvas Size window

Now it’s time to have fun. Save a copy of throbber.gif somewhere else and open it in Photoshop to start digging in. The first thing I’d recommend doing is making your image canvas much larger than it already is. In the Photoshop menu, navigate to “Image > Canvas Size…”. I’d typically set mine to 120 pixels for the width and 320 pixels for the height (the original dimensions multiplied by 8). Having more pixels to work with will allow you to tweak the positioning and size of your graphic with much more control. We’ll shrink it down to the right size when we’re done and want to save it.

Magnifying the default Drupal throbber

You’ve increased your canvas size, but the Drupal throbber remained tiny. Make sure you’re on the active layer and frame and navigate to “Edit > Free Transform…” in the Photoshop menu (or use CMD/CTRL + T). Now, near the top of the window, set the new height and width to be 800% of the original dimensions. Hit enter and it should now take up most of the frame again. It will be really blurry, but that’s ok. We’re only using it as a template for placement and won’t be exporting it. Repeat this for every layer/frame. An important thing to remember is that every time you switch to a different layer, you’ll want to switch to the matching Timeline frame, too. This can be tedious and confusing, so here is a Photoshop CC file with a magnified template already created.

Getting your graphic in the Photoshop template

The next step is to get your graphic into the Photoshop template we’ve created. Whether it be copying and pasting from elsewhere, or by using “File > Place”, import your graphic in as a new layer. Using the Timeline window, make sure this new layer is only visible in the first frame (click between frames and toggle layer visibility). Move it around and resize it until it’s perfectly on top of the blue Drupal throbber on the bottom.

Rotating the custom graphic while creating the throbber

Now duplicate the layer with your graphic and use the Timeline window to make the new layer only visible in the second animation frame. Now we rotate it. Just like the Drupal graphic, each frame will be an additional 30 degrees of rotation from the frame before it. So in the second layer/frame, rotate the original graphic 30 degrees using the Transform tool. While using the tool, hold shift and grab the top right arrow with your cursor to rotate it. As you rotate, it will tell you how far you’ve gone and will snap to helpful increments.

Repeat this step until you’ve got twelve layers visible in the right frames and filled with your graphic progressively rotated. If you’ve done it right, the twelfth will be 30 degrees away from matching the first. Make sure to go through each frame one more time and make sure only the correct frames are visible. For an example, here is our Photoshop CC file after adding and rotating our custom graphic.

Adding the greyscale graphic to the top of the template

That takes care of the colored spinner, but we need to replace the grey one, too. Duplicate the first frame with an upright graphic. Make the original Drupal throbber visible again (any layer/frame works) and move your newest graphic on top of the grey circle atop the original throbber graphic. Again, the size and position should be as close as possible to the original. Now create a greyscale version of it by using “Layer > New Adjustment Layer > Hue/Saturation…”. In the menu that pops up, desaturate it all you’d like. Making the original layer semi transparent will help, too. Tweak the values until you’re happy with the darkness. Unlike the colored graphic, this one layer should be visible on every Timeline frame and should never be rotated.

Desaturating the custom graphic

If you’re still with me, we’re just about there! Your colored graphic that will spin should be in the correct place on all 12 layers/frames and the greyscale version is in all of them as well. Go ahead and delete the layers with the original Drupal throbber. All that should be left are the graphics you’ve added. Here’s our Photoshop CC file with a finished throbber.

It’s alive!

If you click the play button in the Timeline window, you should see your graphic spinning. You may need to pay attention to particular frames that need adjusting if the spinning graphic feels off balance in any way. Other adjustments, such as adding more space between the grey and colored graphics, may also be necessary later.

The Photoshop export dimensions

Finally, let’s save it for use. Using “File > Save for Web…”, select “GIF” for the type. Make sure “transparency” is checked and, most importantly, adjust the size. Give it a width of 15 pixels and a height of 40 pixels. This matches the original throbber’s size. Click ‘Save’ and save it to somewhere you’ll remember. Open it and make sure it spins and looks great.

The CHROMATIC throbber

You’ll notice ours (to the right) looks a lot like the default graphic, but that is because of the nature of our mark. Yours should look completely different!

Adding the graphic to your theme

Only a few small steps left and they are the easiest.

Move your new throbber.gif into your theme’s file structure. Something like /sites/all/themes/yourtheme/images/throbber.gif.

Next, somewhere in your theme’s CSS, add these lines:

/* Overrides /modules/system/system.base.css with a custom throbber. */
html.js input.form-autocomplete {
  background-image: url(/sites/all/themes/yourtheme/images/throbber.gif);
}
.ajax-progress .throbber {
  background: transparent url(/sites/all/themes/yourtheme/images/throbber.gif) no-repeat 0px -18px;
}

It’s important to change the image path to the location and name of your new throbber. These lines will override the uses of the default throbber within Drupal’s System CSS to use your throbber instead. You may want to look in whatever contrib modules you are using to see if they have styles for throbber.gif that you need to override, too. We’ve had to do this for the flag module in the past.

You’re done!

Save your CSS (or Sass, LESS, whatever) and clear cache. Click around somewhere that uses a throbber (Ajax, autocomplete, etc.) and see the magic in action. If the positioning is a bit off, try tweaking the background-position in the styles you’ve just pasted in as overrides.

That’s it! Show it off to the world! You’ve got a custom progress throbber!

Did this help you create one? Leave a comment with a link! Have a question? Ask away!

Drupal Association Board Meeting Tomorrow

Posted by Drupal Association News on October 15, 2013 at 4:40pm

I know what you're thinking. Hey - wait a minute! We just had one of those board meetings! It's true, our last board meeting was just a few weeks ago in Prague. It was exciting too! we got an update from the Software Working Group and we confirmed our At-Large community-elected board members.

Google Code-In and Drupal

Posted by Janez Urevc on October 15, 2013 at 4:17pm

Google anounced that they are running their Code-In programme also this year. Google Code-in is a contest for pre-university students (e.g., high school and secondary school students ages 13-17) with the goal of encouraging young people to participate in open source.

Drupal partecipated Code-In in the past and we're also applying this year. We need help of the community at this point! If we want our application to be complete we need at least 25 good task proposals until October 18th. We're going to need additional 100-200 tasks if we're accepted. 

Do you have an idea for a task? Add it to the official wiki today! 

You can get more information in this g.d.o. annoncement.

Menu Tricks #4: Menu Block with Bootstrap Dropdowns

Posted by Stanford Web Services Blog on October 15, 2013 at 4:05pm

Earlier this year, I wrote a blog post about using Menu Block module. In this post, I'll talk about how Menu Block integrates with Stanford's Drupal 7 themes to create dropdown menus.

To properly leverage the dropdowns in Twitter Bootstrap with Drupal, there are a few things to keep in mind...

Note: This post pertains to these Drupal 7 themes:

Drupal 7 vs Symfony 2: overview after 1 year of Symfony development

Posted by Pixeljets on October 15, 2013 at 3:55pm

We’ve decided to switch to Symfony 2 development in July 2012, if I’m not mistaken - after 7 years of (mostly) Drupal development.
There were reasons to do that:

1. Not-too-great experience with high load projects, powered by Drupal 7

Okay, Drupal is good enough until you get a project with big expectations in terms of response time for authenticated users. Boost and memcached help a lot with anonymous page hits, but things are sometimes not good enough when we talk about authenticated user saving some nodes (1 field = 2 inserts to fields and revisions table, 40 fields - and you get super-slow node saving, at least on non-ssd hosting), using ajax stuff like dynamic forms (Drupal form ajax is not bad, it’s just not super-blazing-fast).

read more

Drupal 8 won't kill your kittens: part 3 of 4 - Why the fear?

Posted by Acquia on October 15, 2013 at 3:04pm

Part 3 of 4 – On October 4/5, 2013 (depending on your time zone), I hosted a live Hangout on Air with three major Drupal core contributors: Lee Rowlands (larowlan), Tim Plunket (tim.plunkett / @timplunkett), and Daniel Wehner (dawehner / @da_wehner). We talked about what's going on in Drupal 8 and how you will benefit from all the new stuff. This post is the third of four that cover the details of that conversation.

Drupal Public Sector Exchange (DPSX) – BoF at DrupalCon Prague

Posted by Ikonami on October 15, 2013 at 10:04am

DPSE logo 1 2013 300x159 Drupal Public Sector Exchange (DPSX) – BoF at DrupalCon PragueThough DPSX has been a tad bit quite since July we did kick up a mini-storm in Prague at DrupalCon last month! The BoF was a hit with relevant attendees from Belgium, Britain, Finland, France, Netherlands and Slovakia represented on the table. in majority the attendees other than Steve Purkiss and myself were from the public sector which was a result!

 

The discussions centred around:

  • The political challenges of having a single platform in government
  • options of multisite Vs Domain access and of course creating distributions
  • Managing diversity in government
  • Selling by building business cases
  • When Open becomes closed and proprietary


class="slideshow_container slideshow_container_0"
style="
height: 400px; "
>


    DrupalCon Prague 201324 11.11.39 Drupal Public Sector Exchange (DPSX) – BoF at DrupalCon Prague
    DrupalCon_Prague_201324 11.11.39


    DrupalCon Prague 201324 11.11.42 Drupal Public Sector Exchange (DPSX) – BoF at DrupalCon Prague
    DrupalCon_Prague_201324 11.11.42


    DrupalCon Prague 201324 11.11.50 Drupal Public Sector Exchange (DPSX) – BoF at DrupalCon Prague
    DrupalCon_Prague_201324 11.11.50


    DrupalCon Prague 201324 11.33.09 Drupal Public Sector Exchange (DPSX) – BoF at DrupalCon Prague
    DrupalCon_Prague_201324 11.33.09


    DrupalCon Prague 201324 11.42.16 Drupal Public Sector Exchange (DPSX) – BoF at DrupalCon Prague
    DrupalCon_Prague_201324 11.42.16

    Wordpress Slideshow */

    The audio from the BoF can be downloaded from here.

    Looking ahead we are planning on one more DPSX meet up in Blighty prior to Christmas, so if you are interested please drop us a line or comment on D.O.

    One last update – folks the DPSX blog posts will be moving to my personal blog from the next meet up – you can keep following DPSX on www.kubairshirazee.com

    How to Add Autocomplete Functionality to Text Filters in Views

    Posted by Web Wash on October 15, 2013 at 6:26am

    Views Autocomplete Filters is a simple yet powerful module that allows you to add autocomplete functionality on any text filter on a Views page.

    The autocomplete functionality will only work for basic text fields (Content: Title), and Field API text fields. Also, for the filter to work, the field must be displayed on the view.

    For example, if you want to add an autocomplete filter to a view that allows users to filter content by title, then the title field needs to be added as a filter criteria as well as a field.

    In this tutorial, I'll show you how to use the module on a basic views page. We'll create a view that lists all content in a table and we'll use the module to create an autocomplete filter that allows users to filter content by title.

    Truly Flexible Commerce: Deliver a Richer Customer Experience with Drupal Commerce

    Posted by Blink Reaction on October 15, 2013 at 4:04am

    Drupal Commerce is a truly flexible framework built on Drupal, the world-renowned open-source CMS, that delivers a seamless experience for customers. In this webinar, Ray Saltini from Blink Reaction and Ryan Szrama & Scott Dahlgren from Commerce Guys will show you how to integrate commerce into your CMS and flatten your business processes. Watch the webinar.

    Drupal core security release window on Wednesday, October 16

    Posted by Drupal core announcements on October 14, 2013 at 10:56pm
    Start:  2013-10-16 (All day) America/New_York Sprint Organizers:  David_Rothstein

    The monthly security release window for Drupal 6 and Drupal 7 core will take place on Wednesday, October 16.

    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, November 6.

    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.

    SANDCamp

    Posted by groups.drupal.org frontpage posts on October 14, 2013 at 10:32pm
    Start:  2014-01-23 (All day) - 2014-01-25 (All day) America/Los_Angeles Drupalcamp or Regional Summit Organizers:  Susan Rust Event url: 

    http://sandcamp.org

    Drupal at the beach!

    This year's event will be held in sunny San Diego at the Marina Village Conference Center -- just steps from beaches, Sea World, and the Mission Beach Boardwalk.

    Thursday is a full day of training.
    Friday and Saturday are two full camp days.
    Sunday is fun-day with disc golf, beach activities, and sight-seeing

    Bring friends and family to make the most of your San Diego experience. This event is organized by the people, for the people and with the help of some friendly sponsors. Some of your favorite, dedicated, Drupal developers will be joining us this year, so don't miss out!

    One-liner for fetching the live-database on your dev server (or localhost)

    Posted by orkjerns blogg on October 14, 2013 at 7:40pm

    So when I first realised that I was neglecting this blog, I somewhat found comfort in that at least it hadn't been a year, right? OK, so now it has almost been a year. Does that mean I have stopped finding solutions to my Drupal problems (as the "About me" block states)? Well, no. The biggest problem is remembering to blog about them, or finding the time. But finding the time is not a Drupal problem, and I most definitely have not found the solution to that problem. Anyway, I digress. Let's end the streak with a quick tip that I use all the time: Syncing live databases without having drush aliases.

    If you use drush-aliases, you could just do drush sql-sync. But for me, even if I do, I still prefer this method, as I find it extremely easy to debug.

    First I make sure I am in my Drupal root:

    $ cd /path/to/drupal

    Then I usually make sure I can bootstrap Drupal from drush:

    $ drush st

    If that output says my database is connected, then let's test the remote connection:

    $ ssh [email protected] "drush --root=/path/in/remote/server st"

    If that output also says we are connected, it means we are good to go, with my favourite command ever:

    $ ssh [email protected] "drush --root=/path/in/remote/server sql-dump" | drush sql-cli

    If you have a drush-alias for the site, you can also go:

    drush @live-site-alias | drush sql-cli

    Tags: developmentdrushmysqldatabase dumpworkflowplanet drupal

    Getting Started with Drupal Commerce

    Posted by Michael J. Ross on October 14, 2013 at 6:40pm

    By

    This book review was published by Slashdot, 2013-10-14.

    An online store is one of the most common use cases for a website nowadays. For those web developers and business owners who choose the current version of Drupal as a basis for such an e-commerce project, the canonical solution is Drupal Commerce. There are numerous online resources for learning Commerce, and yet for the longest time no printed book. Now we have Getting Started with Drupal Commerce, written by Richard Jones.

    This title was released by Packt Publishing on 24 September 2013, under the ISBN 978-1783280230. (This review is based upon a copy of the book kindly provided by the publisher.) On the book's website, visitors can read information about the book, including its table of contents, errata (none listed, as of this writing), and a sample chapter (the third one, on "Planning Your Store").

    At first glance, 152 pages may seem wholly inadequate for explaining how to build an online store using Drupal Commerce. However, the table of contents suggests that, within the book's 10 chapters, the author addresses most of the critical topics: installation of the Commerce project, product catalog and classification, product data, shopping cart functionality, the checkout process, shipping services, taxes, order management, discounts, and coupons. A bonus chapter, "Extending Commerce", is not included in the book itself, but is available as a free download. (Readers should note that the URL provided in the book is incorrect, as it is missing the last underscore.)

    Prospective readers do not need to know how to program in PHP or Drupal; however, a working knowledge of Drupal site building through the user interface, would be helpful. Anyone who wishes to follow the steps performed in the book for creating the example Commerce site, must have access to a Drupal 7 installation, with sufficient privileges to install and configure modules and set permissions, as needed.

    The first chapter, "Introducing Key Concepts", as the title suggests, introduces the reader to the Drupal Commerce package, its overall capabilities, its submodules, and its dependencies. The module list (on page 6) is missing nine entries. Other than that, the material provides a good sense of what is to come. The first chapter, like all the others in the book, concludes with a brief and utterly useless summary. In this case, it states that the readers now "understand the motivation of the developers", even though that was not discussed in the chapter.

    Installing Drupal Commerce is the subject of the next chapter. MySQL is listed as a requisite download, but actually MariaDB, PostgreSQL, and SQLite are equally usable. The author mentions Mac OS X and Windows as possible environments, but neglects Linux. Most of the chapter assumes that the reader has elected to use the Acquia Dev Desktop, and it consequently may prove frustrating to anyone who uses a different distribution to get started, or who installs the needed components individually.

    As an e-commerce website is developed and (usually) later modified, the participants discover the value in all of the time and effort invested upfront in planning the information needed to track products, customers, payments, and other facets of the operation. Thus the third chapter is arguably one of the most valuable in the book, and should prompt site designers and developers to ask plenty of questions of their clients.

    With Chapter 4, "Products", the author begins describing and illustrating the creation of the example website — in this case, a wholesale coffee and tea store based in the UK. At a critical juncture (page 35), the reader is instructed to enable "Commerce Backoffice (Commerce package)" and "Commerce Backoffice (Product package)", which is odd, since all four Commerce Backoffice submodules are in the "Commerce (contrib)" package, and none have those two exact names. Readers may presume that Commerce Backoffice and Commerce Backoffice Product were intended. It later turns out that "Commerce Backoffice content" was also needed. It is possible that the author was using an earlier version of Commerce that had different names, but that's difficult to ascertain because he apparently does not mention which version of Commerce is used in the book.

    Chapters 5 and 6 demonstrate how to set up a shopping cart and configure the checkout process. The material should be comprehensible to the typical reader, and possibly a pleasant relief if his head is still spinning from the terminology soup encountered in the fourth chapter. The author explains how to use PayPal for accepting customer payments, and what permissions to set so that visitors to one's store can check out. Strangely enough, there is no discussion as to what permissions, if any, visitors will need for viewing products and adding them to the shopping cart. This might seem obvious to those experienced with Drupal Commerce, but likely will not be to neophytes.

    The next two chapters show how to set up flat rate shipping as an option for one's customers, and how to apply a value added tax to each order, including the use of the Rules module for handling special cases flexibly, such as offering free or discounted shipping when the checkout balance exceeds a certain amount on any order not being shipped internationally. Lastly, readers learn how to set up order tracking.

    The last three chapters demonstrate how to apply various tax rates to customer orders, how to manage orders on the back-end (such as setting status codes and viewing payment transactions), and how to define discounts and coupons that can be offered to prospective customers. The 11th chapter, on extending Drupal Commerce, should have been included in the published volume itself, as it certainly would not have pushed the page count beyond a reasonable level.

    Throughout the book, almost all of the explanations are clear and straightforward, with the only exceptions being the puzzling reference to a "uid property" (page 10), which is not explained, and the use of several different phrases to describe product display nodes (in the fourth chapter). Unfortunately, all of the material apparently assumes that the reader will encounter no problems in trying to perform the same steps, because no troubleshooting resources are mentioned.

    Aside from the aforementioned faulty URL on page 2, this book contains too many errata relative to its size: "out of the box" (page 5; missing three hyphens), "Apache based" (page 13; same problem), a space in the URL (page 15), "than [a] necessity" (16), "to [the] recently" (17), "Specifying [the] language" (25), "to [the] public" (27), "other than helper modules" (35), "Images/" (39; should be lowercase), "fairtrade" and "fair trade" (46 etc.; should read "fair-trade"), "doesn't" (47; should read "isn't"), "top-" (64), "blocks" (67; should read "block"), "rules" (73; should read "rule"), "as [a] page" (76), "as screen" (93), "field_tax_code" (106-107; should read "field_vat_code"), and "cine" (108; movies and Jamaican coffee have the same pricing?).

    Like so many other books in the computer field, this one contains other flaws in the writing, such as semicolons used where commas are called for (e.g., page 5), and the mixing of singular and plural terms (e.g., page 28). However, its quality of writing is better than that of the majority of Packt Publishing's offerings.

    Most of this book's screenshots are quite helpful, although a few might cause some confusion, mostly in that they do not reflect what the reader will see in her own installation. Consider only a handful of examples: An image field "Progress indicator" is mentioned (page 39), but not evident in any screenshot nor on the "Product image" edit page in my own installation. The screenshot on page 45 does not include the "Description" field that the reader is instructed to create, two pages earlier. A "Product: Tax code" field is shown (page 57), prior to any tax functionality being implemented in the narrative. The checkout web page is missing a field for an e-mail address (page 80). Alert readers will immediately wonder where in Drupal Commerce they would go to modify the billing fields, but that doesn't seem to be covered (but I could be mistaken).

    One may level the charge that this book provides only the information needed to create a fairly simple e-commerce website. But that would be missing the point, because this book is not intended as an exhaustive exposition of the subject. Getting Started with Drupal Commerce is a valuable starting point for anyone interested in learning how to build online stores using Drupal 7.

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

    This book is available on Amazon

    Analyze Your Solr Index on Pantheon

    Posted by Mike Milano on October 14, 2013 at 5:31pm

    Ever curious about what exactly is getting indexed in Solr? Drupal abstracts Solr to a point where it can be difficult to understand how Solr is queried directly. It's actually not that difficult.

    Drupalcamp Atlanta - 5 Days Away!

    Posted by Mediacurrent on October 14, 2013 at 5:29pm

    Are you ready!? Drupalcamp Atlanta is just five (5!) days away. With 34 sponsors, 420+ registrations36 sessions, a job fair for employers and job seekers, expert round-tables, a product/demo room, and an awesome after-party, this is sure to be a great event.

    The Farmischt Freelancer

    Posted by Drupal Watchdog on October 14, 2013 at 3:50pm
    The Hunt for Chartreuse October

    No, dear readers, this isn’t a tale of a sunken initiative with a payload that threatens the rest of core, though darn, that would’ve been good! This is a tale that I hope will entertain those already moist in Drupal droplets, while informing the dry newbies among us.

    It is a megillah of mishigas[1] seemingly immune to the eroding currents of entropy. It begins on a cold November day, with yours truly staring at the home page of a mature Drupal site belonging to a newly acquired client. And there it was, by all appearances innocuous, except that it stared out at me from the center of the page, like a hibiscus in a field of Dusty Miller.

    OCTOBER

    It was this errant text I needed to exile from the page. You know the backstory: some other developer created the site and, for whatever reason, was no longer contactable. So it was up to me to discover the provenance of the chartreuse OCTOBER.

    J. Ayen Green

    J. Ayen Green authored Drupal 6 Content Administration, Drupal 6 Attachment Views, and Drupal 7 Views Recipes. He has been a developer long enough to be curmudgeonly. A writer of sorts, a poet of metered sorts, and a rascal of all sorts, Green enjoys nature, critters, kayaking, ethnic food, the arts, other cultures, horses and Hog. Track him down @accidentalcoder or theaccidentalcoder.com

    Share/Save

    Improving Drupal's default registration and login forms

    Posted by Deeson Online on October 14, 2013 at 2:25pm
    Improving Drupal's default registration and login formsBy Graeme Blackwood | 14th October 2013Do-Surgery's new login form

    We recently completed a complete overhaul of the user experience of Do-Surgery.com, a video training portal for surgeons, and I want to talk about just one area of the site that we have spent some time getting right.

    Login, or not to log in

    Debates about misspelling of the verb "log in" aside, login forms aren't particularly interesting, right?

    Drupal defaults to having a dedicated page for logging in, and an optional login block that you can put wherever you want. But the login block often gets stuck in a sidebar across the whole site, taking up valuable page real estate and limiting layouts to that classic body-with-sidebar look. Worse, the default approach for a responsive site is often to put the sidebar below the content area, meaning what is otherwise a very useful feature often doesn't even get used.

    Consider the alternative – a dedicated login page. Having to go through a whole server call and wait for a new page to load just to get to the login form is pretty heavy going, especially if you're a mobile user.

    So I revisited the block in an attempt to use it properly. By hiding it initially and intercepting clicks on the "Log in" link, I could keep it right under the header and toggle its appearance as instigated by the user – no server load or waiting times, just a pretty little form. Take a look! The focus states were quite fun to play around with, and I love using :active on buttons to get that depressed look on click, instead of an often-seen gradient flip on hover/focus. I know there isn't anything particularly original about all this; I'm just highlighting that with a bit of attention, there are some really easy wins for the experience of logging in.

    Registration, and legal and text, Oh My!

    If the requested data is used to enhance their experience, it's worth making that clear!

    Getting the registration form right can be a bit more involved. If your objective is to actively encourage registration, as with Do-Surgery, the registration form has to be right. It is an opportunity to remind the user of how they will benefit by sharing their data, and particularly if the requested data is used to enhance their experience, it's worth making that clear! This is what the old reg form looked like:

    Old registration form

    In the case of Do-Surgery, these were the factors influencing the requested information:

    • Access to the full site content is exclusive to surgeons, and acceptance of a user registration is performed manually after verification of their credentials.
    • Once logged in, the site recommends content to the user based on their area(s) of specialism.
    • Joining the mailing list also enables webinar registration, event reminders and tailored emails of new content in their area of specialism.
    The new form

    New registration form

    The leader copy is concise, reassuring and aspirational.

    Microcopy (via Drupal's form element descriptions) is used to communicate what information is required, but can overwhelm forms with text. So, I decided to hide the microcopy and show it only when a related textfield is in focus. If you're curious about the technicalities, I used input:focus + .description.

    Microcopy is also often only used on forms to describe what is needed (no spaces, lowercase only, that sort of thing). The user probably knows their own name, email address and area of specialism, so I shifted the copy angle to why we need this info, rather than just what. This means on each field, the user is reminded why they are bothering to complete the form, and encouraged to continue.

    How errors are handled on the new registration form

    The other useful thing about this approach is that if any required fields are incomplete when the user submits the form, we can highlight the microcopy, which explains why it is needed. This means the Drupal error message at the top of the page isn't so disconnected from the fields it refers to. All of this was done with almost no templating – just CSS, a bit of JS and some careful thinking.

    I'm not saying my approach is perfect, but it's a big improvement on the old form, and I'd encourage everyone reading this to look again with fresh eyes at their forms.

    Drupal 8 wins: unified entities n' plugins!

    Posted by Acquia on October 14, 2013 at 12:51pm

    Part 2 of 4 of the "Drupal 8 won't kill your kittens" live Hangout on Air with Lee Rowlands, Tim Plunkett, and Daniel Wehner. Here, we discuss the incredible improvements that have gone into Drupal 8's entity and plugin systems and how you will benefit from these as a developer.

    Let's Drup Up The Week. Issue 2

    Posted by TimOnWeb.com on October 14, 2013 at 9:17am

    This is the second issue of my weekly Drupal roundup. The first issue received lots of positive responses and I want to thank you for these. I hope that information gathered in this newsletter will be useful for you. I tried to gather the most interesting Drupal content that appeared in the last 7 days. If you want to get this roundup via email, signup with the form at the bottom.

    Read on about Let's Drup Up The Week. Issue 2

    Simpler Password Reset in Drupal 7 - Revisited and Improved

    Posted by Dave Cohen on October 14, 2013 at 12:44am

    This is a follow-up to my earlier post in which I described a simple trick changing Drupal's password reset behavior. That trick emails the user a link that logs them directly into the website, instead of the default one-time login page. That one-time login page forces user to click a Log in button before they are able to change their password.

    In the thread following that original post, Heine referred me to the Drupal issue in which the one-time login form was created. Now I understand better the reasons behind the one-time login form. To be perfectly frank, the solution from that thread was lazy. It solved the problem, but not elegantly, and Drupal deserves better. The user asked to reset their password so that's the form they should see, as soon as possible without the unnecessary step.

    Here's what the user sees first, in core Drupal:

    And here's what (I think) they should see:

    This post describes how to accomplish this with a custom module. [UPDATE: Save yourself the trouble of writing a custom module by downloading Simple Password Reset module from drupal.org.]

    Our strategy is to replace the unwanted behavior, which comes from a menu item defined in user.module. We use hook_menu_alter() to replace that behavior.

    <?php
    function custom_menu_alter(&$items) {
      // Drupal's default behavior is to show the user a log-in form, then their user profile.  We change this item to skip the unnecessary step.
      $items['user/reset/%/%/%'] = array(
        'title' => 'Reset password',
        'access callback' => 'custom_pass_reset_access',
        'access arguments' => array(2, 3, 4),
        'page callback' => 'custom_pass_reset_page',
        'page arguments' => array(2, 3, 4),
        'type' => MENU_CALLBACK,
      );
    }
    ?>

    An access callback ensures that only users who received the password reset email can reset their password. The URL parameters have to be just right. This is the same logic used in the core Drupal function that renders the one-time login form.

    <?php
    function custom_pass_reset_access($uid, $timestamp, $hashed_pass) {
      if (!drupal_anonymous_user()) {
        return FALSE;
      }

      // Following logic copied from user_pass_reset().
      // Time out, in seconds, until login URL expires. Defaults to 24 hours =
      // 86400 seconds.
      $timeout = variable_get('user_password_reset_timeout', 86400);
      $current = REQUEST_TIME;
      // Some redundant checks for extra security ?
      $users = user_load_multiple(array($uid), array('status' => '1'));
      if ($timestamp <= $current && $account = reset($users)) {
        // No time out for first time login.
        if ($account->login && $current - $timestamp > $timeout) {
          drupal_set_message(t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.'));
          drupal_goto('user/password');
        }
        elseif ($account->uid && $timestamp >= $account->login && $timestamp <= $current && $hashed_pass == user_pass_rehash($account->pass, $timestamp, $account->login)) {
          return TRUE;
        }
      }
      return FALSE;
    }
    ?>

    Now that our access callback ensures only the right users can access our reset page, we can show the profile edit form. Remember, this is where Drupal shows the unwanted one-time login. Instead we let the user make the password change right away.

    <?php
    function custom_pass_reset_page($uid, $timestamp, $hashed_pass, $option = NULL) {
      module_load_include('inc', 'user', 'user.pages');

      // Show the user edit form instead of silly one-time login form.
      $account = user_load($uid);
      $form = drupal_get_form('user_profile_form', $account);
      return $form;
    }
    ?>

    That seems quite simple, but we're not done. At this point the user would be able to change their password, but then they'd have to log in manually. We want to save them the trouble, and log them in right away. The profile edit form becomes the one-time login form. To do this, we need a hook_form_alter().

    <?php
    function custom_form_user_profile_form_alter(&$form, &$form_state) {
      if (arg(0) == 'user' && arg(1) == 'reset' && drupal_anonymous_user()) {
        // This is not the normal profile edit form, but actually the password reset form.

        // Our submit handler will log the use in after form submit.
        $form['#submit'][] = 'custom_pass_reset_submit';

        // Require a new password.
        $form['account']['pass']['#required'] = TRUE;

        if (arg(5) == 'brief') {
          // Since the user is most interested in getting a working password, we don't need to show their picture, timezone, etc.
          foreach (element_children($form) as $key) {
            //dpm($form[$key], $key);
            if ($form[$key]['#type'] == 'fieldset') {
              $form[$key]['#access'] = FALSE;
            }
          }
          $form['account']['#access'] = TRUE;
          $form['actions']['#access'] = TRUE;
          $form['actions']['submit']['#value'] = t('Reset password');
          $form['account']['mail']['#access'] = FALSE;
        }
      }
    }

    function custom_pass_reset_submit($form, &$form_state) {
      if (drupal_anonymous_user()) { // Sanity check.
        // This logic copied from user_pass_reset().
        $account = $form_state['user'];
        $GLOBALS['user'] = $form_state['user'];
        user_login_finalize();

        watchdog('user', 'User %name used one-time login link.', array('%name' => $account->name));
        drupal_set_message(t('Your password has been reset.  Welcome back, %name.', array('%name' => format_username($account))));

        $form_state['redirect'] = 'user';
      }
    }
    ?>

    Two things to note in the above code. First, we add a submit handler to the profile edit form (but only when used to reset a password). Our submit handler logs the user in so they don't have to do it manually.

    Second thing to notice, we honor an optional parameter, "brief", which abbreviates the form. This is because Drupal uses the reset page not just when a password is reset but also when new user accounts are created or email addresses are confirmed. In those cases it may be reasonable to show the entire profile edit form. When just resetting password, it's nice to show them only that portion of the form. To use this feature, under Admin >> Configuration >> People >> Settings >> Password recovery, replace the token [user:one-time-login-url] with this:

    [user:one-time-login-url]/brief

    This technique allows an administrator to choose between the longer or shorter version of the form fairly easily.

    So there you have it! This approach should have none of the drawbacks of my earlier trick, and all the benefits.

    Tags:

    Subscribe with RSS Syndicate content

    Planet Drupal aggregates broadly appealing, Drupal-related blog posts pertaining to the community at large (code, advocacy, marketing, infrastructure etc.). If you would like your blog to be included in the Planet, read the requirements and steps on how to join.

    Collecting posts from the following 520 sources:

    XML feed
    nobody click here