Doomed To Reinvent

There’s an old saying, “Whoever doesn’t understand X is doomed to reinvent it.”X can stand for any number of things. The other day, I was pointing out that such is the case for ORM developers. Take ActiveRecord, for example. As I demonstrated in a 2007 Presentation, because ActiveRecord doesn’t support simple things like aggregates or querying against functions or changing how objects are identified, you have to fall back on using its find_by_sql() method to actually run the SQL, or using fuck typing to force ActiveRecord to do what you want. There are only two ways to get around this: Abandon the ORM and just use SQL, or keep improving the ORM until it has, in effect, reinvented SQL. Which would you choose?

I was thinking about this as I was hacking on a Drupal installation for a client. The design spec called for the comment form to be styled in a very specific way, with image submit buttons. Drupal has this baroque interface for building forms: essentially an array of arrays. Each element of the array is a form element, unless it’s markup. Or something. I can’t really make heads or tails of it. What’s important is that there are a limited number of form elements you can create, and as of Drupal 5, image isn’t fucking one of them!.

Now, as a software developer, I can understand this. I sometimes overlook a feature when implementing some code. But the trouble is: why have some bizarre data structure to representa subset of HTML when you have something that already works: it’s called HTML. Drupal, it seems, is doomed to reinvent HTML.

So just as I have often had to use find_by_sql() as the fallback to get ActiveRecord to fetch the data I want, as opposed to what it thinks I want, I had to fallback on the Drupal form data structure’s ability to accept embedded HTML like so:

$form['submit_stuff'] = array(
  '#weight' => 20,
  '#type'   => 'markup',
  '#value'  => '<div class="form-submits">’
             . '<label></label><p class="message">(Maximum 3000 characters)</p>'
             . '<div class="btns">'
             . '<input type="image" value="Preview comment" name="op" src="preview.png" />'
             . '<img width="1" height="23" src="divider.png" />'
             . '<input type="image" value="Post comment" name="op" src="post.png" />'
             . '</div></div>',
);

Dear god, why? I understand that you can create images using an array in Drupal 6, but I fail to understand why it was ever a problem. Just give me a templating environment where I can write the fucking HTML myself. Actually, Drupal already has one, it’s called PHP!. Please don’t make me deal with this weird hierarchy of arrrays, it’s just a bad reimplementation of a subset of HTML.

I expect that there actually is some way to get what I want, even in Drupal 5, as I’m doing some templating for comments and pages and whatnot. But that should be the default IMHO. The weird combining of code and markup into this hydra-headed data structure (and don’t even get me started on the need for the #weight key to get things where I want them) is just so unnecessary.

In short, if it ain’t broke, don’t reinvent it!

</rant>

  • E-mail this story to a friend!
  • Sphinn
  • StumbleUpon
  • Facebook
  • del.icio.us
  • LinkedIn
  • TwitThis
  • Digg
  • Google
  • MySpace
  • Reddit
  • StumbleUpon
  • Technorati
  • Yahoo! Buzz

Comments & Trackbacks

studdugie wrote:

I feel your pain. I've also inherited a cluster fuck of really fucked up php code where shit is just being reinvented from file to file. There is this one file that is ground zero for the admin interface, it's 12,696 lines long.

NonProfit wrote:

Drupal has a complete templating system, (The .tpl.php files). Image submit buttons are no more difficult than implementing any other .css sprite. Assign your class to the .tpl file, load as a background image via .css. Search for the Drupal Theming Guide for more details.

Andrew Berry wrote:

Try theming your form instead

I think you've missed that you can theme the output of your form's HTML quite easily. For example, on one site we wanted the search submit button to be an image button which was specific for the theme. In your template.php for your theme, you can override the theme function for the button. You'll have more maintainable code (since the button will still work if you change themes), and it will be easier to understand.

On the flip side, if you're doing theming which is part of a module and not tied to your current design, you can implement the theme code there by using the #theme property of the form, or by just implementing the default theme_myformname() function.

Take a look at this:

/**
 * Override the default search form theming.
 */
function phptemplate_search_theme_form($form) {
  unset($form['search_theme_form']['#title']);
  // This is just to make it a little cleaner, it doesn't have to be
  // it's own function.
  $submit = mytheme_search_button($form['submit']);
  $form['submit']['#printed'] = TRUE;
  return drupal_render($form) . $submit;
}

/**
 * Print the search form element as an image button.
 * Most of this is copied from theme_search_button().
 */
function mytheme_search_button($element) {
  global $base_path;
  // Make sure not to overwrite classes.
  if (isset($element['#attributes']['class'])) {
    $element['#attributes']['class'] = 'form-'. $element['#button_type'] .' '. $element['#attributes']['class'];
  }
  else {
    $element['#attributes']['class'] = 'form-'. $element['#button_type'];
  }

  return '<input type="image" src="' . $base_path . path_to_theme('mytheme') . '/images/en/buttons/go.gif" ' . (empty($element['#name']) ? '' : 'name="'. $element['#name'] .'" ') .'id="'. $element['#id'] .'" value="'. check_plain($element['#value']) .'" '. drupal_attributes($element['#attributes']) ." />\n";
}

Hope that helps (and renders right - I don't see a preview button).

Discussion is now closed.

Powered by KinoSearch