Learning about Drupal

Over the past six or eight months, I’ve had the pleasure of getting to know Drupal. Coming from a PHP/MySql programming background, I have always been a little apprehensive about using a “mass distributed” framework, since you always hear things like “code bloat” and “how could my site be custom/different using mass distributed framework” etc. etc. After getting over my initial bias to hand coding & stereotype of frameworks, I decided to embrace Drupal.

Admittedly the first week (or two) was painful, the admin interface seemed cumbersome, the concepts seemed way too abstract, but once I “settled in” asked a ton of questions, watched a million video tutorials, I slowly began to see the benefits and the overall power of Drupal.

Drupal isn’t a small pill to swallow, it takes a time commitment to really learn the concepts, getting to know many of the thousands of modules, testing, playing, banging your head, laughing (and a little crying).

Suddenly you realize, hey this is a totally custom site, and I’m using a mass distributed framework…”I’ve been wrong all this time?!” Well wait a second, I couldn’t be wrong, I’m sure there is some dirty secret hid under the hood, let me open up and see how this thing ticks…”What?! this code is clean!!”, So at this point I have to take back all my preconceived notions, ouch. I’ve only been wrong once before ;) .

One of the many cool & powerful things that Drupal can do is the module Views. This module is basically a window into all the fields in the database (and me bing a DB guy), fell in love with the ease of being able to basically write a query, and the interface in one action, being able to preview the results and modify, fine tune, and modify without every having to actually write any code. Don’t get me wrong, I love writing code, but this gives (once you know it) an edge, you can quickly build custom pages, reports, etc quickly and easily. Everything is laid out in front of you and all you have to do, is think it out, configure and test. Views is just one of the thousands of modules available for Drupal, making it easy to plug in new functionality to your site.

The one downside I’ve found with Drupal, is the ability to maintain a code base and track development. For instance, when you hand code you can plug your code into your favorite code repository, dump your database schema, check it in, and you can easily track/modify it’s progression, even with multiple developers. With Drupal this isn’t so simple, since all your configuration is stored as data in the database, and there isn’t really anything that separates what is what, so you can’t simply roll your development site into your production site. You have to recreate the steps that you did on dev on your production environment (and hopefully you remember them all, or you took good notes). There are a couple tools to help, for instance with views you can export the view and import into your production environment, same with panels and some others. But you can’t simply roll it all up (core settings) and be able to successfully merge it into your production environment. Hopefully this problem will be solved soon, then you can have a successful dev, stage, production setup. For small sites where that is not necessary, Drupal is definitely worth considering.

Open Source Gardening

I recently started a garden, for many different reasons. One reason is that I want to be able to eat fresh, chemical free vegetables and share them with my community. The other reason is to show my son the joys of working with the soil and being able to spend quality time with him, showing him what is truly important in life.

Planting a garden brings back many memories of my own childhood. We grew up pretty poor, but even though we didn’t have much money, my mother showed me how to make it work with little or nothing. Being a single mother of 3 she worked full-time (crappy) jobs to bring in ends meat, but aside from that she spent her time planting a garden to help subsidize our food, not only did we have a garden, we had a reasonably sized chicken coop with about 80 chickens for which we had plenty of eggs and sold the remainder at our local farmer’s market.

Looking back this has clearly left an impression on my life, I find it very comforting and relaxing working with the soil, picking weeds, and spending time with my son. Although he’s probably too young to really know what we’re doing, I hope it leaves the lasting impression on him, that it left on me.

Much like open source software which I use on a daily basis, I think of my garden as open source as well, not only because it comes from the earth, it’s totally organic and it’s no secret to anyone what’s in it, but because I plan on providing whatever I sow from it back to the community without charge, there are a lot of people who simply can’t afford fresh vegetables, not only where I’m at but all over the world. Additionally there are so many people buying chemically saturated fruits and vegetables from their local super market and never really knowing what they’re ingesting and the profound effects it has on their lives and the lived of their families.

I’m starting small, but I have large aspirations, and I hope to not only plant the seeds for my garden, but to plant the seed in everyone’s heart to do the same, to give to others, to make it pure, make it clean and to expect nothing in return.

