drupal

Sneezing Alligators Come to the Gardens

If you've stumbled your way here, welcome. While I've had the great opportunity to support, use and play with Drupal Gardens the last few months, the number of sites I've built have primary been used for testing. This, here, is my first "real" site, that will soon replace my current blog at http://alligatorsneeze.com

I'm one of those developers that even when I might have the time, there's almost always more pressing matters, other sites to break or fix, or a multitude of other tasks piled upon my to-do list that working on my own personal site and blog is almost always at the very bottom of the list. Because of this, Drupal Gardens is a perfect choice for me. It allows me to quickly put a site up, use the awesome theme builder to more easily customize the look and feel of my site, and I don't have to worry about updating it or keeping it maintained.

Sounds perfect, right?

We'll see. I very much realize it's still in beta, and that Drupal 7 is still in alpha. I suspect I'll continue to run into issues. But I'm having a lot of fun building out this site. I've got my banner working after a couple snags and will be working more on the way the site looks. Being that I have very little design background or sense, we'll see how that plays out...

Drupal Quick Tip #2: Using Images as Submit Buttons (5.x)

This is a pretty simple task but one I seem to end up doing over and over again for whatever project I'm working on at the time. I've done it a number of ways, from simply using CSS and dealing with multiple cross-browser issues, and probably quite a few alterations of this technique.

In our custom module we're going to need a couple functions. First, we need to use hook_elements to define our new image element.


function siteconfig_elements() {
$type['image_button'] = array(
'#input' => TRUE,
'#button_type' => 'submit',
);
return $type;
}
?>

Next, we need to theme our new type of element, which is called image_button above.


function theme_image_button($element) {
return '\n";
}
?>

This is a very similar to Drupal's core theme_button function.

This function is needed to ensure the default_value doesn't get moved to #value. This should solve the issue with multiple submit buttons some browsers have.


function image_button_value() {
// null value to guarantee default_value doesn't get moved to #value }
?>

Next, we need to use our trusty old hook_form_alter for the submit button of our choice.


function siteconfig_form_alter($form_id, &$form) {
if ($form_id == 'myformid') {
$form['submit'] = array(
'#type' => 'image_button',
'#image' => base_path() . path_to_theme() .'/images/search-btn.gif',
'#title' => t('Search'),
'#default_value' => t('Search'),
);
}
}
?>

Voila! Thanks chx and merlinofchaos. ;)

Tags: 

Drupalcon is Exhausting

Note: Not posting this to Drupal planet as it's not really that interesting for most people.

End of day three of Drupalcon Boston 2008. It's been fun, stressful, exhausting, interesting, insightful and I'm incredibly mentally and physically exhausted! I feel like I could sleep for days. I actually did oversleep this morning after a late night over at FELT, the awesome gathering Acquia threw. I was sad to miss the Simpletest session.

So... recap of my day yesterday. I went to the Future of Fields session which was really insightful, but I couldn't get my wireless working during it which tends to make me impatient.

Went to the Google in Open Source session since my wireless wasn't working. It was entertaining, which is always good.

I left early because I had some work to do and quite honestly the crowds of people were starting to get to me. I found out I forgot my hotel key in the hotel room, the hotel help desk wouldn't give me a replacement because I never actually checked in (it was checked in under my co-worker's name who was also staying in the room, nikkiana), and ended up finding the best wifi in this city at the mall across the street from the Royal Sonesta hotel. Woo hoo! Starbucks + awesome wifi = heaven.

Got some work done, yay. Went to FELT and that was fun. Met a lot of people I've been wanting to and played some really awful games of pool, wanted to play Wii but never got it, generally a good time. Stayed up way too late, though.

Today's sessions were pretty interesting. I went to .. ugh, I can't even remember now. Oh, the Dragon Drop session was awwwwesome. I can't wait to implement it in my soon to be released module and use it more in D6! Hurrah.

Went to the Flex/Flash session, that was cool. Something I don't know much about and wanted to.

