Skip directly to content

drupal

How to use theme_pager without a SQL query (and go to hell)

on June 29th, 2010 at 10:42:27 AM

pager.inc is... ugly.  Let's get that out of the way.  I'm sure there are valiant souls out there who are not bitching about it, but trying to fix it.  I'm not one of those people right now, I've got my own battles, but if you happen to go up against it and want to create a pager for a data source which isn't a SQL database, here's what you need to do (mostly copied from pager_query):

Global variables (yes and it gets worse)

pager.inc makes extensive use of global variables to pass around the state of the pager.  You can see how these are defined in pager_query():

global $pager_page_array, $pager_total, $pager_total_items;

Honestly, don't ask me what these are.  Roughly, $pager_page_array is an array of different pagers on the page and what page they are at (I think).  $pager_total is the total number of pages for each pager, $pager_total_items is the number of items in the set.

These are all set in pager_query if you care to find out more.

 

Getting the current page

You'll need this of course to split your set up so you can show just what you need to show on that page.

Fortunately, this is pretty straightforward in a really obtuse way:

$page = isset($_GET['page']) ? $_GET['page'] : '';
// The user will go to mypage?page=0,3,5,6.
// What does this mean?  There are 4 pagers on the page.
// They don't have names, just numbers.
// Sorta like in a prison, only it's a mental facility and the inmates are running it.
// The first one is on page 0, the 2nd one on page 3, etc. etc

$pager_page_array = explode(',', $page);
// So this builds an array of all the pagers on the page and what page they are on.
// One of these is the pager you care about. In most cases, it is the only one, 
// so you can just set $element = 0;
$yourpage = $pager_page_array[$element];

Okay, now you do whatever you need to with that in terms of running a for loop to build a table or whatever.

Setting up the pager

// Number to show per page.
$limit = 10;
// The bizarre "element number" as long as you are the only pager on the page
// this will work fine
$element = 0;
// $total_records is a variable you define that reflects the total number of
// records you plan on showing (not per page but overall).
$pager_total_items[$element] = $total_records
// This is the total number of pages.  If you can't figure this out,
// go back to grammar school.
$pager_total[$element] = ceil($pager_total_items[$element] / $limit);
// wtf...
$pager_page_array[$element] = max(0, min((int)$pager_page_array[$element], 
  ((int)$pager_total[$element]) - 1));
// No seriously... wtf... this is basically saying, I'm on the first page,
// unless I'm not. I know, it's really clear.

Let it loose

return $my_paged_content . theme('pager');
// Go get a drink.

Okay, I hope I helped someone.  Happy hacking.

Oh and don't forget to vote for my DrupalCon Copenhagen sessions!! I really want to go and got to get 'em accepted. If you want me to remind (harass) you when voting opens, please follow me on twitter @JacobSingh.

Giving our customers the gift of Ham: Mollom (anti-spam service) provisioning API

on June 9th, 2010 at 10:28:17 AM

Well, Sprint 39 just finished up at Acquia Engineering and we've got a number of new exciting features and bug fixes releasing to Drupal Gardens in the next week.  One of these is Mollom - the best spam protection service on the internet - for all Drupal Gardens site owners.  For those not in the know, Mollom protects your site from spam by analyzing the contents of comments or other content that is contributed by users and presenting Captcha challenges if the content is suspect.

What this means for Drupal Gardens beta testers:

You'll get setup with the best spam protection available from Mollom.  No cost, nothing for you to do.  Just works.

What this means for Developers who want to provide Mollom to their customers:

Most people aren't aware, but Mollom offers an extensive provisioning API for Mollom partners to create accounts on behalf of their customers.  Gábor Hojtsy and I got to work on this feature and Gábor wrote the mollomapi module which does the provisioning. Here's a sample of how the API works:

$mollom_keys = mollomapi_site_add('whitehouse.gov', 'obama@whitehouse.gov');
if (!empty($mollom_keys) && is_array($mollom_keys)) {
  $public_key = $mollom_keys['public_key'];
  $private_key = $mollom_keys['private_key'];
}
Cool. right?  The full API docs are available from Mollom, so feel free to get in touch with mollom, request a reseller account and continue the quest to rid the 'net of spam!

Create gorgeous rotating banners with 0% nerdliness

on May 6th, 2010 at 12:12:00 PM

Acquia's been working on ways to let people create really professional looking Drupal sites using only web-based tools.  One of those tools is the Rotating Banner module which just had its first release this morning.  What is a rotating banner?  I'm talking about those pretty slideshow type things at the top of most sites' homepages these days.  For a couple examples, check out http://acquia.comhttp://kofiannanfoundation.org/, http://amnesty.orgThis module was developed for Drupal Gardens by myself and James Elliot.

Core features:

  • Various transition effects (fade, wipe, etc)
  • A rich editor where you can pick a background image and add headlines and text areas with inline editing
  • Pre-defined layouts for your text or a custom mode where you can drag and drop right where you want.
  • Creates blocks, you can make a bunch of them.  Put them in sidebars, the header, etc.
  • Can be a static size, or will grow to the size of your largest / smallest image or the size of the region you put it in automatically!
  • Controls for switching between slides, or auto transition

