Shomeya

Two web artists. One amazing company.

What do building web apps & houses have in common?

from Sarah Prasuhn on May 10, 2013 01:44pm

What is a million dollar house worth if it has bad wiring? Bad wiring means ripping out the drywall, getting it inspected by the city, and starting from scratch. If you have a builder that would allow something like that, as an owner you have to go from the bottom up and review what else they left lurking in your dream home.

Web application development is no different from a house. Sites require real estate, maintenance, and are living, functioning pieces. They require the occasional remodel to add more features as users needs change.

So why do so many web consultants often act like the McMansion builder of the web? Build it fast, cheap, charge as much as we can and walk out the door? Who do they think they're fooling? Maybe the clients, but will they be repeat clients?

Read more

Making Drupal images look good on retina displays

from Michael Prasuhn on April 9, 2013 11:35am

Article_large_retina-phone

"Why does my site look blurry?"

After hours of laboring over a new Drupal theme, you check, double check, compile, and push your code. After emailing your client you sit back anticipating a pat on the back when you hear "Why is it blurry on my iPhone?"

While responsive design goes a long way towards making your site look great on all different sizes of devices it doesn't take into account the device resolution or 'retina' aspect of device its being displayed upon.

What is a "Retina" display?

Retina is the term that Apple uses to describe their high DPI (dots per inch, sometimes seen as PPI, or pixels per inch) screens, which simply means that the individual pixels on their screens are smaller, and there are more of them in a given space. This make text and images more crisp by displaying more detailed information.

It's not just Apple devices

You might think that this is a problem limited to Apple devices based on how heavily Apple market this feature, but there are plenty of other devices out there. Many of the top selling Android phones and tablets would qualify as high DPI too, such as the Nexus S, Nexus 7 and the new Samsung Galaxy S3.

You're going to need something other than a few CSS3 media queries to make your images look good on all the devices out there...

Read more

Using per-project Drush commands to simplify your development

from Michael Prasuhn on February 19, 2013 08:45am

Article_large_2013-02-18_17.55.54

Developing a large Drupal site is no easy task and managing all the latest tools isn't getting any easier. Between SASS, Compass, Simpletest, Guard, Behat, Capistrano, Git, and sometimes even Drush itself, you've got alot of commands to master. Trying to remember all the right flags and syntax can be a nightmare that ends up requiring it's own documentation page just to get all of your team on the same page. If you've ever caught yourself or another developer asking someone to paste a command into a chat window, or sharing their shell history via email, it's time to simplify things by writing your own Drush commands.

Read more

Killing pesky caching during migrations and upgrades part 1: drupal_static()

from Michael Prasuhn on September 25, 2012 01:30pm

At the end of a long day of writing and testing some new features for a Drupal site I decided to be a good developer and wrap up my changes in a migration, or update function and get the code out the door. My code looked something like this:

<?php
function my_module_update_7001() {
  module_enable(array('bean'));

  $plugin_info = _bean_admin_default_plugin();
  $plugin_info['name'] = '';

  $bean_type = new BeanCustom($plugin_info);
  $bean_type->type = 'social_links';
  $bean_type->setLabel(t('Social links'));
  $bean_type->setDescription('');
  $bean_type->save(TRUE);

  user_role_grant_permissions(1, array('view any social_links bean'));
}

Seem simple enough, just create a new entity type, and setup permission inside of hook_update_N. It's a piece of cake thanks to many of the new APIs in Drupal 7, right? When I tried this code, I was presented with the following error:

PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'module' cannot be null:    [error]
INSERT INTO {role_permission} (rid, permission, module) VALUES (:db_insert_placeholder_0,
:db_insert_placeholder_1, :db_insert_placeholder_2); Array
(
    [:db_insert_placeholder_0] => 1
    [:db_insert_placeholder_1] => view any social_links bean
    [:db_insert_placeholder_2] =>
)
 in user_role_grant_permissions() (line 3034 of modules/user/user.module).

Huh? How can that module not be enabled, and why doesn't user_role_grant_permission know about this module?

Read more

Update allowed values during a content migration

from Michael Prasuhn on May 28, 2012 05:00pm

Many times during a large data migration we have a case where we want to import some data into field that should be a list type with a select widget (either dropdown or multi-select) but we don't know what all those values are when setting up the field type, or starting development since the data to be migrated is still being edited.

In these cases what we end up doing is just making sure that each imported value is added to the allowed values list for that field if it isn't already present. To do that we use the following pattern.

In a custom module add the following bit of code:

<?php
/**
* Verify that a given value is in the list of allowed values for a field.
*/
function _MYMODULE_verify_allowed_value($field_name, $value, $key = NULL) {
  $field_info = field_info_field($field_name);
  if ($field_info) {
    if ($key == NULL) {
      $key = $value;
    }
    if (array_key_exists($key, $field_info['settings']['allowed_values'])) {
      return TRUE;
    }
    else {
      $field_info['settings']['allowed_values'][$key] = $value;
      try {
        field_update_field($field_info);
      }
      catch (FieldException $e) {
        return FALSE;
      }
      return TRUE;
    }
  }
}

Then in your migration simply call that function from prepareRow():

<?php
class MymoduleCustomMigration extends MymoduleBaseMigration {
  public function __construct() {
    /** snip */
  }

  /**
* PrepareRow callback.
*/
  public function prepareRow(stdClass $row) {
    _MYMODULE_verify_allowed_value('field_product_color', $row->color);
    _MYMODULE_verify_allowed_value('field_product_sizes', $row->size);
  }
}

What this does is call this function for each row of data to be migrated and ensure that it's value is present or added to the allowed values list before the new item is actually saved.

Getting started with Compass and Drupal

from Michael Prasuhn on January 9, 2011 04:00pm

Here at Shomeya we have been making some changes to our design process, and Sarah has started to write about the creative process but I thought I would cover some of the technical challenges. We decided to use SASS and Compass to develop the visual look and feel of our site (I'll leave the 'why' for another article) and needed to find a way to make Compass play nice with Drupal. While there is a Compass module for Drupal, we did not use that for this project since it was not ported to Drupal 7 at the time we started, and we wanted to use the convenient compass watch command to automatically rebuild our stylesheets. We did this by moving the config file from a normal compass project to the root of our Drupal site, and configuring it with the full path of our theme folder in our config.rb:

# Require any additional compass plugins here.
# Set this to the root of your project when deployed:
http_path = "/"
css_dir = "sites/all/themes/shomeya_theme/css"
sass_dir = "sites/all/themes/shomeya_theme/src"
images_dir = "sites/all/themes/shomeya_theme/css/images"
javascripts_dir = "sites/all/themes/shomeya_theme/javascripts"
# To enable relative paths to assets via compass helper functions. Uncomment:
# relative_assets = true
preferred_syntax = :sass

I think using this technique has several benefits, such as providing a clean consistent place to run compass watch and should we decide to use full URLS, as some mixins do, the path will be correct, referencing the root directory of our site. Then when we are ready to deploy changes we can run compass compile --force -e production -s compressed add the files into git, commit and we're ready to push changes.

Getting used to #attached

from Michael Prasuhn on January 6, 2011 03:00pm

In the course of building our new website on Drupal 7 I wanted to get to know some of the cooler new features that are now available, after spending the last three years salivating over commits and code that wasn't always 100% stables (even though it was 99.99% stable for the most part).

One of these new features is the #attached property which allows you to attach Javascript or CSS to any point in a render array structure and let the render API make sure that it ends up in the appropriate place in the header, footer, inline or external, whatever. You can read about the changes compared to Drupal 6 code on the Converting 6.x modules to 7.x page on Drupal.org. In short, you don't need to call drupal_add_css() or drupal_add_js() anymore, although that method still works fine. The advantages of using the render API quickly become apparent should you want to modify the JS or CSS attached to an element from another section of code. Although the online API docs don't indicate this, it works just fine with render arrays, not just forms.

An example

We wanted to add simple effect from the jQuery Inline Fields plugin to the search box at the top of our site. This required including an external Javascript file and a small portion of inline javascript to trigger the effect on the field. Here's the code that it takes to make this happen (I'll explain this in more detail below):

<?php
/**
* Implements hook_form_FORM_ID_alter().
*/
function shomeya_theme_form_search_block_form_alter(&$form, &$form_state, $form_id) {
  $form['search_block_form']['#title_display'] = 'before';
  $form['#attached']['js'] = array(
    array(
      'data' => drupal_get_path('theme', 'shomeya_theme') . '/js/infields.js',
      'options' => array(
        'group' => JS_LIBRARY,
        'preprocess' => TRUE,
        'every_page' => TRUE,
      ),
    ),
    "jQuery('#search-block-form label').inFieldLabels({fadeOpacity: 0.5, fadeDuration: 150});" => array('type' => 'inline', 'group' => JS_THEME, 'scope' => 'footer'),
  );
}
?>

First off, you may have noticed that this was placed in our theme. Yup, it turns out that in Drupal 7, themes can implement several common alter hooks This is great since this isn't really a change that affect any functionality, it's pure presentation. This lets us keep UI focused Javascript and code in our theme, and the themers and developers can stay out of each others way very easily, even if the code would be identical if it was in a module.

