Archive for April, 2010

Facebook, OAuth, & Open Socialism (a rebuttal)

Posted on: April 23rd, 2010 by Mike

Here at Purple, we’ve been trading emails back and forth the past few days about the announcements at F8 regarding Facebook’s adoption of Open Social, as well as what it means for the future of the internet (I’m too busy to link any of this, go Google it). Today’s emails focused on Chris Messina’s blog post.

I’m not sold on his rant. Below is a quick synopsis of my personal (and contrasting) opinions on his post.

As a disclaimer, I have no beef with Chris Messina, and according to others I may be apathetic and offensive when it comes to the Open web. I’m sure plenty of other open-advocate developers out there will readily disagree with me. I may be the only one in the internet who thinks this way, so IMO it’s worth sharing.

In bold are pull-quotes from Chris’ article, with my personal opinions below (if you missed it, it’s probably worth reading his blog first)

…Oh, and anyone that wanted to be part of the Google index, well they’d have to add additional metadata to their pages so that the content graph would be spic and span…

We actually do that already, and it’s what half of our marketing business is based on. Well-researched Titles, Keywords, and Descriptions are intended to help index content and determine what any given web page is about.

…Except — shucks — there’s one problem with this model: it’s evil…

It’s not evil, at least not any more evil compared to any other business model. It’s obviously a sound idea for Facebook to seek realistic ways to monetize a web product that’s been free to end-users since day one. No one twists anyone’s arm to sign up for Facebook. Since a huge portion of the world is already connected on Facebook (rather than through only basic open protocol) it just makes sense to use this as a gateway for social graphing and (realistically) connecting trends and data.

…When all likes lead to Facebook, and liking requires a Facebook account, and Facebook gets to hoard all of the metadata and likes around the interactions between people and content, it depletes the ecosystem of potential and chaos — those attributes which make the technology industry so interesting and competitive

Just like Google hoards page rank so Yahoo and Bing are screwed? No. Google is just more widely adopted, but it has its competitors. When the (global) feds need to step in and regulate an unchecked Facebook monopoly, they will. Until then, there should be no impediment to progress.

…(and not just because that provider becomes a single point of failure)….

This late in the game, this is only analogous in the same sense that a catastrophic volcano would be a “single point of failure” for humanity. If the service is widely distributed (which Facebook is) and widely adopted (which…Facebook is), it won’t be an indefinite point of failure. Facebook is larger than many tangible nations on the face of this earth, in terms of both population and revenue.

As I and others have said before, your identity is too important to be owned by any one company.

If it’s open protocol, then it’s shared. It may be tangibly “owned” by Facebook, but that depends on your definition of ownership. At some point, everyone will have access. The only thing regulated on Facebook is their advertising platform that harvests this information, but that really doesn’t make them any different from Apple with their iPhone and iPad market, does it?

Thus I’m looking forward to what efforts like OpenLike might do to tip back the scales, and bring the potential and value of such simple and meaningful interactions to other social identity providers across the web.

The blind scales of some internet justice system? OpenLike, while egalitarian and altruistic in nature, will fall by the unchecked wayside because (chances are) the majority of humanity will not find an inherit interest in it. We as developers forget that for most citizens, everyone’s family linkage, photo albums, birthdate reminders, and favorite things are all uploaded and connected through Facebook. As useless as our development community seems to think it is, people still use it. It’s a slim chance that anyone outside of the “open web community” wants to be burdened with a clone feature that holds no inherit value to their personal lives, lives that are already catastrophically being consumed by this social media behemoth.

I’ve mentioned this in passing to some and I’ll mention it here: when both Facebook and world governments are linked through an open standard, your government will have unchecked access to your online identity, your wants, your “likes”, your ideas, your medical records (ahem, government regulations on health care) and all of your distributable digital content.

You think things are weird now? I can’t wait to see it in two years, you know, around 2012. Maybe it’s my totalitarian Roman heritage, but I for one welcome our new Facebook overlords. OpenSocialism is a wave that can only be ridden.

Magento Therapy: Overriding Core Magento Files

Posted on: April 19th, 2010 by Rob Zienert 3 Comments

Let’s pretend your Magento store needs to modify core functionality offered inside of the app/code/core/ folder. I’d have to smack you if you went modifying those files directly as it wrecks your ability to easily maintain changes throughout upgrades. Fortunately, Varien was good enough to know that the way they developed Magento isn’t the way everyone may need it to work. Barely on the surface, you have three code folders: community, core and local. In this post, I’ll be reviewing how to rewrite and extend those classes inside of the core folder.

