Topic: Drupal

The Drupal Commerce Address Duplication Issue

Recently I was working on a very large Drupal Commerce website that required many addresses for shipping (not billing) per customer.

The setup of the site was rather unique and required us to create many custom modules utilizing. We also needed a way to create orders on the front end of the site (the shopping cart side) and the back end of the site (the administrators side).

One thing that we noticed was that the checkout process on the front end and back end were very different. As a front end user, it’s the pretty typical shopping cart experience, but the backend was very different.

Going through the order creation process, we noticed there wasn’t a good way to search for a user. But even if we did manage to reference the user correctly using their email address, we couldn’t select one of their previously user addresses for an order.

Enter in the Commerce Admin Order Advanced module.

This module was exactly what we needed to search for customers and pick a previously used address that is stored as a Customer Profile in Commerce (and the address book if you’re using the AddressBook module).

But right off the bat, we noticed that ever single time we placed and order for a user, their address profile was duplicated. So one customer would have dozens of the same addresses entered into the system. You can see from he screenshot above, the same address is showing in the dropdown twice.

In one test, I had at least 20 of the same addresses in the system for one user. So if a manager went to go create an order, the same address was showing up over and over again. This didn’t seem like a very good user experience.

The strange thing is that, after we did some research, we realized that the address duplication was default commerce behavior.

Customer Profiles seem to endlessly duplicate!

Our solution was to allow the duplicate address to be created, but if the address is being referenced from an already existing customer profile, the new profile that is created when the order is saved would be set to deactivated.

// Load the current shipping profile
  $profile_dedup = commerce_customer_profile_load($form_state['values']['shipping_profile']);

  // If the profile is set and has an ID
  if(isset($profile_dedup->profile_id)) {
     
      // Load the referenced customer profile into the order
      $profile = commerce_customer_profile_load($profile_dedup->profile_id);

      // Set the status to deactivated so the shipping profile doesn't show up in the select box
    $profile->status = 0;
   
    // Save the profile as deactivated
    commerce_customer_profile_save($profile);    
  }

Twitter Lite Drupal Module

A while back, I was working on a Drupal website that needed to be lightweight and flexible. One of the requirements was a Twitter feed.

Now, don’t get me wrong, the official Twitter Drupal module is nice and has some great features. I have always felt like it’s a little bloated and not as easy as it should be to make a Twitter feed.

I decided to make a quick an easy to use module to solve my problem.

I’m naming it Twitter Lite since it is the lite version of the Twitter module. It doesn’t have all of the features that the Twitter module has.

This module creates two Twitter feed blocks. You can also choose how many tweets to show per block.

Eventually I’ll extend this to show hashtag searches as well as usernames. For now, it only uses usernames.

There are some fallbacks that need to be made also.

Feel free to try it out on your own Drupal 7 site.

Please feel free to let me know if you have any bug reports or issues with the module. I’d like to actively maintain this and prep it for Drupal 8.

Drupal Sandbox Project Page: https://www.drupal.org/sandbox/tk421jag/2451325

Github repo: https://github.com/jasonglisson/twitter_lite

Being a successful Drupal Developer

I’m a web developer. I enjoy what I do. A lot.

About 7 years ago, I discovered what it was that I was missing in web development. Drupal.

Drupal is open source software maintained and developed by a community of over 1,000,000 users and developers. (That’s taken directly from Drupal’s website.)

The first Drupal website I put together was a combination of downloading modules, hacking themes, and generally having no idea what I was doing. But it was fun and I was learning what Drupal was. I recall it was just after Drupal 6 was launched. Seems like it was eons ago.

I wish I could go back and yell at the developer I was then for not doing things a better way. Knowing what I know now, my development skills have dramatically improved and I try very hard to stay within the Drupal Best Practices documentation.

Here are some of my tips for being a successful Drupal developer.

Don’t hack core!

This is basically one of the cardinal rules of Drupal development. Hacking core files of Drupal means updating the site will likely break everything. Also hacking modules means that you won’t be able to update them for bug fixes and troubleshooting.

Learn to use the Drupal API

Eventually, you’ll find the need to write functions and do crazy things with your code. The fun part of developing for Drupal is that the API rocks. I mean, really rocks. There are so many cool functions and code snippets for doing things that would otherwise take you forever to write/code yourself. Learn to use things like node_load(), path_to_theme(), node_save(). These three functions are simple but extremely useful. Use case: I recently wrote a module that went through 20,000 nodes for a Drupal website, retrieved data from another website using their API, brought that data back to my project site, then saved the data using node_save(). Doing that by hand, no. It would take weeks on top of weeks. The script I wrote took 90 seconds. Boom. Drupal Magic.

Contribute to the Drupal Community

Whether you contribute code, testing, or bug reports, Drupal thrives off the community. This is something that I failed at for a while. I simply felt that I wasn’t good enough to contribute to discussions or code. However, simply reporting a bug is useful to the community. If you’ve used a module and had an issue with it’s basic usage, report it. Search for the bug you’re reporting first. It could be that it’s a duplicate issue. Please please please search for the issue first. Don’t be a lazy Googler.

Learn Version Control

