Welcome to Look Alive! Blog of Alli Price, a Front-end Developer living in the UK who works with Drupal and lots of other fun stuff!

Posted: Monday, February 13th 2012

If you ever used the Pathauto module and the very useful [menupath-raw] token in Drupal 7 this is gone.

Using the latest stable release of Token module, this is now the way!

[node:menu-link:parents:join:/]/[node:title]

 

The use case for this would be that you have a page at /shop, and you want to create a sub-page under it (let's say we're creating a Help page), and have that hierarchy reflected in the URL, you'd set the parent menu item for your new node as "Shop", then you'd get the URL:

/shop/help

If you just had the node at the top level of a menu, not nested in any way you'd get:

/help

Posted: Wednesday, August 31st 2011

So far this year has had a lot of (justified) noise bounced about advocating responsive design, not so long ago Henrik Eneroth did an excellent post and suggested re-design of the browser as we know it. Pulling out responsive design from within the browser viewport to the application level.

The results make a lot of sense, elevating the buzz wordy "responsive" design from just something for web designers, but as a way of thinking to design in general.

Here's his original post (via @cameronmoll):
http://blogg.antrop.se/interaktionsdesign/redesigning-the-browser-window

 

Mozilla have released screenshots of the user interface for Firefox for Honeycomb Android tabets which is very close to what's described in the original post, not quite a full blown re-think of the browser for the desktop, but a move in the right direction, and a signal that Mozilla are very much switched on.
http://www.engadget.com/2011/08/30/firefox-for-honeycomb-ui-shown-off-in...

Posted: Sunday, August 21st 2011
Tags:

Here's a couple tips for views theming, great fun! Also an opportunity for the longest post title in the world.

First, How to get the row id from within the fields template.

When doing your own custom views theming, it can be useful to know which row number you're currently working with. A good example of this usage would be super-sizing certain elements for the first row of a listing.

To begin let's take a look at the default fields template views-view-fields.tpl.php.

<?php
/**
* @file views-view-fields.tpl.php
* Default simple view template to all the fields as a row.
*
* - $view: The view in use.
* - $fields: an array of $field objects. Each one contains:
*   - $field->content: The output of the field.
*   - $field->raw: The raw data for the field, if it exists. This is NOT output safe.
*   - $field->class: The safe class id to use.
*   - $field->handler: The Views field handler object controlling this field. Do not use
*     var_export to dump this object, as it can't handle the recursion.
*   - $field->inline: Whether or not the field should be inline.
*   - $field->inline_html: either div or span based on the above flag.
*   - $field->wrapper_prefix: A complete wrapper containing the inline_html to use.
*   - $field->wrapper_suffix: The closing tag for the wrapper.
*   - $field->separator: an optional separator that may appear before a field.
*   - $field->label: The wrap label text to use.
*   - $field->label_html: The full HTML of the label to use including
*     configured element type.
* - $row: The raw result object from the query, with all data it fetched.
*
* @ingroup views_templates
*/
?>

<?php foreach ($fields as $id => $field): ?>
  <?php if (!empty($field->separator)): ?>
    <?php print $field->separator; ?>
  <?php endif; ?>

  <?php print $field->wrapper_prefix; ?>
    <?php print $field->label_html; ?>
    <?php print $field->content; ?>
  <?php print $field->wrapper_suffix; ?>
<?php endforeach; ?>

At the top of the file you've got a listing of the variables available to you, very useful! But there is an extra variable not listed: $id.

At a guess, it's not mentioned as the variable name is re-used in the foreach loop, before this point you can re-assign it or re-use it.

Depending on the nature of theming we are carrying out, sometimes it's necessary to have a specific HTML structure to each row, here's an example of this, making use of $id to add an extra class to the first item.

<?php
// $Id$
/**
* @file views-view-fields.tpl.php
*/

$wrapper_classes = 'wrapper';

if (
$id == 0) {
   
$wrapper_classes .= ' supersize';
}
?>

<div class="<?php print $wrapper_classes; ?>">
  <div class="left image">
  <?php print $fields['field_image_fid']->content; ?>
  </div>
  <div class="left text">
  <h2><?php print $fields['title']->content; ?></h2>
  <?php print $fields['teaser']->content; ?>
  </div>
</div>

Second, How to tell how many total rows a view has found, not just the number it's currently displaying.

This one's actually really easy, where-ever you have a view, in a view template, when running a view in code, you can do:

<?php
$view
= views_get_view('view_machine_name');
$view->execute();

$view->total_rows;
?>

One caveat, for this to work, your view needs to be using a pager. If you're not there are other ways, but it's a bit more involved.

Posted: Saturday, August 6th 2011
Tags:

If you've tweaked your user register form, and now for some reason you can't add a new user via the admin section. It's entirely possble that you've changed the submit buttons value, like:

/**
* Implementation of hook_form_alter().
*/
function mymodule_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'user_register') {
    $form['submit']['#value'] = t('Register');
  }
}

The user_register form is re-used in the admin section, so any tweaks you make will appear here also. Unusually if you change the submit value, then the admin user register form will break, and bounce you back to admin/user/user without an error message.

All you need to do is make the submit value tweak specific to only the front-end form:

/**
* Implementation of hook_form_alter().
*/
function mymodule_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'user_register') {
    if (arg(0) == 'user') {
      $form['submit']['#value'] = t('Register');
    }
  }
}