Extending Core Classes

As mentioned in my Multi-Store and Internationalization post, PRPL adopted an inverse Translate method that fetches from translate.csv files before those located in app/locale/. In order to do so, we needed to make this change global while keeping the scope of impact as minimal as possible.

Magento manages their dependency injection through the XML configuration files. When you want to rewrite a class, you can tell Magento to look elsewhere from where it normally would.

Inside of app/code/local/, we have a namespaced folder called Prpl, which is where we’ll be putting any of our custom code1. Place the following code inside of app/code/local/Prpl/Core/etc/config.xml:

<?xml version="1.0"?>
<config>
    <modules>
        <Prpl_Core>
            <version>0.1.0</version>
        </Prpl_Core>
    </modules>
    <global>
        <models>
            <core>
                <rewrite>
                    <translate>Prpl_Core_Model_Translate</translate>
                </rewrite>
            </core>
        </models>
    </global>
</config>

It should be pretty obvious what’s going on here: We’re telling Magento to rewrite the “core/translate” model to our class. The cool part about overriding Magento classes in this way is that we can extend them2. Now to create the class, Prpl_Core_Model_Translate, with the following contents:

class Prpl_Core_Model_Translate extends Mage_Core_Model_Translate
{
    /**
     * Reverses the priority of translations to check translate.csv first, and
     * then the locale packages second -- the way it should be.
     *
     * @param text $text
     * @param text $code
     * @return text
     */
    protected function _getTranslatedString($text, $code)
    {
        $translated = '';

        if (array_key_exists($text, $this->getData())) {
            $translated = $this->_data[$text];
        } elseif (array_key_exists($code, $this->getData())) {
            $translated = $this->_data[$code];
        } else {
            $translated = $text;
        }
        return $translated;
    }
}

Enabling Your Namespace

Lastly, lets not forget to enable your new module. We prefer using a module xml file called Prpl_All.xml, which is placed at app/etc/modules/. The basic contents would look like this:

<?xml version="1.0"?>
<config>
    <modules>
        <Prpl_Core>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Mage_Core />
            </depends>
        </Prpl_Core>
    </modules>
</config>

After that, you should be all wrapped up and ready to go. If caching is enabled, you’ll likely have to clean it out.

Magentoisms

Today I was working on a new module for one of our clients for some enhanced inter-product support functionality. Since it’s largely focused towards live search functionality, I figured I would piggyback some of the CatalogSearch functionality to reduce duplicate code.

In doing so, I ran into a small roadblock in that it appears overwriting controllers isn’t as auto-awesome in Magento as with models and other classes. I didn’t investigate far into the “why”, but the Magento autoloader wasn’t playing nicely.

The point I’m making with this is that little things like this are bound to crop up and they’re hurdles you simply have to expect. Keep special attention on the XML files: they have been known to be sensitive to whitespace. When this happens, Magento doesn’t give you any considerably useful errors. *face palm*

Foot Notes

  • 1 If you’re creating a namespace for your company to be placed in multiple client projects, I would recommend plopping it in the community folder. I prefer having the ability to have a common code base that we can then extend further in local for the client if necessary.
  • 2 The other method of rewriting Magento classes, which I don’t recommend, is to copy the entire contents of the class you want to overwrite into the local folder and put it inside of a mirror file (e.g. Mage/Core/Model/Translate.php). Doing it this way totally blows for two primary reasons: 1) you need to maintain more code and 2) if Varien updates Magento, see point 1. This is the method I used prior to discovering XML rewrites… those were dark, dark days. It’s a total pain in the ass and wreaks of code smell. I can’t think of any particularly enticing reasons to use this approach.

Experience Toggles (aka Just Another Crazy Idea)

Posted on: April 16th, 2010 by Justin

Recently while browsing some of my favorite news sites I came across the redesigned Reuters.com and noticed an interesting feature: the “Now View”. It allows the user to toggle how the news is presented based on preset options. For example, if the site visitor is interested in viewing headlines based on location, there’s the “Newsmap View”. If he is more interested in photography he can choose to view the same headlines, but with photography serving as the lead content. Same concept can be applied to the “Video View” and “Headline View”. This isn’t revolutionary functionality by any means, but the underlying concept — presenting a website differently based upon a user’s mindset and preference — can be extended further and offers several intriguing possibilities.