This may be one of the most valuable takeaways from this post. Version control isn’t just used by the Drupal community, it’s used by coders everywhere for a wide variety of things. Personally, I use Git for version control, but there are many other options. Some people find it very daunting to do things in Command Line or Terminal (that thing that looks like MS-Dos for those that don’t know). It’s really very simple though. If you learn version control, you’re value to a company will go up significantly. I promise. Here are a few sites that might help:

  • Easy Guide – http://rogerdudler.github.io/git-guide/
  • Try Git – https://try.github.io/levels/1/challenges/1
  • GitHub – https://github.com/

Learn helpful shortcuts

For a long long time, when I setup a Drupal website, there was a lot of downloading, decompressing files, placing modules and themes in the correct place, then finally starting to work on the project. Enter Drush. If you are using Command Line/Terminal, then Drush will be your best friend. Using Drush, you can download Drupal, setup themes and install them, download modules and install them, update Drupal, backup you site, and a slew of other things using very basic and easy commands. It’s cut down my setup time to just a few minutes. Read up on Drush here.

Setup local development environments

Gone are the days where you had to have a server to work on a website. There are some very easy to setup tools that you can use to setup your site on your desktop or laptop so you can work on it anywhere without the internet. I once worked on a local website for 2 hours while my train was stuck in a cellular dead zone in Virginia. Try using MAMP to setup your local environment so you can get coding and work on your sites from anywhere.

Attend conferences and meetups

Speaking for myself, I learned Drupal development from a hand full of very gifted developers over a long period of time. It never hurts to find a developer willing to share some knowledge with you. The best resource to learn Drupal is by going to conferences and meetups to hear people speak on a wide variety of topics. Maybe you can even take some training. Drupal Con is a big one. I’ve never had the opportunity to go, but something tells me that I will soon. My favorite conference was the 2011 Do It With Drupal (DIWD) conference by Lullabot. My mind was blown about every 60 seconds. I came back understanding more about development skills, Drupal development, and the future of the web. Here are some highlights from that conference.

Don’t be closed minded to other technologies

I love Drupal. We know this. But I also love WordPress. I can hear some developers now: What’s that you say! Traitor! Burn him!

Calm down people. Being a web developer doesn’t mean I only want to do things my way or I only want to use one technology to do things. You need to learn when and where specific software and tools will work best. If someone says to me “I want a website, but I’m not that good at computers, but I do want to write blog post” then I’m likely gonna recommend WordPress. But if someone comes to me and said, “I want a custom website where I can load in videos, pictures, and other content. I also want to sell things, etc etc” then I’d likely recommend Drupal.

Having said that, there are other options outside of Drupal and WordPress that I’ve also used from time to time. Flat-file CMS’ are popping up everywhere. they are lightweight and easy to setup. One of my favorites is GetSimple. Another one is Pico.

Hopefully this will help someone figure out what they need to learn to be more successful at Drupal development. As always, feel free to contact me if you have any questions. Except for haters. You guys can jump in front of a bus.

Convert Taxonomy Term ID (tid) to alias url path

While working on a tremendously large Drupal 7 project, I found myself needing to convert Taxonomy tid’s to full URLs. The easiest solution was to just print out the value of the field after the taxonomy path url, like this:

/taxonomy/term/$tid

A problem with this is that it’s not following the alias naming conventions that you may have setup for your site. In my case, I had hundreds of taxonomy terms that were setup with specific URLs.

Luckily, Drupal has it’s own function to link the terms to their alias URLs.

$url = drupal_lookup_path('alias', 'taxonomy/term/'. $known_tid);

So in my case, I was able to write a foreach statement to cycle through all of my terms that have been referenced through an entity reference field.

foreach ($node->field_related_issues['und'] as $val) {
    $tid = $val['taxonomy_term']->tid;
    $url = drupal_lookup_path('alias', 'taxonomy/term/'. $tid);
    echo '<li><a href="/' . $url . '">' . $val['taxonomy_term']->name . '</a></li>';			    
}

Display only the first menu link in Drupal 7

This is a useful Drupal 7 code snippet that can echo out the first (or whatever link you prefer) link in a menu. Recently, I used this to create a menu with one link used for a Donation button. I wanted to prevent any other items being echoed or inserted into a block area, so I used this so that the first menu item was always the only one that would be shown. It was useful since, on other pages, the full menu with other links under “Donate” was used in Block form.

<?php
$menu_depth = 1;
$menu_tree = menu_tree_output(menu_tree_all_data('menu-donate', null, $menu_depth));
print drupal_render($menu_tree);
?>	

Delete all of a content type in Drupal 7

On a recent project, I had the need to delete thousands of a content type in order for me to correct some issues with the website, before re-adding them all. This is a useful script that I found to do just that. You fill in your content type, and all the nodes will be deleted. This works best in a custom module that you can turn on or off.

$node_types = array('content_type'); // add the machine names of node types you want to bulk delete

$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->propertyCondition('type', $node_types, 'IN');
$result = $query->execute();
foreach($result['node'] as $node){
node_delete($node->nid);
}

Find Your Congressperson Drupal Module

