6199 comments
2357 subscribers
Follow me on Twitter (@sachac)
Subscribe! Feed reader E-mail

Notes from today’s Drupal hacking

  • Avatar selection/upload during registration: Oddly enough, avatar_selection doesn’t handle this. You need the reg_with_pic module, too.
  • Shared and per-site file directories: We’re segregating uploaded files by microsite, but we want to share some files as well. Hacking the shared path into file.inc is a kludge, but it works. Like so:
    --- file.inc    (revision 1046)
    +++ file.inc    (revision 1589)
    @@ -66,6 +66,11 @@
    else if (file_check_location($file_path . '/' . $dest, $file_path)) {
    return $file_path . '/' . $dest;
    }
    +  // Not found, check by going up one more
    +  else if (file_check_location($file_path . '/' . $dest, $file_path . '/../')) {
    +    return $file_path  . '/' . $dest;
    +  }
    +
    // File not found.
    return FALSE;
    }
    
  • Group names with signed-up events: signup.module doesn’t make it easy to theme the list of events, so I created my own block based on the code in signup_list_user_signups. To determine the possible group a node came from, I check for the intersection between $node->og_groups and the array keys of $user->og_groups.
  • Fixed panes: I couldn’t figure out a way to set a block as fixed in Panels 2, but a workaround is to define a custom layout that includes the block in the right place. Here’s an example:
    /**
     * Implements hook_panels_layouts
     */
    function mymodule_panels_layouts() {
      $items['my_panel'] = array(
        'title'  => t('My Panel Layout'),
        'icon'   => 'my_panel.png',
        'theme'  => 'my_panel',
        'css'    => 'my_panel.css',
        'panels' => array(
          'top' => t('Top'),
          'left' => t('Left'),
          'right' => t('Right'),
        ),
      )
      return $items
    }
    
    /**
     * This function uses heredoc notation to make it easier to convert
     * to a template.
     */
    function theme_my_panel($id, $content) {
      if ($id) {
        $idstr = " id='$id'"
      }
      // Pull in the Organic Groups - 0 block.
      $group_details = og_block('view', 0)
      $group_block = < <<EOT
      <div class="block block-og" id="block-og-0">               
        <h2 class="title">$group_details[subject]</h2>
        <div class="content">
        $group_details[content]
        </div>
        
    EOT
      $output = < <<EOT
    <div class="panel-2col-stacked clear-block panel-display" $idstr>
      <div class="panel-col-top panel-panel">
        <div class="inside">$content[top]</div>
      </div>
        <div class="center-wrapper">
        <div class="panel-col-first panel-panel">
        <div class="inside">
        $content[left]
        </div>
        </div>
        <div class="panel-col-last panel-panel">
        <div class="inside">
        $group_block
        $content[right]
        </div>
        </div>
      </div>
      <div class="panel-col-bottom panel-panel">
        <div class="inside">$content[bottom]</div>
      </div>
    EOT
      return $output;
    }
    

    To limit the choices to just that layout, put this in your installation profile:

      panels_load_include('common');
      $allowed_layouts = new panels_allowed_layouts();
      $allowed_layouts->allow_new = TRUE;
      $allowed_layouts->module_name = 'panels_common';
      $allowed_layouts->allowed_layout_settings = array(
        'threecol_33_34_33_stacked' => 0,
        'twocol' => 0,
        'flexible' => 0,
        'threecol_25_50_25' => 0,
        'threecol_25_50_25_stacked' => 0,
        'onecol' => 0,
        'threecol_33_34_33' => 0,
        'twocol_stacked' => 0,
        'twocol_bricks' => 0,
        'my_panel' => 1
      );
      $allowed_layouts->api_save();
    
  • Organic Groups RSS feed: There’s an og_aggregator module, although it doesn’t quite fit in neatly with everything else.
  • Organic Groups tag cloud: I was surprised to find that this wasn’t built in. I ended up defining my own block using a SQL query like this:
            if (($node = og_get_group_context()) && node_access('view', $node)) {
              $result = db_query(
                'SELECT COUNT(*) AS count, d.tid, d.name, d.vid FROM {term_data} d
                 INNER JOIN {term_node} n ON (d.tid=n.tid)
                 INNER JOIN {og_ancestry} og ON (og.nid=n.nid)
                 WHERE og.group_nid=%d AND d.vid=0 GROUP BY d.tid, d.name, d.vid ORDER BY count DESC', $node->nid);
              $steps = 6;
              $tags = tagadelic_build_weighted_tags($result, $steps);
              $tags = tagadelic_sort_tags($tags);
              $output = theme('og_tagadelic_weighted', $node, $tags);
              $block['content'] = $output;
            }
    

    og_tagadelic_weighted was a custom theme function that constructed a link to a faceted_search using the og: and taxonomy: filters. I had to hack faceted_search, too. First I needed to enable the og filter, and then I needed to make taxonomy_facets.module recognize free tags (vid=0). Patch for taxonomy_facets.module:

    ===================================================================
    --- taxonomy_facets.module	(revision 1046)
    +++ taxonomy_facets.module	(revision 1582)
    @@ -147,6 +147,7 @@
           // and create facets from it.
           if ($found_text = search_query_extract($arg, 'taxonomy')) {
             $vocabularies = taxonomy_get_vocabularies();
    +        $vocabularies[0] = 1;
             // Extract separate facets
             $paths = explode(',', $found_text);
             foreach ($paths as $path_index => $tids) {
    

It’s a good thing I can find my way around sparsely-documented code with few or no examples… <laugh>

Short URL: http://sachachua.com/blog/p/5409
  • http://bmannconsulting.com Boris Mann

    These examples and patches are great, Sacha. What’s your plan for giving back / integrating upstream?

    For example, I can tell you that dww, maintainer of signup, would welcome feedback / a patch that would “make it easy to theme the list of events” — probably a theme_ function of some kind.

    Keep up the good work, and thanks for sharing directly here.

  • http://themegarden.org Drupal Themes Garden

    thanks for those nice hacks/patches.

    Suggestion: it could be nice if you could add attachments with patches.

On This Day...

  • 2012: Investing time into building sketchnotes as a business — Something shifted, and I was curious about what it was. I’ve been drawing a whole lot more than I did [...]
  • 2011: Transcript: Blogging (Part 15): Tools to help you get started — Hat-tip to Holly Tse for organizing this interview! At the end of the blog series, I’ll put them all together [...]
  • 2010: Writing about lots of different kinds of things — The first change off the bat is to just start writing more varied material and see what sticks, an approach [...]
  • 2009: The shy connector’s guide to business travel — As an introvert, I often find business travel quite stressful. I know I should be making better use of the [...]
  • 2007: Finding out if I’m overscheduled — If you’re anything like me, your task list is long and growing, but the time you have is just as fixed. [...]
  • 2005: Ruby: Turn bash.org quotes into a fortune file — The following code turns XML quotes from bash.org (a popular IRC quotes server) into a fortune-cookie file. Handy for using with [...]
  • 2005: Two years ago — Was it really just two years ago today that I learned that free tech support gets you so much more than [...]
  • 2005: To write well, one must have leisure — To write well, one must have leisure: leisure to read, leisure to think, to talk things over, to talk oneself [...]
  • 2005: Squidoo now on public beta — Squidoo opened its doors to the public today. Open beta. Try it out if you’re into Web 2.0 stuff. I’m personally [...]
  • 2005: Secret Santa exchanges the Web way — Elfster makes it easy to set up Secret Santa gift exchanges. It automates signing up, drawing people, and even anonymously asking questions. [...]
  • 2005: From elsewhere: Linux: a social experiment — Linux advocate disguised as panhandler gives CDs away. Interesting social results: most people don’t read signs, and panhandling is fairly [...]
  • 2004: Panic, panic — MIT application coming up soon. Dec 15. Nearly forgot about it. Embarrassing, as I’m into personal information management. At least my statement [...]
  • 2004: Demo tomorrow — Objective: Give Prof. Chignell some ideas about Planner so that he can introduce me to the wearable computing and personal information management [...]
  • 2004: Philippine websites ranked — From the Philippine PHP mailing list: here’s a site that lists the philippine’s top sites by alexa. the one on cebu-online doesn’t [...]
  • 2003: Burrito attempt flop. — Writing off attempt to make burritos, as lettuce makes burrito soggy. Must figure out how to do it properly. In meantime, [...]
  • 2003: Fortuitious events — Found my keys in pocket of khaki jacket. Extremely fortunate as discovered upon entering Ateneo that no classes meant buildings were closed [...]
  • 2003: Training — The normal arrangement is HRD goes into a contract with the instructor, but since it’s a short course, we’ll just send [...]
  • 2003: Problems with lphdisk — lphdisk does not seem to recognize my hibernation partition. Here is the output of fdisk -l /dev/hda: Disk /dev/hda: 20.0 GB, 20003880960 [...]