Imagine visiting ESPN.com and being able to choose a “Team View” from a header-based toggle, where you’ve already set your favorite teams in your account profile. Suddenly, the entire website shifts to be about your teams. The site structure remains the same in this instance, but the content, and maybe even navigation, changes to only cover topics and teams you wish to read about. Or if you visit a news website and you’re really only interested in the Middle East at that very moment, you could choose “Middle East” as an “experience toggle” which would shift the content of the entire site to meet that mindset and content need. The site visitor in turn feels engaged and fully in control of the experience, leading to increased overall satisfaction (in theory). In a way, the site visitor is creating a customized magazine just for himself.

“Uh, why not just click on ‘Middle East’ in the navigation in that last example?”, you ask. I’m not a fan of your tone, but excellent question. The value here, at least in my view, is that this would eliminate a lot of informational and visual noise. The website becomes laser-focused, completely subservient to the user’s mindset and goals, and hides any content not related to the user’s current aim. It’s not dissimilar to a news website’s mobile experience versus its desktop counterpart — you get just the facts on the mobile platform, clear of distraction. With the desktop version you get the facts, but you also get a ton of other content that you may or may not find interesting. The content switch could be handled dynamically, and switching back to a standard view for passive exploration would be as simple as a click.

There are obviously a lot of holes in this idea, and it’s not something I’ve put a ton of thought into just yet, but any way to provide the site visitor more control over the on-site experience and increase engagement is worth further discussion. Would love to hear your thoughts!

Magento Therapy: Multi-Stores and Internationalization

Posted on: April 16th, 2010 by Rob Zienert 1 Comment

This is part of the Magento Therapy blog series.

Before I get started, Crucial Web has an extremely helpful tutorial on how to setup multiple Magento stores. They provide many different avenues to get the job done and they’re all pretty relevant, but we opt for a hybrid method which we’ll go over shortly.

As noted in the Crucial Web article, setting up multi-stores in Magento through the admin is only half of the solution. The rest has you getting a little dirty in the code with switch statements and whatever else. Not a big deal, I prefer that it’s a partially implemented solution because you can fit it to your needs instead of being shackled down.

Multi-Stores

Through popular demand from our larger clients, we’ve globally adopted a url structure as follows: "http://COUNTRY.domain.com/LANGUAGE/". We chose this method to accomodate countries with potentially more than one language, for example a Canadian site would probably have English and French versions. This is the format that quite a few large E-Commerce companies use, so we followed suit.

For this post, we’ll be using Canada as our new multi-store. Canada is a great choice because I love hockey and it allows us to address a hybrid subdomain- / subdirectory-based multi-store.

Setting Up the Stores in Magento

I’ll breeze over this portion really fast, as it’s very well explained at Crucial Web. You’ll want to create the following from the System -> Manage Stores page:

  • A Website named "Canada Website" (code: canada)
  • A Store named "Canada"
  • Two Store View Names: "Canada EN", "Canada FR". (codes canada_en and canada_fr, respectively)

Modifying Magneto Store paths

Now that the stores are setup, you’ll need to get your paths in order. This is done inside of the Web tab in Configuration.

The Base URLs will be "http://ca.magento.local". You can make this global to all Canada Stores by modifying the setting at the Website level. You’ll then want to go into each Store configuration individually and set the Base Link URL to:

  • "{{unsecure_base_url}}en/" and "{{secure_base_url}}en/"
  • "{{unsecure_base_url}}fr/" and "{{secure_base_url}}fr/"

We’ll get to the design tab later.

Modifying the Magento index.php file

I’m not a particular fan of how Crucial Web tells you to copy/paste .htaccess files and index.php files around for the subdirectories to work. Instead, I prefer to modify the original index.php file so that I can just require it in the subdirectories:

First, lets just setup the subdirectories. We’ll need a "fr" and "en" directory on the root. Inside, we’ll have a very simple index.php file:

// en/index.php, fr/index.php
require_once dirname(__FILE__) . '/../index.php';

That’s it. Unfortunately, Magento doesn’t play nicely with a setup like this, so we need to edit their index.php file. Where ever a file is included into the index.php file, we need to add dirname(__FILE__) before it. Like so…

// index.php
$compilerConfig = dirname(__FILE__) . '/includes/config.php';
$mageFilename = dirname(__FILE__) . '/app/Mage.php';