This module allows users to lookup a congressperson using a 5 digit US zipcode. It connects to the Sunlight Foundation Congress API V3 (https://sunlightlabs.github.io/congress).

The admin page allows you to toggle on and off the features that you’d like to display.

Here are some screenshots:

drupal module

drupal module
drupal module

You can view this modules on going development on GitHub and on Drupal.org.

Note: This was originally named “Find Your Congressman” because of a clients requirements. I’ve since renamed it “Find Your Congressperson”.

Add a Search field anywhere in a Drupal template file

When I’m theming a site in Drupal, I don’t always use the search block that Drupal provides. Sometimes I like to put a search field in the header, sidebar, or even in the off-canvas menu. This snippet will let you display a search field anywhere you’d like.

<div id="search-form" class="search">
    <?php $form = drupal_get_form('search_block_form', TRUE); ?>
    <?php print render($form); ?>
</div>

Creating a fixed header region in Drupal 7

One of the big web design trends in the last year has been fixed headers. They look great (sometimes) and you can do some really creative things with them.



tech-crunch

This article will explain how to make a fixed header that appears after the website scrolls up. Essentially, you’ll have two headers. One fixed, and one scrolling.

When doing this in Drupal 7 you’ll run across several issues:

  1. What CSS changes do you need to make for all of this to work?
  2. Accommodating the admin bar on the top and the fixed header.
  3. How does the fixed header work as a region? How do I create a new region?

CSS

Let’s look at the CSS first. You’ll need to use something like firebug to check where your header region begins and ends. This can vary template to template. Find the line in your stylesheet that has all of the CSS for your header div. Usually begins with .header or .header-wrapper.

Here is the CSS that I used on my site:

#header {
    position: relative;
    z-index: 999;
}

You might also, depending on your template, need to make the header’s width 100% of the page. Or if you want it to only stretch a certain width, then just adjust the width to match your template.

Now, we’re going to go ahead and create the CSS for the new fixed header. We’ll call the new div “fixed-header”. Creative, right?

#fixed-header {
    width: 960px;
    margin: auto;
    position: fixed;
    top: 0;
    z-index: 99;
    text-align: center;
}

Then create the container that the fixed header region will reside in.v You can call this anything you’d like, but just make a note of it.

.top-fixed-area {
    width: 1000%;
    height: 60px;
    margin: auto;
    position: fixed;
    top: 0;
    z-index: 99;
    background-color:#fff;
}

Note the z-index value. That is really what creates the magic here and it’s very simple to alter. You don’t have to use 9’s, I just have a habit of using them. One 9 will be the lowest layer. 99 will appear over that layer. 999 will appear as the top layer. And so on. Makes sense, right?

Fix the Admin Bar

While you’re in the stylesheet, go ahead and adjust your admin menu so that when you’re logged in, it appears over everything:

#admin-menu, #admin-menu ul {
    line-height: 1.4em;
    list-style: none;
    margin: 0;
    padding: 0;
    z-index: 99999;
}

Create a New Region

Next we’ll need to create a region in Drupal and insert the CSS to make that region work.

Go into your theme folder on your server and open the .info file for your theme. MAKE SURE YOU BACK THIS UP BEFORE DOING ANY EDITS! You’ll notice that these regions coincide with the regions in your block administration page. Insert a line just under the header region called “Fixed Header”. This will be the title that shows up in your block administration area.

    regions[header] = Header
    regions[fixed_header] = Fixed Header
    regions[help] = Help
    regions[page_top] = Page top
    regions[page_bottom] = Page bottom
    regions[highlighted] = Highlighted

Now, open your page.tpl.php. PLEASE remember to back this up. You’ll need to do two things here.

  1. Create the div for the fixed header to “reside” in.
  2. Create the region for the fixed header.

Insert this just before your header div. Should look something like:

<div class="top-fixed-area"></div>

Next create your fixed header region. I’ve done this in a manner so that I have two logos. One logo will be in your normal header, and the other will be a shorter logo tailored to your fixed header height.

<?php if ($page['fixed_header']): ?>
  <div id="fixed-header">
                 <a href="<?php print $front_page; ?>" title="<?php print t('Home'); ?>" rel="home" id="logo">
    <img src="INSERT YOUR PATH TO THE FIXED HEADER LOGO HERE" alt="<?php print t('Home'); ?>">
  </a>
        <div class="top-header">
    <?php print render($page['fixed_header']); ?>
  </div></div> <!-- /.fixed-header, /#fixed-header -->
<?php endif; ?>

Save this and drop it back in your theme folder then clear your cache.

After refreshing your site, you should see the header appear at the top, and you should have a Fixed Header region in your block administration page.

 

Conclusion

Naturally, you can style this any way that you’d like. I’ve done a drop shadow on the content area before, which looks great. Making the header background transparent looks awesome as well. You can do that by using a transparent PNG as the background. I am doing this type of fixed header on a furniture website that I’m developing right now (pictured above). The logo was no problem, and you can use the module “Menu Clone” to copy your top menu and create a new block to place into your new fixed header region.

That’s pretty much it! Ask any questions if you got ’em. All comments are monitored and approved.