That's all I can remember right now! I'm looking forward to catching up w/ all the video of the sessions I missed. All in all, a wonderful time, I met some amazing people, and I can see the future of Drupal is bright.

Drupal Boston - First Day, First Impressions

I meant to post this last night but the wifi sucks at the hotel (Royal Sonesta) and I gave up. Here's a recap of my day yesterday, first impressions, general thoughts. Not a whole lot of info on the sessions because I missed a lot of them attempting to get some work done.

This is my first Drupalcon and I've been really looking forward to it for months. So far, I'm mostly star struck. There are a lot of people I know of and recognize from the Drupal community, people I've chatted with on IRC, co-workers I'm meeting for the first time. It's a bit overwhelming, but pretty fun.

My first session of the day was the Usability one which is something I am interested in with Drupal 7. I've been doing some of my own usability testing and hope to publish those results soon. Some interesting tidbits I got away from that session:

  • Content in Drupal is really, really confusing. None of the participants seemed to get it.
  • Taxonomy was not confusing and people understood what it was. Go figure.
  • People use the "Welcome to Drupal...!" screen as navigation, and get really confused when it disappears. This is something I would have never thought about.
  • It's really hilarious to see the quotes of people thrust into the world of Drupal administration. Unfortunately I forgot to write any of the quotes down (but I'm sure there's some transcripts or video).

So that was good. After that was Dries' keynote and it was amazing to see the number of people really here. I am a little sad, to be honest, that I wasn't able to go to a Drupalcon where there were a lot less people. I feel a bit lost in the crowd and am looking forward to some smaller gatherings.

I missed everything after that. Oh, I did make DrupalChix which I just happened to look at the BoF board in time. I think if there were more notice, more women would've made it. Some interesting things about that:

  • There were 17 women there, wow! And I know there was a lot more here at Drupalcon.
  • There was, of course, also a Sprout. Bean joined us later, too.
  • There were women from all sorts of backgrounds, freelance developers, designers, those working for "Drupal shops", those who didn't know much about Drupal.
  • merlinofchaos' wife rocks.

So, yeah. It's been a blast, although pretty exhausting, too. Some other thoughts, in no particular order.

  • When you get beer into Drupallers, things get really interesting.
  • Free coffee goes fast.
  • Having Drupalcon in a freezing city kind of sucks.
  • People are a lot different in person than in real life. People who are curt online I have found friendly in person, people I have talked w/ online have blown me off in person.
  • We need more Drupal paraphernalia.
  • It's hard to talk to the "cool kids" because they are always swarmed by crowds of people. I managed to talk to a few briefly, though.
  • I forgot to charge my camera and couldn't take any pictures. :(

If you're at Drupalcon and reading this, come say hi! I'm friendly, just a bit shy when the number of people is in the thousands.

Drupal Quick Tip #1 - Setting CCK Option Selects to Blank as Default and Required

This took me a little bit of poking around to figure out, so here's a quick tip in case others are attempting to do the same thing.

For some CCK select options, you want it to both be required and to also not default on the first answer because a user might click through without changing the default without meaning to. There is the Default value options you can play with, but the easiest way I've found is in your Allowed values list you can simply enter this as your first choice:


|-Please Choose-

This will give you the -Please Choose- as a default, but if the user doesn't switch it, an error will come up. The reason for this is it's expecting you to have your answer in a format such as 1|Option 1, with the "machine" or "key" name first, followed by a pipe, and then the name of the option a user will see. If you don't give it a machine name it simply isn't valid.

Here's an example of an Allowed values list you might have.


|- Choose City-
la|Los Angeles
sd|San Diego
sf|San Francisco
sb|Santa Barbara

Please note that for normal options you don't have to have the key value at all. This isn't the best way to do this, as it now gives you a value without a key which can be troublesome later.

Alternatively, you could use hook_nodeapi. For example, let's say you add in your CCK field


choose|-Choose-

Now, in a custom module, in this case called "siteconfig", you could add:


function siteconfig_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
if ($node->type == 'custom_content_type') {
switch ($op) {
case 'validate':
if ($node->field_city[0]['value'] == 'choose') {
form_set_error('field_city', 'Invalid choice, please choose a city.');
}
break;
}
}
}
?>

Diving into Drupal E-Commerce: An Ubercart vs. E-commerce Comparison

While I've built oven a dozen Drupal-based websites spanning almost 2 years, my contact with e-commerce within Drupal has been limited. Two of my latest projects brought me face to face with a need for e-commerce, though, and while I toyed with the idea of using ZenCart once again, after installing it and relearning how to work with it, I immediately uninstalled it and turned back to Drupal.

Faced with two choices, Ubercart and the e-Commerce modules, I was left a bit bewildered. Back when Drupal was still in 4.6, I used e-Commerce for a website where users were rewarded with points via the Userpoints module, and with these points were able to purchase items using E-commerce. It worked well but because it was when I was still very new to Drupal, I remembered it being cumbersome, difficult to configure, and just a big headache, and that was without needing an actual merchant account or payment gateway.

NOTE: These evaluations are based on using Drupal 5.2 with eCommerce 3.3 and Ubercart Alpha7b.

So, for all these reasons when an e-commerce site fell into my lap a couple months ago, I chose Ubercart.

Another project came my way shortly after which used a variation of modules that led me to believe e-Commerce was the way to go, plus I wanted to know how well it held up in comparison - so for that project, I chose e-Commerce.

Having worked with both in overlapping time frames these past few months, I've got a pretty good understanding on how each works, the differences between them, the pros and cons as I see them, and community behind them, yadda yadda. And so here we go, let's jump right in -

The Pros and Cons of e-Commerce and Ubercart

E-Commerce

Pros Cons
Endlessly extensible UI is difficult and confusing
More options for contributed modules Requires a lot of theming
Been around the block longer Feels bloated and cumbersome

Ubercart

Pros Cons
More ready to go out of the box Difficult to customize some areas
Lots of jQuery built in Lots of jQuery built in
Vibrant, active community Still in alpha
User interface is awesome Not as many modules available

What's Available

Payment Gateways e-Commerce Ubercart
2Checkout No Yes
Authorize.net Yes Yes
CCard Yes No
CyberSource No Yes
Eurobill Yes No
Eway Yes No
e-xact Yes No
Fast Transact Direct No Yes
Google Checkout Yes No
iTransact Yes No
Moneris No Yes
Ogone PSP No Yes
Paypal Yes Yes
Viaklix No Yes
Wonderpay No Yes
Worldpay Yes No

Additional Functionality e-Commerce Ubercart
File Downloads Yes Yes (separate contrib)
Donations Yes No
Role Grants/Purchases Yes Yes (separate contrib)
Auctions Yes No

To touch on a few points... Ubercart is strong in that is has a much better user interface, makes more sense to someone not very savvy in the ways of Drupal to manage a store, has a lot of built-in, out of the box features that don't require a lot of customization and frustration, including some cool jQuery usage.

On the same token, that also makes it a bit if a pain to customize in some ways, since you have to strip these things out, overwrite them, etc. E-Commerce gives you what you need, but from there you need to mold it into the desired result.

You may also notice I mention jQuery as both a pro and con for Ubercart. I love jQuery. I've been using it more and more and I'm still amazed at how easy it can be. But, like I said, if you don't want these added features, want to customize the way specific things look and behave, you need to strip them out or overwrite them.

The Community

Community and buzz around projects can be incredibly important. The Ubercart community is active on http://ubercart.org. The guys working on the project answer questions quickly, are friendly, and the community feels vibrant. People are jumping in and writing modules which will possibly bring Ubercart's features up to par with e-Commerce, as well. One thing that has always bothered me, though, is when a project has it's own website and, more specifically, has it's own issue queue. I understand the reasoning behind it, but it tends to make things feel disjointed and confusing.