I’ve also created a function to help handle the language subdirectories. I just throw this in right above the Mage::run() code at the bottom of the file.

function mageLangSubdir(array $storeCodes, $default) {
    $code = $default;

    preg_match('#^/([a-zA-Z]{2})/?#', $_SERVER['REQUEST_URI'], $matches);
    if (count($matches) > 0) {
        $matches[1] = strtolower($matches[1]);
        if (array_key_exists($matches[1], $storeCodes)) {
            $code = $storeCodes[$matches[1]];
        }
    }

    return $code;
}

It’s not glamourous by any means, but it does get the job done. It pulls out the "/fr/" or "/en/" portion the request URI and will match it against acceptable codes (provided in a moment). If no matches are found, it goes to the default.

Now the bootstrapping. As you add more sites, this switch statement grows.

// Enable multi-site support
switch ($_SERVER['HTTP_HOST']) {
    case 'ca.magento.local':
        $codes = array(
            'en' => 'canada_en',
            'fr' => 'canada_fr',
        );
        $store = mageLangSubdir($codes, 'canada_en');
        Mage::run($store, 'store');
        break;

    case 'magento.local':
    default:
        Mage::run();
}

As you can see, we’re using the switch statement to determine the website, but then parse the request URI with the function above to route us to the correct store.

If you’ve setup everything properly, you should now be able to navigate to your websites. Depending on your setup, you may get 404 pages regarding your homepage. At this point, it’s just a matter of creating site content.

International Themes

In all likelihood, your client will want the same design across all your Magento Stores. I’m all for that. It’s cheaper for the client, a lot easier to manage and brings cohesion to the client brand across all sites. Fortunately, in all of Varien’s wisdom, Magento knows you want to do this and gives you the tools to easily make it happen.

We’ve adopted using a parent theme called, "intl" for our international sites (or at least for the left-to-right languages). No store directly uses this theme, but instead, all of our international themes fallback (default) to this theme. So for example, our English Canada site will have a Themes tab that looks like this:

We’ve adopted the naming convention of "clientname_country_LOCALE" so it’s easy for us to navigate around the themes directory. You can name your themes whatever you please, but we tend to stick to conventions where possible just to make things more predictable.

Your goal in using the intl theme is to make it as reusable as possible so that any files inside of "magento_en_CA" are few in number. We sometimes have a completely empty folder except for perhaps a different newsletter signup callout that submits to a different destination. Everything else falls back to the intl theme.

Unfortunately, life isn’t so wonderful going to the skins folder for the theme. Right now, we have to copy/paste the entire directory for each theme. It’s terrible. It’s depressing. It’s a massive waste of an initial 30 seconds and an unquantifiable increase in maintenance time. It’s something we have been meaning to build onto Magento, but haven’t had the time. So changes to say, the CSS file or custom Javascript will have to be duplicated. Too bad. Your only saving grace is possibly using symlinks, but when files start getting theme-specific changes you’re out of luck.

Translations

The last thing is that we keep our translations inside of the intl theme’s translate.csv files. Of course, we use the translation files in app/locale where applicable, but any custom translations we keep in the theme folder. Just general preference, but it came at the small cost of overriding Mage_Core_Model_Translate::_getTranslatedString().

We found that the files inside of app/locale were getting precedence over the theme translate.csv files. This probably makes a whole lot of sense and works great for some people, but our workflow doesn’t accomodate too well structured like this.

We’ll be going over overriding core Magento classes in a different blog post, but it was simply a matter of checking for the $text instead of $code first:

class Prpl_Core_Model_Translate extends Mage_Core_Model_Translate
{
    /**
     * Reverses the priority of translations to check translate.csv first, and
     * then the locale packages second.
     *
     * @param text $text
     * @param text $code
     * @return text
     */
    protected function _getTranslatedString($text, $code)
    {
        $translated = '';

        if (array_key_exists($text, $this->getData())) {
            $translated = $this->_data[$text];
        } elseif (array_key_exists($code, $this->getData())) {
            $translated = $this->_data[$code];
        } else {
            $translated = $text;
        }
        return $translated;
    }
}

I’m not a personal fan of using their inline translation editor. It’s a fantastic tool don’t get me wrong, but I don’t really like that it saves to the database… nor that it takes longer to get things done. It’s easy to parse a content inventory spreadsheet to generate translate CSV’s, it’s another thing to surf a website changing strings manually only to not have it in version control.