PDG Commerce Ajax Newsletter Signup

To reply to Dak’s question about email marketing integration, I thought it better to take a minute and contribute to the community. Below I’ll outline how to integrate an email marketing application (in this case mailchimp) into your PDG checkout page.

There are a couple pre-requisites:
1)You’ll need a mailchimp API key or Username & Password
2)Your server will need to run PHP
3)A wee bit of knowledge (but not alot)

Here’s a link to mailchimps API: http://www.mailchimp.com/api/    (You probably won’t need to see it, but good to know)

Since we don’t want users to have to open a popup we’ll utilize jquery (javascript) to pass the data directly to mailchimp in the “background” so it doesn’t detract from the checkout process. Jquery comes “default” in PDG version 5, if you’re using an older version I highly recommend using it. It allows you to take PDG to the next level (but that’s another topic).

In this example I’m utilizing some code taken from Mailchimp’s site and written by by Aarron Walter (aarron@buildingfindablewebsites.com), although we are slightly modifying it for our needs

So let’s get down to business… I’m using the “default” checkout template from PDG version 5.

Code from Checkout.html (PDG)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" />
<title>Please Provide Contact, Billing and Shipping Info</title>


<meta name="robots" content="index, follow" />
<script type="text/javascript">
/*this is the code to send the email address to the php if the newsletter checkbox is checked*/
function AddEmail(){
	if($('#email_signup:checked').val() !== null){
		var email = $('#email').val();
		$.ajax({
		   type: "GET",
		   url: "/includes/store-address.php", //adjust this is you don't use an includes folder or want it somewhere else.
		   data: "email_address="+email,
		   success: function(msg){
		   		if(msg != ''){
    		 		alert( msg );
					return false;
				}
   			}
		})
	}
}
</script>
</head>
<body>

!---TOP_NAV---


	<h1>Checkout</h1>
        <br /><br />
        <div id="basket">
	<br /></div>
	<div class="form">
	<form method="post" action="!---SCRIPT_NAME---" id="checkoutform" onsubmit="AddEmail(); return false;">
	<fieldset>
	<legend>Your Information</legend>
	<p>Please provide us with the following information so we may process your
        order promptly.  If any items are missing, we may not be able to process
        your order.  Most importantly, please ensure your email address is correct,
        as this is how we will notify you if any problems occur while processing your
        order.</p>
        <h3>Contact Information</h3>
	<label for="username">name:<input type="text" name="contactname" id="username" value="!---USERNAME---" /></label>
	<label for="email">email:<input type="text" name="contactemail" id="email" value="!---EMAIL---" /></label>
	<label for="company">company:<input type="text" name="company" id="company" value="!---COMPANY_NAME---" /></label>
	<label for="phone">phone:<input type="text" name="phone1" id="phone" value="!---PHONE1---" /></label>
	<h3>Billing Information</h3>
	<p>If paying by credit card, then your billing name should match the name
        on the credit card and your billing address should match your credit card's
	billing address.</p>
	<label for="billfirstname">first name:<input type="text" name="billfirstname" id="billfirstname" value="!---BILL_FIRST_NAME---" /></label>
	<label for="billlastname">last name:<input type="text" name="billlastname" id="billlastname" value="!---BILL_LAST_NAME---" /></label>
	<label for="billstreet1">address line 1:<input type="text" name="billstreet1" id="billstreet1" value="!---BILL_STREET1---" /></label>
	<label for="billstreet2">address line 2:<input type="text" name="billstreet2" id="billstreet2" value="!---BILL_STREET2---" /></label>
	<label for="billcity">city:<input type="text" name="billcity" id="billcity" value="!---BILL_CITY---" /></label>
	<label for="billstate">state (US/Canada):</label>
	<label for="billprovince">other (international):<input type="text" name="billprovince" id="billprovince" value="!---BILL_PROVINCE---" /></label>
	<label for="billzip">zip code:<input type="text" name="billzip" id="billzip" value="!---BILL_ZIP---" /></label>
	<label for="billcountry">Country:</label>
	<label for="billtext">billing comment:<input type="text" name="billtext" id="billtext" value="!---BILL_TEXT---" /></label>
        <h3>Shipping Information</h3>
	<label for="shipmethod">ship via:</label>
	<label for="shipdestination">ship to</label>
	<label for="shipname">name:<input type="text" name="shipname" id="shipname" value="!---SHIP_NAME---" /></label>
	<label for="shipstreet1">address line 1:<input type="text" name="shipstreet1" id="shipstreet1" value="!---SHIP_STREET1---" /></label>
	<label for="shipstreet2">address line 2:<input type="text" name="shipstreet2" id="shipstreet2" value="!---SHIP_STREET2---" /></label>
	<label for="shipcity">city:<input type="text" name="shipcity" id="shipcity" value="!---SHIP_CITY---" /></label>
	<label for="shipstate">state (US/Canada):</label>
	<label for="shipprovince">other (international):<input type="text" name="shipprovince" id="shipprovince" value="!---SHIP_PROVINCE---" /></label>
	<label for="shipzip">zip code:<input type="text" name="shipzip" id="shipzip" value="!---SHIP_ZIP---" /></label>
	<label for="shipcountry">country:</label>
	<label for="shiptext">shipping comment:<input type="text" name="shiptext" id="shiptext" value="!---REG_SHIP_TEXT---" /></label>
	<p><input type="checkbox" name="EmailSignup" id="email_signup" /></p>
	<div id="inputsubmit"></div>
	</fieldset>
	</form>
	</div>