As for e-Commerce, there are some guys working really hard on it and the issue queue moves quickly with issues being fixed daily. e-Commerce 4 has been released in alpha, which is supposed to be a big improvement and sounds very promising. There's often activity in #drupal-ecommerce, and they have opened http://www.drupalecommerce.org as a more centralized place for communications on the project, raising funds, and building a community. The community doesn't feel as strong here, but appears to be growing and is very positive.

So which is better?

Well, I'm still not sure. There may be no solid answer. If you want to get a site up quickly, Ubercart may be the way to go. If you need something highly customized, then e-Commerce may be the way to go. For many, Ubercart has been the answer to all their shopping cart problems. But in the end, I failed to find anything it actually offered that e-Commerce could not do, it just might require some work to get there. Edited: After my original post I came to realize this is not quite true. There are a few things Ubercart offers that e-Commerce does not. Most importantly, as I see it, is a one page checkout. Ubercart has a really nicely done one page checkout, while e-Commerce's leaves much to be desired.

If nothing else, perhaps having them both will give us two strong options for using e-commerce in Drupal. We'll see how well e-Commerce 4 goes, as well as where Ubercart leads us in a final release. And if all else fails, there's always ZenCart.

Just kidding, of course!

jQuery Tabs: Creating "Continue" and "Previous" Buttons

jQuery is neat, and so is the jQuery tabs plugin. This is a method I used to add "continue" and "previous" buttons to some jQuery tabs, essentially giving it a "wizard-like" look and feel. While I am also using a version of the JS Tools tabs module for Drupal, this should hopefully work for the stand-alone plugin, too.

Despite the tabs being assigned anchor IDs, simply trying to skip to the next one only seems to work in Firefox. Let's break this down and say I have a page with 3 tabs. The tabs are named #section-1, #section-2, and #section-3.

In #section-1, I want a "Continue" button going to #section-2. This is the code I add directly to my tabs page at the bottom of #section-1.

I also added some similar links on #section-2 for a previous AND continue button, like so:

Now I need to add some stuff to the tabs javascript file (in my case, tabs.js).


$function() {
$('

Continue').prependTo('#first-continue').find('a').click(
function() {
$('#container').triggerTab(2);
return false;
});
$('

Continue').prependTo('#second-continue').find('a').click(function() {
$('#container').triggerTab(3);
return false;
});
$('

Previous').prependTo('#first-previous').find('a').click(function() {
$('#container').triggerTab(1);
return false;
});
});

Note that container is the main ID of the whole tabs structure. These names are similar to what you'll find at the jQuery tutorial. If you're using the Drupal JS Tools tabs module, you may need to change this to .drupal-tabs.

That's it. Tested in IE6, IE7, Safari3, and Firefox. You can style the look of them to appear more like buttons using the continue class with CSS.

Creating "Groups" Using CCK, Views, Node Profile and Node Reference in Drupal

Being an avid user of CCK and Views, I decided to try essentially creating "groups" using them and the CCK node reference. This isn't going to be a step by step how-to, but more of a general proof of concept.

The modules used in order to achieve this functionality:

The idea here is we're going to create a content type to act as the group's main page. For instance, let's say we create a CCK called "group". We'll have the title of the group and a description.

Now we need to set up nodeprofile. For more info on nodeprofile and how it works, check out the documentation. There's also a great step by step tutorial on creating a nice user profile with the nodeprofile set of modules. Basically, it allows for users to be treated as nodes. So, let's say we create a node called "user profile". We'll have fields like name, location, picture, etc. We'll also add a CCK node reference to this node, and and check "group" as a reference. Set it as a nodeprofile.

Now, when a user is created and their nodeprofile is created, you can choose which "group" content type to reference the user to.

There's lots of things that can be done from here, but let's assume we want to create a list of all the users associated with a specific group. We would create a view called "group_user_list", add the correct Node Reference as an argument, filter it by the nodeprofile content type, and add it to the "group" content type. In my situation, I embedded the view directly in node-group.tpl.php