Wrap Up

That’s about it. If you wanted to do something more fancy with multi-stores, it certainly wouldn’t be difficult to add in GeoIP functionality for automatically selecting stores based on a visitor’s location and so-on.

If you’d like to read more about setting up multiple stores in Magento, I’d suggest checking out the multi-store knowledge base at MagentoCommerce.com.

Amazon Series: Leveraging Amazon Web Services for Practical Scalable Applications (Part 1)

Posted on: April 16th, 2010 by Chris

So I recently just finished a project here at Purple, Rock, Scissors. Web Design and Development Firm / Digital Agency in Orlando, FL.  It was the first time we were asked to provide a quick setup and a low cost solution for scalable web hosting.  Instantly, Amazon EC2 with Elastic Load Balancing came to mind.  I find that many IT professionals have a strange fear of "Cloud Hosting".  This isn’t all that uncommon though.  Many IT Pro’s fear the unknown and choose to bash it rather than embrace technological advances.  

Before anyone bashes me though for being an obsessed "fanboy", I do not always utilize AWS or other Cloud Providers.  While cloud hosting has many advantages, it is certainly not for everyone.  Every client has different needs and therefore AWS does not get recommended to all of them.  Most clients who request help with hosting still get directed into a traditional hosting plan with our favorite provider Peer1.  They have datacenters all over the US and have the flexibility to meet most of our clients’ needs.  It also gives the flexibility to upgrade / downgrade to meet the ever-changing needs of our clients.  

We actually used ourselves as a test case starting last year.  We run both our Zimbra mail server and our Drupal website on a single small instance for about $80 / month.  That is a pretty good pricepoint for the amount of use we get out of the server.  The only caveat to running mail on AWS is that they don’t provide reverse DNS entries, which means that you need to use a 3rd party SMTP service such as AuthSMTP.  For us, this works out to an additional $160 / year, which still makes it more economical at a total cost of $1120 / year.  This is roughly 20% of what we used to pay in a traditional hosting model.  Not only that, but should we need additional capacity, we can simply turn off our server, request the next largest size instance, and be up and running again in under 20 minutes.  

However, in our use…we are using a single Amazon EC2 small instance.  Setting up a load balanced environment is a whole different ballgame that we got to experience.  Let’s dive in and look at setting up a sucessful load balanced environment utilitizing Amazon Web Services. 

Step 1

First, go ahead and sign up for an account at http://aws.amazon.com.  If you already have an Amazon account for buying things on Amazon, the same exact account can be used…you just need to enable web services.  Once you have that set up, go ahead and grab your X.509 certificate, Access Key and Secret Access key from the "Security Credentials" section of your account. 

Step 2

There are many admin panels available for Amazon.  I recommend using the AWS Management Console in EC2 mode.  This is available directly from the AWS site.  If you only need basic EC2 functionality, you can download ElasticFox for managing EC2 and S3Fox for managing S3 buckets directly from Firefox. I still recommend the Amazon panel though, as you can log into the interface without special Firefox plugins.

Once you are in the admin panel, you will see an interface similar to this:

The image above shows off the AWS Admin Panel.  It gives us a heads up display of all the things that are currently in use in our account.  Let’s take a few mins to explain each of the sidebar elements:

  • Instances
    An instance is an amazon machine image or "AMI" which has some current runstate.  It could be Pending Deployment, Running, Shut Down, Restarting, or Terminated.  EC2 instances come in many different sizes, the smallest of which costs 8.5 cents / compute hour (Essentially $61.20 / month for a constant duty machine based on 24 hrs / day for 30 days).  Reserved instances may also be purchased for a lower cost.  This reduces the hourly rate to roughly 3-3.5 cents / compute hour with a $300 up front commitment.  Most of the lower instances will be created with a 15 GB hard drive by default.  You can increase or decrease the size of the main volume during setup.
     
  • Spot Instances
    A spot instance is an on demand instance for which you pay minimally based on the fact that they are limited to availability. 
     
  • AMIs
    An AMI or Amazon Machine Instance is a bundled image which can be selected under the instance panel for deployment.  If you have ever used VMWare, think of this like a virtual machine which is in the off state, except you can start up many instances of a single AMI.
     
  • Bundle Tasks
    This panel does not get used as much as it used to.  When you are creating a custom AMI of an image with a local storage drive built into it, this panel will show you if you have a running bundle task against that instance.
     
  • Volumes
    Over the past year, Amazon has move away from using local storage within the instance.  Now they allow you to use an elastic block store "EBS" volume and attach it to an AMI.  You can also attach additional EBS volumes to an instance for additional storage.  A volume though can only be attached to a single instance at once.
     
  •  Snapshots
    A snapshot is similar to snapshotting within VMWare.  It allows you to choose a moment in time and backup the entire contents of a volume.  This can be used to run manual backups, but it is also a natural part of creating a custom AMI of a running instance.  During the snapshot process for custom AMI’s the instance is shut down, the hard drive is snapshotted and bundled with the bootstrap data required to start an instance.
     
  • Elastic IPs
    By default, instances are considered ephemeral. Restarting and bundling are the only two states through which your internal IP and external IP address will stay reserved to your instance.  If you terminate an instance, it’s IP address is thrown back into a pool and you are assigned a new one.  If you don’t want to lose your IP and be stuck updating DNS records (assuming you are using the server in a production environment), you can purchase an elastic IP which will ensure that you are always guaranteed the same IP…you even have the ability to assign it to a different AMI.
     
  • Security Groups
    By default, all ports are closed.  To get around this, you must create a security group which has all the appropriate ports opened so that you can access appropriate services on your server.  For example, a linux server should (at minimum) have port 22 open or whatever port you decide to run SSH on.  It would probably have port 80 open for serving up http requests.
     
  • Key Pairs
    A keypair is used during the bootstrapping of your instance.  When it starts up, password authentication will always be turned off by default.  This means that you need to have a key on file in the system so that you can use it to login to your instance once it is fully deployed.
     
  • Load Balancers
    One of the great features of AWS, is that it provides what Amazon calls an "Elastic Load Balancer".  ELB’s are easy to set up and work similar to traditional load balancers.  There are custom health checks which can be altered on the fly and they allow you to specify a page to access which will determine if the load balance server is healthy.  I usually create an index.html page which just returns a 200 OK message to the Load Balancer.  Once an instance stops returning a response when the page is pinged, it will simply remove the instance from the load balancer queue.
     

Step 3
Now that you have a basic understanding of AWS, you can set up your first instanceTry not to get too excited, but it is cool.  You will choose a base installation image.  Make sure you choose a good base image…once you have it up and running, you probably don’t want to start from scratch again ;) .  I highly recommend the images produced by Eric Hammond of Alestic.  He makes great base images which are lean, so you can build them out however you want. 

Once you have chosen the image, the Amazon EC2 interface has a wizard to lead you through the process of launching for your first EC2 image.  Once you start the launch process, it will take 2-3 minutes to provision the server.  You can monitor the progress from the Amazon Web Services admin panel.  For the initial connection, you will need to use the public IP assigned to your server along with the pem key that you created during your account signup process.

Step 4

Once you have your image built exactly the way you want, it is important to snapshot the Volume as a backup.  This will create a bundled instance.  During this process the system will go down for bundling.  Once finished, your server will restart and be ready for use.

Now that you have your initial server, now comes the fun part!  Unfortunately…I don’t have time to write about it right now :) .  Next time I will discuss the process and caveats to setting up an Amazon Elastic Load Balancer.  Stay tuned…

 

Magento Therapy: A Series on Magento Development

Posted on: April 13th, 2010 by Rob Zienert

E-Commerce is a huge part of the internet, and choosing the right tool for the job is integral to success. At PRPL, our developers primarily work in PHP, so it was an easy choice going with Magento for our defacto E-Commerce platform. There’s a laundry list of reasons why it’s the best PHP shopping cart, but I won’t go into it here — check out the Magento website for that. 

There is, however, one over-arching community complaint that we even found ourselves battling a lot: the learning curve is steep. Real steep. It’s architecture is greatly different than what most PHP developers are accustomed to, and the documentation quite bluntly sucks. It’s my opinion that throwing around explicatives and an excess amount of sarcastic praise is normal (and likely healthy) while learning Magento. But worry not, you’ll come to love the architecture — it makes fantastic things easier!