!---BOTTOM_NAV---

</body>
</html>

This is the PHP that the ajax is sending to: store-address.php

<?php
/*///////////////////////////////////////////////////////////////////////
Part of the code from the book
Building Findable Websites: Web Standards, SEO, and Beyond
by Aarron Walter (aarron@buildingfindablewebsites.com)
http://buildingfindablewebsites.com

Distrbuted under Creative Commons license
http://creativecommons.org/licenses/by-sa/3.0/us/
///////////////////////////////////////////////////////////////////////*/

function storeAddress(){

// Validation
if(!$_GET['email_address']){ echo "No email address provided"; }

if(!preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*$/i", $_GET['email_address'])) {
echo "Email address is invalid";
}

require_once('MCAPI.class.php');
// grab an API Key from http://admin.mailchimp.com/account/api/
$api = new MCAPI('your_apikey');

// grab your List's Unique Id by going to http://admin.mailchimp.com/lists/
// Click the "settings" link for the list - the Unique Id is at the bottom of that page.
$list_id = "my_list_unique_id";

if($api->listSubscribe($list_id, $_GET['email_address'], '') === true) {
// It worked!
echo 'Success! Check your email to confirm sign up.';
}else{
// An error ocurred, return error message
echo 'Error: ' . $api->errorMessage;
}

}

// we're calling it with Ajax so we just want the function to be ran
echo storeAddress();
?>

You’ll also need the .php class (MCAPI.class.php), I’ve packaged this all together neatly for download here: http://www.aaronniemi.com/pdg-newsletter-ajax.zip
I prefer to keep my “code” in an includes folder, so this is how I’ve packaged it, if you keep your code somewhere else you’ll need to adjust some paths.
Also note that I haven’t ran this code, so if you notice a bug please let me know and as usual I’ll be glad to help fix it and I’ll update the tutorial. Another note, unfortunately worpress hoses my formatting (I’m looking for a good code format plugin if you want to suggest one). So I’d just work from the .zip file.

Thanks
-Aaron

Simple Pleasures

I’m a self-admitted workaholic (I know, who isn’t right?). My wife has always told me, pleaded with me, tried to pound into my head, that life is the journey not the destination. Which until recently I thought “well if you want to eat along the this journey I need to work ALOT more”. But then I had an epiphany, and once again I realized that my wife is (as usual) correct.

What help me come to this epiphany was the loss of my job which I loved and I often feared the day that I might not have it. There had been times in the past that we were told that the outlook didn’t look that great and to be “prepared” so I had been living in this place of uncertainty for quite awhile. Then the day came and I was told that the company could no longer afford to keep me. Strangely, a sense of calm came over me, almost relief… I got laid off, but I didn’t die, my wife still loves me, my son still smiles at me… life continued regardless of my employment status.