Demo (click to view on YouTube):

How Acquia keeps aHEAD of Drupal 7

on April 29th, 2010 at 6:48:22 AM

When we (Acquia) started planning our hosted Drupal service (Drupal Gardens) a year ago we had to take the call of developing in Drupal 7 or Drupal 6.  I don't think this was ever really in doubt, but the decision to try to build a product on Drupal 7 core at that stage was certainly a risky one. Why? there were almost no contributed modules or themes and the architecture and APIs were changing daily. Acquia's business is squarely Drupal.  Drupal support, Drupal promotion, Drupal migrations, Drupal polish, Drupal architecture, Drupal Drupal Drupal (you know the song).  So even though this was a risk, we knew that the benefits to Drupal and Acquia would be too great to back down from it.

There is a saying open source software: 

Q: When will it be done?

A: When it is done.

One of the things the Drupal community prides itself on is a dogged dedication to quality irrespective of commercial or social pressures.  This means that we have to be prepared to stay up to date with new developments and adapt our product to the movement of the many thousands of developers who drive Drupal forward. 

In other words, everyone on the Gardens engineering team has to be aware of what's going on with core.  We have to keep up with every commit and know which ones are likely to land in the future.  Many of our engineers also figure heavily into the list of core patch writers and reviewers.  

The upside is that we all get to work on core, improving Drupal while testing the core APIs by building the first product on Drupal 7.  The community gets a massive influx of hours by Acquia engineers AND a ton of free beta testing as we have thousands of Gardens sites using Drupal 7 and finding bugs / suggesting improvements. The feedback thus far  from gardens testers on the usability improvements in Drupal 7 has been extremely positive!

 

Recently, we decided to switch from basing Drupal Gardens releases off of Drupal 7 Alpha releases to running off of "HEAD".  What is HEAD and what is the difference?

  • Alpha releases are getting released every month or so.  They mark a point in time which Angie Byron (webchick) and Dries have decided that the product is "stable enough" to declare an alpha release.   It doesn't mean a whole lot, but is basically a chance to mark the time, look at our achievements and encourage people to try it out and get involved outside of the core developer community.
  • HEAD means the latest and greatest code that gets added to Drupal core.  Every day Dries and webchick commit about 8-12 new pieces of code.  So if you grab HEAD today, you have the very last thing that was added, if you grab it tomorrow, you'll get the changes that went in tomorrow.

Running from an Alpha vs HEAD is like the difference between playing Jenga on a sleeping elephant to playing Jenga on a cocaine addled elephant riding a skateboard being jabbed in the ass with a hot poker.  In other words, it's a wild ride.

To facilitate that process, here's what we do:

(Warning: It's about to get nerdy up in here, so if you don't care about such things, leave now with the elephant image)

  • Every sprint (3 weeks) we create a new branch for the core upgrade.  We do this to keep trunk from being broken while we at least get it installing.
  • Next, we go through the entire CVS log from the last time we updated until now.  I use Git for core development and GitX for reviewing the backlog.  It's a pretty sweet process, see the pic (click for larger):



    20100429-mmcshgwi6kc2xx2tc34p8x2x7b.png


     
  • While going through the backlog we:
    • Identify each change which will affect databases and require a head2head update function (more on that below)
    • Identify each change which changes APIs that we use in our custom modules or install profiles
    • Identify each change that will affect our documentation and screenshots
  • Then we repeat the process for every contributed module we have in our code base.  We check their changelogs, update their code and if it hasn't been updated (which is often the case), we contribute patches to the queue or commit if we have rights.
  • Nathanial Catchpole (Catch), a member of the Clarity team started the head2head module recently.  This module is an effort for D7 developers to collaborate on update functions.  Since Drupal 7 is not released yet, there is no upgrade path supported.  This means that when code changes, it can totally break your site or destroy data (remember the elephant).  Since we've got thousands of people using Drupal 7 on real sites (like this one) in Drupal Gardens, we can't do that.  So people who contribute to head2head add those update functions which would be present in all official Drupal releases (and will be supported when the first Drupal 7 beta comes out).  We love this idea and have already made a few commits there!
  • We then update all of our custom modules and make sure that we can install DrupalGardens.
  • Then comes the fun part.  To ensure that we don't break our beta-tester's sites, we actually take dozens of example sites and upgrade them using our automated build process.  We run automated testing and manual testing to ensure that there was no data loss and the upgrade smoothly completed.

We live on the bleeding edge, so you don't have to.

I'm proud to be a member of our team because even though this is a really difficult task and we expose ourselves to a lot of risk, it all of this leads to big improvements in Drupal 7 core and contrib. For instance, here's a sample of some of the modules we have either written or contributed to as a part of Gardens: FollowMailing ListComment NotifyMediaSimpleviewsPathautoRotating BannerMollomStylesTypekitWysiwygAddthis.  This version of Drupal Core may be one of the most widely tested versions by the time it releases and thanks to the efforts of the #D7CX crew will have more than enough contributed modules!