global $current_view;
$current_view->args[0]=$node->nid;
$view1 = views_get_view('group_user_list');
print (views_build_view('embed', $view1, $current_view->args, false, false));
?>

You can also create other content types to associate with the group. A CCK event type, blogs, etc. Creating views to add them onto the main group page is pretty straight forward. Each content type will need the same node reference field, and when creating the view, use the node reference field as the argument. You will need to add:


$args[0] = arg(1);
?>

in the "Arguments Handling Code" section of the view in order to get things to display properly. Voila, groups without using organic groups!

How To: Creating a Simple Plugin for TinyMCE

UPDATE: This also works with TinyMCE 2.1.1 and Drupal 5.1, but there is some strange behavior with the icons not showing up in Safari 2 and IE6.

I needed a simple plugin for TinyMCE, but it seemed impossible to find any kind of real examples. All that I needed was a custom button, and when that button was clicked, an image to be inserted into the text. No popups, nothing fancy at all. I'm using TinyMCE version 2.0.9 for this, and in the end I integrate it into Drupal 4.7's TinyMCE module. This should work without the Drupal integration, though.

Here's an example of creating such a plugin. We'll just call it icon, to be generic.

First, in your TinyMCE plugins directory, create a new directory and name it icon. You can also start with copying the _template directory if you wanted, but in my version of TinyMCE I don't seem to have one. Inside the "icon" directory, I also have a langs and an images directory.

Back to the icon directory, though. We need to create a file, called editor_plugin.js. Here's what's inside my file:

/**
 * Insert icon plugin
 *
 *
 * @author Brenda Boggs
 * @copyright Copyright © 2007, Brenda Boggs, All rights reserved.
 */
 
tinyMCE.importPluginLanguagePack('icon', 'en');
var TinyMCE_IconPlugin = {

    getInfo : function() {
        return {
            longname :  'Icon',
            author :    'Brenda Boggs',
            authorurl : 'http://alligatorsneeze.com/',
            infourl :   'http://alligatorsneeze.com',
            version :   '0.1'
        };
    },

    initInstance : function(inst) {
        inst.addShortcut('alt', 'u', 'lang_icon_desc', 'mceIcon', false, 1);
    },

    getControlHTML : function(cn) {
        switch (cn) {
            case "icon": return tinyMCE.getButtonHTML(cn, 'lang_icon_desc', '{$pluginurl}/images/icon.gif', 'mceIcon');
        }

        return '';
    },


    execCommand : function(editor_id, element, command, user_interface, value) {
        switch (command) {
            case "mceIcon": 
                    tinyMCE.execInstanceCommand(editor_id, 'mceInsertContent', false, "\"Icon\"");
                    return true;
            }
            return false;
    },
};

tinyMCE.addPlugin("icon", TinyMCE_IconPlugin);

Keep in mind, it's calling the actual image that will show up in the TinyMCE toolbar in one place, and the image that's going to be inserted into the text in another place.

This should work for anything you need quickly inserted besides images, too. Just replace the img code with the text or code you want.

Now that that's done, you need to go into the langs folder and create a file called en.js. This file only consists of these lines:

tinyMCE.addToLang('',{
icon_desc : 'Insert Icon'
});

The image you want to show up as the button within the editor will be placed in the images folder. And voila. Simple plugin created.

I'm certainly no JavaScript guru and this was pieced together by looking at other plugins, so feel free to suggest any improvements.

Drupal Integration

If you're using this with Drupal, you need to add these lines to your plugin_reg.php file near the bottom, but before the 'return $plugins':

$plugins['icon'] = array();
$plugins['icon']['theme_advanced_buttons3'] = array('icon');

You can alternate theme_advanced_buttons3 with theme_advanced_buttoms1 or theme_advanced_buttoms2, which seems to dictate where on the TinyMCE editor bar the button is placed.

Subscribe to RSS - drupal