With this I realized that jobs/work/bosses/experiences etc, come and go, but the truly important things (Family, Friends, Memories) are everlasting. While I continue to look for my next great opportunity, I hope that I can keep in the front of my mind that if you invest only in work and one day it’s gone, you’ll have nothing to show for it, so you need to take the time to invest in yourself, your family and your friends, because when the job is gone, you’ll still have a strong foundation based on the love of the ones closest to you.

Internet Employment Options & Opportunities

If you’ve recently decided that you’re going to make a living off the internet, you’re probably inundated with all the options you have. In my own research I have found there are lots of opportunities out there for eager and self-driven people, but there are just as many scams for the people who are looking for “get rich quick” opportunities as well.

One thing I truly believe: “You’ll only succeed if you’re passionate about what you’re doing.” The reason I believe this is simple, if you’re not passionate about what your doing, you will only put lackluster energy into it, and therefore that is all you’ll get out of it (no matter what “it” is). If you part hard-work and enjoyment into it, you’ll get great rewards and enjoyment out of it.

So what have you got to offer? You don’t have to be a web-developer to make money on the internet, you don’t have to even have something to sell on ebay. The beauty of the internet is, you don’t even have to have products. One method to make income on the internet, which has taken off is blogging. I can hear you asking, how do you expect to make money off writing stuff? It’s simple really, let’s pretend I’m really into snowboarding (which I am), so I get a blog setup to write about all the awesome places I’ve shredded, and I write about all the sweet gear I bought and why it’s the best and why I love it so much. After awhile I have quite a few post’s talking about my passion, sooner or later other people surfing the internet come across your blog that tells all about snowboarding and all your awesome gear, they read your post and think “man I wish I had a sweet snowboard like theirs”, this is where the monetization part comes in… After you’ve written a few posts, you need to start signing up for affiliate services, there are tons out there and they pay different rates (so do some research), once you’ve picked your affiliates (ones that fit your blog subject), then as you write about your awesome Sims Snowboard, you link the words “Sims Snowboard” to the site (your affilate) who sells that board. So when your reader clicks the link and buys that snowboard you automatically get a commission.

So what’s the catch? There isn’t a catch, however I wouldn’t expect to get rich off one Blog about snowboarding, the key is to not only have one blog about snowboarding the key is to have a blog about every thing you’re passionate, experienced, or expert in. If you know something better than most, then there is an opportunity to be had. BUT, you have to be consistent, you have to add to your Blog(s) regularly, you can’t expect a post from 6months ago to keep driving traffic.

The only thing that limits you is you’re imagination, there are literally millions of ways to make money on the internet, many people sell things on Ebay, others open up E-Commerce sites, some create directories of other sites (affiliates) in hopes you’ll click a link and buy something someone else is selling. You can even get paid to simply link to other people’s sites (one-way linking). Whatever ideas you come up with, make sure you do you’re research, there is probably a good chance someone is doing it already, so learn from them. There is an ancient Chinese proverb that says: “A fool learns from his own mistakes, A wise man learns from the mistakes of others”.

PDG Commerce a love story…

Well it’s more like one of those dysfunctional relationships, most of the dysfunction comes from PDG, but once you can get past some of the irritating “gotcha’s” and idiosyncrasies you can look deep inside and see it’s true potential.

I’ve had my hands in quite a few PDG installations and I think I have pushed the envelope. PDG gives you enough flexibility to be able to create some pretty cool custom solutions. I’ve built front end applications that let you basically “build” an item, I’ve created ajax scripts that let you add items to your cart without leaving the page. Coupling JQuery with PDG can provide some really cool functionality. I don’t think there has been a problem yet that we haven’t been able to create a solution for. (actually I can think of 1, involving product options and PayPal).

The only other “drawbacks” that I’m not really stoked about is, it’s not open source (compiled cgi) and you can’t use php files for the templates, (and it’s not writen in php), support while excellent, you have to maintain a contract. And of course it’s not FREE as in beer. (which is a bummer considering the Pro version is $999)