If anyone is interested on how to keep up2date with Drupal 7 and/or how to get involved in Drupal 7 core development, please feel free to get in touch.

Comment moderation fixed on Drupal Gardens / D7

on March 31st, 2010 at 2:38:29 PM

Yay!  While I was off basking in the newborness of my daughter (code name poopiepants) the Gardens team was busy banging out a bunch of new features and making bug fixes in Drupal 7.

One of the small ones which was a huge thorn in my side since migrating my blog from my old blog was a few bugs in Drupal 7 comment moderation. Mollom support in Gardens is just around the corner, but in the mean time, I got a bad case of the spammies.

A brief summary:

  • Previously, the nice approve and delete buttons on each unmodderated comment did nothing.  Now they work
  • Previously, when you multi-selected comments to approve, only the first one actually got approved, now they all will.

Sweet!  Keep on Gardening!

Correction: Media module demo link

on March 15th, 2010 at 6:38:00 PM

Hey planet,

Something strange happened where only I could see the embedded youtube video of the demo.  Sorry for the confusion.  If you were interested in a demo of the currently in progress media module, I've added a link to the demo. (It's' at the bottom): http://jacobsingh.drupalgardens.com/content/media-mania-multimedia-solution-drupal-7

Apologies, my webmaster will be flogged appropriately.

Media Mania - The Multimedia solution for Drupal 7.

on March 15th, 2010 at 2:11:39 PM

Most who know me know I like to take on Big, Scary, Projects and make them work.  But, I don't go in with a blueprint and a chizel, I typically go in with a bottle of whiskey, a stubborn attitude, best intentions and a sledgehammer.  

My latest baby is Media.  The Multimedia solution for Drupal 7.

I'll spare you the history, because it is quite long and involved.  It can all be read on the product page.  It is numerous heroes specing, designing, factoring, refactoring, re-refactoring.  It is the shoulders of giants like emfield, styles, field API, asset, wysiwyg and image_assist. And it is the ongoing support of companies like Acquia and Advomatic.

My ideas are simple though:

  • You never have to upload twice.  Whenever you need a file, and it's already on your system, you should be able to re-use it.
  • Files have feelings too :)  They have meta-data, they should have fields.   MP3s have genres, images have captions.  Make them 1st class entities.
  • The Internet is full of media.  You should be able to use a flickr image, a youtube video and an uploaded image in the same gallery and with the same interface.
  • Media belongs *everywhere*.  You should be able to embed media in any text area on Drupal
  • Media is for everyone.  Make it safe and easy for any users (even anonymous ones) to upload, select, and reference media in their content.
  • A picture says a thousands words.  I want one of those words to be Sexy.  A nice API is great, but we also want this to look great.  We want people to hand media to their clients and watch their jaw drop with a zero-training-required solution.

You can see the project page for the status of various features in this goal.

The latest demo (below) shows the new media_gallery module which I've been developing.  This will provide a way to create collections of media objects and give them descriptions.

It also shows off how media works as a field, and can be attached to anything fieldable in Drupal 7.

Link to video: http://www.youtube.com/watch?v=Sqyh-TQKAQI

 

Mediacrity 50% complete

on March 14th, 2010 at 12:42:34 PM

I got a little time off from "normal" sprint work since Acquia is beginning a new sprint and my baby is supposed to arrive any day now :)

So being the manic workaholic that I am, I  made some major improvements to the Media module in the past few days.  To name a few:

  • Re-wrote the browser to be more "drupally" I think it's a good compromise of convention and flexibility.  Let's see... http://drupal.org/node/697036
  • Implemented the Entity Api and type restrictions (so launch a browser to just select images)  http://drupal.org/node/697106
  • Got Media as a field working really nicely, got multi-value field support http://drupal.org/node/740546
  • Added a title and data field to the media field so that extending modules can chuck on extra information there.  Sweet! No issue for this, just a bonus.
  • Built the media_gallery module.  This is a new entity called gallery with 2 fields: Title and Media Items.  Media items is a multi-value media field with a description and link for each item.  Next step is to build the display mechanism for it.  I will be posting a video for this soon!
  • Kicked the shit out of cruft
  • Build a bulk importer which is awesome for testing, and fun for making albums: http://drupal.org/node/739430
  • Created a testbed interface for trying out different launch parameters.
  • Dynamic AJAX Scrolling for the library!

I promise, a more engaging demo is coming soon(ish) depending on how long I stay on this roll and when I become a parent. 

Media demo

How expensive is an anti-pattern?

on March 4th, 2010 at 12:29:02 PM

This one really got my goat today...

I was trying to figure out why file_transfer wasn't sending the headers I was passing in after upgrading my module from D6 to D7.

Turns out that the function signature for the function which sends headers had changed, and decided that instead of taking a serial array, it now takes an associative array.  That's fine and all, but it did something I see commonly in Drupal which makes my blood boil.

It does nothing.

No error, no warning, nothing.  In fact, the function drupal_add_http_header($name, $value) actually returns you a list of headers already added if you don't pass in the name.  Imagine all the disk space saved by not creating a function called drupal_get_http_headers! errr....

http://drupal.org/node/732486