Secondly, since we are modifying the search block form the first thing we had to do to make the Inline Fields plugin work was make sure that the label was visible. In past versions of Drupal, or in many contributed themes this would be done with targeted CSS, and while the form label is still hidden with CSS, it's not a case of targeted CSS anymore. The form element was wrapped in a class of 'element-invisible' which is a new feature in Drupal 7 that helps many individuals using your site with screen reader software. This is an awesome feature but we needed to disable it. By examining the non-rendered structure of the form, we can see that there is a new '#title_display' element responsible for this class, simply changing that to before, removed the 'element-invisible' class and we were on our way.

Using #attached

As you can see from the code sample above, #attached can take data in multiple ways. If the key of the element inside of #attached is numeric, it looks for a 'data' element, and reads in extra items from and 'options' array. This is how the Inline Fields JS file is included. On line 16 of the snippet you'll see the other method of using #attached, which is where the element's key is a string, and the element itself is an array of options. Here you can see that we have a 1 line snippet to target the #search-block-form label, and call the inFieldLabels method on it. We've declared this an inline script, set to be output in the footer, and grouped with other items coming from the theme. All of these options and more are documented with drupal_add_js on api.drupal.org.

While this doesn't seem like a huge change, it subtlety affects the way that processing and alterations are performed in Drupal 7, and hopefully will catch on as a primary method for those doing tiny alters to other forms, or structures to add their JS and CSS to forms, in a way that others can easily manipulate. I'd love to hear and see what other uses for #attached that developers are coming up with. If you have an interesting example, please share it in the comments and let us know how Drupal 7 is changing the way you develop.

Experiments in WebDesign: Part 1

from Sarah Prasuhn on January 4, 2011 02:00pm

Article_large_paper_-_large

This is the first post in a three part series on the re-design process of Shomeya.com, and what we learned. Getting started was actually the hardest point, for every method of web-design there are five different tools you could use. We looked at everything from hosted, adobe, and free solutions like google docs and tried most of them.

Old School

Paper beat them all. With Konigi's version of the blueprint grid we were able to refine a process and make decisions quickly. And by using blueprint grids whatever we did on paper could translate to our mockup on the screen with simplicity of adding a few classes. (Later we switched to SASS and Compass, but that's post 2.)

Advantages of paper

The eraser. A big fat one. It was so refreshing to not have to select and delete and undelete items every time we wanted to make an adjustment. By printing out several grids and creating a few layout mockups deciding on the structure was much easier. With that new structure I began making copies and adding elements in different variations. By adding and removing elements quickly we came to agreement on the design much faster, and kept the project from losing momentum in that crucial stage of initial excitement. With less time investment overall it made changes less personal, and more about achieving our goals.

Disadvantages

Face-to-face interaction is best with this method, which can be costly or difficult depending on where your client is located. Sharing paper in person is much simpler than from 2,000 miles away. Balsamiq or this Google Drawing is my choice of mockup for something that I need to have in digital format to edit with clients. However, I would still start with paper simply because for me inspiration is found much more quickly with a break from the computer and a chance to blink.

Inspiration

Paper isn't the best method for every project, but ultimately web-design is a marriage between the functional and the creative. The early stages of design are all about inspiring the functional elements to exist cohesively in a way that ultimately inspires your client's users. Paper allows this inspiration to flow without Photoshop crashing, and having to learn how to manipulate lines on a screen.

The Journey to Drupal 7

from Michael Prasuhn and Sarah Prasuhn on December 30, 2010 02:00pm

Article_large_d7-clouds

As the world takes in all the changes in Drupal 7, the developers are already tirelessly moving onto Drupal 8. So before we get into how awesome D7 is we would like to thank all of the collaborators that we have worked with off and on for the past three years. D7 contributors you are truly a remarkable group of people to see this difficult journey through with such incredible results.

The journey to Drupal 7 was a long and difficult one, but the product is nothing short of amazing. In fact it is very possible that no one really knows how much Drupal 7 will change the course of history for the individuals that have participated, and for those yet to use it. Three years is a long time for a Drupal release, but Drupal 7 is well worth wait.

It maintains and extends the concepts that have made Drupal what it is. With a powerful and focused core that is easy to build upon, and usable by even those with no prior web-development experience.

In the backend a new powerful Field API uses entities. Allowing tighter integration and better support, and a consistent way to extend any Drupal object from users to files, and taxonomy terms. In addition it works more easily with new generation NoSQL databases such as MongoDB, Riak, and many others.

Overlays make administrating simpler out the box. This in addition to the new Seven theme make administering sites faster and provide a consistent UI wherever Drupal 7 is used. This also reduces the level of expertise needed to add content and moderate sites. Which all adds up to leaving more time in development to focus on building the forward site instead of the administration pages.

Subscribe via RSS