Et voilà!

Posted: Saturday, August 6th 2011

If for whatever reason you need to search an entire database (and you don't have PhpMyAdmin available to you) then a really quick and easy way is to use mysqldump and grep.

First do a mysqldump of the database you want to search:

mysqldump -uUSERNAME -p DATABASE_NAME > database-dump.sql

Replacing USERNAME and DATABASE_NAME with your respective details, for more on mysqldump go here: LINK

Once you've got your database in a file just grep!

grep -i database-dump.sql "Search string"

Easy huh :)

Posted: Saturday, August 6th 2011

First up is a pretty cool showcase of what you can acheieve from a typography point of view with web fonts, called Lost Worlds Fairs, which take place on the Moon and at Atlantis (latter being my favourite!).

http://lostworldsfairs.com
http://lostworldsfairs.com/atlantis

Next up is the very cool iScroll project. I've just used this on some client work, and whilst it does seem to be a little quirky in some cases, it tends to behave more often than not on mobile devices though.

So what does it solve? On certain mobile devices like an iPhone or iPad, if you've got an area which has CSS overflow: scroll or auto applied, on a desktop browser you would get scrollbars, but on these devices you get …nothing.

What end users might not know is that you can still scroll these areas using two fingers, but this isn't very clear, and can result in a frustrating experience. Enter iScroll which simply adds scrollbars to these areas (and more)! You will need to target these areas and add iScroll, it doesn't magically detect them, but offers up a solution for something Apple didn't particularly want to tackle.

Posted: Sunday, July 3rd 2011

Out of curiosity I had a search around for which usages would be quicker:

$('#wrapper').hasClass('sidebars');

Or

$('#wrapper.sidebars').length > 0;

As it happens the guys over at JsPerf have already worked it out, which is a good chance to introduce this excellent resource of js based performance tests:

http://jsperf.com/jquery-selector-vs-hasclass
http://jsperf.com/browse

So the bottom line? Go with .hasClass();!

Posted: Wednesday, June 29th 2011

I'm thinking there should be a Drupal on the edge series, featuring all the weird and wonderful problems you're never likely to encounter :)

Here's one of them, recently I've had to work with negative timestamps and Drupal, which as it happens doesn't support negative timestamps.

The issue is one more of PHP compatibility than Drupal, providing you're running PHP >= 5.1 all you need to do is apply the patch from the following d.org issue:

http://drupal.org/node/271398#comment-888391
http://drupal.org/files/issues/node.module_80.patch

 

That's it! But to help you with whatever troubles you may have, I came across this very helpful post on how to convert dates to timestamps whilst keeping in mind negative timestamps, and vice versa:

http://www.epochconverter.com/programming/mysql-from-unixtime.php (See the heading "Negative epochs" on this page).

Posted: Wednesday, June 22nd 2011

The jQuery Lazy loader plugin, as been around for a long old while and I've been aware of it, though never really given it a good poke, mostly due to the big fat warning at the top of the page saying "this doesn't work".

Having seen a few sites which use it, this plugin still doesn't work. Browsers still "front load" all of the content, then once you scroll and the image you're lazy loading comes into view, it downloads the image again.

So this isn't too awesome, but not useless. If you've got a site which you can require that Javascript be on, any images which you want to lazy load should start out with a placeholder image, e.g.

<div class="listing">
  <div class="row">
    <div class="image"><img src="placeholder-image.gif" original="path-to-giant-image.jpg" class="lazy-load" alt="" /></div>
    <div class="text">
      <h3>Hello world article</h3>
      <p>Lorem ipsum etcerum...</p>
    </div>
  </div>
</div>

With the JS being something like:

$(function() {
  $("img.lazy-load").lazyload({effect: 'fadeIn'});
});

To this end, I've come across a modified version of the aforementioned plugin which does exactly that. It works, but the obvious limitation is that if you don't have javascript turned on you won't see any images.

Here's the code for the plugin

// Adapted Lazy load plugin from http://www.appelsiini.net/projects/lazyload

(function ($) {
    var $window = $(window);
    $.fn.lazyload = function (options) {
        var didScroll = false;
        var options = $.extend({
            threshold: 100,
            effect: "show",
            effectspeed: 0
        }, options || {});
        var elements = this;
        var load = function () {
                elements.each(function () {
                    var self = $(this);
                    if (!isBelowFold(self, options)) {
                        self.trigger("appear")
                    }
                })
            };
        $window.bind("scroll", function () {
            didScroll = true
        });
        setInterval(function () {
            if (didScroll) {
                didScroll = false;
                load()
            }
        }, 400);
        return elements.each(function () {
            var self = $(this),
                src = self.attr("data-src");
            self.one("appear", function () {
                $("").bind("load", function () {
                    self.hide().attr("src", src)[options.effect](options.effectspeed);
                    self.data("loaded", true);
                    var temp = $.grep(elements, function (item) {
                        return !$(item).data("loaded")
                    });
                    if (temp.length == 0) {
                        $window.unbind("scroll", load)
                    }
                }).attr("src", src)
            });
            if (!isBelowFold(self, options)) {
                self.trigger("appear")
            } else {
                self.data("loaded", false)
            }
        })
    };
    var isBelowFold = function (element, options) {
            var fold = $window.scrollTop() + $window.height(),
                imgPos = element.offset().top;
            return imgPos >= (fold + options.threshold) || false
        }
})(jQuery);