Over the next few weeks, Zach and I will be aiming a series of blog posts at the finer points of Magento website development with the hopes you can take away some pointers from us that we’ve had to learn along the way. We’ve developed everything from simple out-of-the-box implementations to highly customized and targeted implementations: one of our Magento sites has made over $3 million dollars in online revenue in the last 8 months. Unfortunately, this client is white-labelled, so we will not be able to talk specifics or show examples from this client. :(

The schedule is looking something like the following:

Of course, we’re open to suggestion and would love to hear your thoughts on what matters most to you!

We’ll be back!

 

GWB ‘knew Guantánamo prisoners were innocent’ but that’s not the shocking part.

Posted on: April 11th, 2010 by Rabbit

Woke up this morning to catch this really disappointing article claiming George W. Bush, Dick Cheney and Donald Rumsfeld covered up that hundreds of innocent men were sent to the Guantánamo Bay prison camp because they feared that releasing them would harm the push for war in Iraq and the broader War on Terror. Maybe I have been naive but that wasn’t the shocking part.

The shocking part, for me, came from a seemingly quick side comment (emphasis mine):

Colonel Wilkerson, a long-time critic of the Bush Administration’s approach to counter-terrorism and the war in Iraq, claimed that the majority of detainees — children as young as 12 and men as old as 93, he said — never saw a US soldier when they were captured. He said that many were turned over by Afghans and Pakistanis for up to $5,000. Little or no evidence was produced as to why they had been taken.

Children as young as 12? Dangerous terrorists? Men as old as 93? Not subject to a civil hearing or given legal notice as to why they are being detained? Children?! Treated as hostile enemy combatants who don’t deserve a court hearing? Little kids who never necessarily understood why they were being detained? Why doesn’t the article expand on this little comment? Does everyone know about this? Am I the only one shocked?

Please, someone explain this to me. I’m having a hard time wrapping my head around it. Even if everyone there were guilty, dangerous terrorists it’s still a difficult fact to wrap my head around that a child doesn’t deserve a court hearing. According to the Colonel Wilkerson though we’re talking about innocent children. Ugh!

Court rules FCC does not have custody. Internet cries without father figure. Rabbit confused.

Posted on: April 6th, 2010 by Rabbit

So I’m browsing the Digg headlines and I come across this article about a federal appeals court ruling that the FCC lacks the authority to meddle in the affairs of broadband providers. "This is great news!" I think to myself. I’m an evangelist for open, free, unregulated internet. I’m a supporter of net neutrality and am very concerned about information control currently being carried out all around the world to silence citizens, conceal truths, and discourage opposition to unjust rule. Which is why I was completely stunned to find the Yahoo! article painted these events with a negative brush and the comments about the article were a waterfall of tears and desperate cries for a savior.

Make no mistake: this is about control which is about power. Governments steal it, corporations patent it, and citizens lose it. Right now the control is largely in the hands of the bandwidth providers and that scares us. There is a very real incentive for large corporations to purchase road blocks for their potential competitors. I’m not naive. I fully understand this would be absolutely horrendous and none of us — none of us — can afford to tolerate it. I also think it’s a little odd that the FCC claimed to be able to fix this issue. Since when did the FCC have control over the internet? This ruling answers that question: they never did. If you think the FCC ensuring net neutrality is the one and only goal, then you either haven’t been around long enough or haven’t been paying attention. This is about using your support for net neutrality to position themselves as the agency in control of the internet. Hope you’re ready for Hulu, Grooveshark, and Last.fm to suck like television and radio.

The internet is an unbounded, uncontrolled, unbiased, global, data manifesting, exponentially accelerating, unstoppable beast. For freedom loving people of the world; it is a reason to rejoice, raise a glass of wine for a toast, and dance around a grassy field in a Hobbit-like utopia. For governments, corporations, and other persons or entities that exist with a incessant desire to control; it is a marauding devil bear with virgin blood eyes vomiting nuclear holocaust onto your family. In other words it’s the scariest thing to be invented and embraced since the U.S. Constitution.

The internet is a scary place. It has profanity and porn. That offends people. It has free speech. That really offends people. There are viruses and hackers and identity thieves and sensitive intellectual property and banks and finances and medical records and serious business and on and on and on. That’s a lot of real estate and natural resources. Surely, we need somebody to come along and tell us what to do about it because we’re clearly out of our minds, right? We need the FCC to be our savior, don’t we? … Hell no!

So, to reiterate. This whole FCC being shot down? It’s a good thing. Embrace it! Yes, we still need to figure out how we will ensure corporations aren’t going to start showing bandwidth favoritism but if you’re paying attention we already have that: it’s you. Stop relying on Daddy so much. We’ll figure this one out on our own.