Some things to keep in mind… I think the major draw to this web application is it’s QuickBooks integration, however I’ve never really had much to do with that end. It does support a wide variety of credit card gateways, which was nice since that is usually a pitfall for open source applications. I mentioned before their support is awesome, they’ve always been helpful, over the years I’ve had to call them less & less except for the occasional “issue” where we need to make magic happen, in which case their developer’s have addressed issues relatively quickly.

I think I’ve had my hands in most open source, hosted and “other” shopping cart applications and while getting to know PDG over the last 5 years, I can say we’ve had our up’s and down’s but overall it’s been a good ride.

Once version 5 gets some of the bugs shaken out, I’m sure I’ll be giving it a good test run.

SEO From the Start

I’m one of the believer’s that if you coded your site correctly, you’ve spent the time researching your market, & you’ve written good content, then your site is probably in pretty good shape search engine wise, with a few simple additions like SEO friendly URL’s and maybe some well written, meta tags you’ll be on your way to a better  page rank in no time.

Text is king when it comes to search engine optimization, it’s great to have fancy ajax & javacript, but always make sure you can still operate your site as if you were a spider, with no javascript. Google’s webmaster tools, now offers a feature that lets you view your site like their crawler, so you can see exactly what the googlebot see’s when it’s scanning your site. Pay close attention to what your using as anchor text, if you have 20 “read more’s” in a page, you might want to come up with a way to optimize the link, like “read more about keyword”.

Proper use of heading tags is also important, your pages should be using H1’s, H2’s or H3’s and p tags, I know this sounds elementary but if you look around the web a lot of sites are simple throwing standards out the window. What ultimately increases your rank is how many people actually use and reference your site, so that means your content needs to have some value, something that draws visitors to your site. If you’re selling some rare product or service this is easy, however when your trying to sell the same widget everyone else is, you have to be more creative with your content and keywords to compete.

Once you come up with your list of keywords and terms you want to market your site to, it’s easy to start plugging in those keywords and terms into your content, but make sure you’re not overusing keywords, this practice is called keyword spamming and it will hurt your page rank, and also make sure your content is still human readable, because after all your site is for humans and not bots alone.

Doing simple things every day to improve your site will pay off big in the long run. Google has a new tool called Website Optimizer that lets you test changes to your site so you can really see if adding those security logos or changing the button color effects visitor trends. You’d be very surprised how a very small change can affect conversion rate greatly. If nothing else, follow the leaders, Amazon clearly thinks checkout buttons should be orange and a specific size and a specific font, and I’d be willing to bet they spent a lot of money testing it. But now it’s relatively simple to test it out on your own site.

I Fell in love with JQuery

If you’ve ever used Javascript for interfaces or for anything for that matter then it will be easy for you to fall in love with JQuery. I find it to be the most simple and elegant javascript framework around, and since it’s being adapted into other systems (like mobile phones) it’s sure to stick around for awhile.

The best part about it is you simply have to type less, hence the slogan “The Write Less, Do More, Javascript Library”. Here’s a sample of what I’m talking about:

Standard Javascript:
document.getElementById('div_id').innnerHTML = 'Add some content';

JQuery
$('#div_id').html('Add some content');

That by itself is almost half the keystrokes. We’re not even mentioning the fact that JQuery and JQuery UI have A TON of built in functions as well as a huge amount of contributed modules to quickly and easily spice up your site bringing it into 2.0 with a some quick JQuery additions.

A little about me…

I have  a beautiful family and I enjoy spending time with them. My wife’s name is Lidia, she is an amazing & beautiful Brazilian woman, who has taught me the value of true passion. Together we have a the most adorable son, his name is Malakai, he brightens up every day with his beautiful smile and his playful & loving personality.

I think of myself as a “down to earth” person, I believe in true justice, peace. I’m earth conscious and have a strong faith in god.  I grew up on Vashon Island and have always lived in Washington state.  I love being outdoors and enjoy camping, mountain biking, snowboarding…and just about everything else outside.

My wife inspires me to achieve greatness and truly believes the only limits we have are self-imposed. She understands that “Failing to Plan is Planning to Fail” and she helps steer the ship while I’m in the engine room. I think we make a good team, and I think Malakai is lucky to have such cool parents (of course!). Our adventure is only a couple years in the making and we have great plans in store!