Magento: One site, multiple domains

A client recently wanted 2 domains resolving to the same Magento instance. This is typically discouraged due to SEO concerns of duplicate data/information but I digress.

Depending on your DNS management, you’d probably “park” the 2nd domain over the primary domain… done and dusted.

Unfortunately, it’s not that simple with Magento due to its robust multi-site and URL rewriting system. Magento has multiple scope/layers that allow you fine grain control over what you want to share between site/store instances. You can read more about that here: Overview: How Multiple Websites & Stores Work

In our case, the client wanted both domains to resolve to the same site (same template, same products, same everything). This was performed in Magento 1.6.2 on a standard LAMP setup.

  1. Create a new store
    1. System->Manage Stores
    2. Create Store
    3. Fill in the store fields, taking care that the Website and Root Category are the same as your primary site.store

      Screen Shot 2014-02-21 at 11.33.27 AM

    4. Save Store
    5. Create Store View
    6. Fill in the store view fields, change Store to the new store you just created, give your store view a Name (spaces ok), a code (must be all lower case with no spaces) and make sure it’s enabled.

      Screen Shot 2014-02-21 at 11.37.24 AM

    7. Save Store View
    8. System->Index Management->Select All & Reindex Data
    9. Your new store which will be share everything with your primary store is now created
    10. Note your Store View Code as you’ll need it later
  2. Tell Magento where to look – part 1
    1. System->Configuration->Web
    2. Change the scope on the upper left to your newly created store view
    3. Change Unsecure->Base URL to your second domain (You’ll have to uncheck Use Website)
    4. Change Secure->Base URL to your second domain (You’ll have to uncheck Use Website)
    5. Save Config
  3. Tell Magento where to look – part 2
    1. Using your favourite IDE, open the .htaccess at the root of your Magento install
    2. Add the following, obviously changing the values with your own:
      SetEnvIf Host www\.mysecondarydomain\.com MAGE_RUN_CODE=yoursecondarystoreviewcode
      SetEnvIf Host ^mysecondarydomain\.com MAGE_RUN_CODE=yoursecondarystoreviewcode
      
  4. Finishing up
    1. Clear the cache for good measure: System->Cache Management->Flush Magento Cache
    2. You may need to change the scope of your CMS pages to show on all sites and now just your primary site/store: CMS->Pages->Update the Store View to All Store Views or individually select the applicable stores.

Magento Cron Debugging with XDebug and PHPStorm

I recently needed to debug some Magento code from both the command line and stuff executed by cron. Inserting Mage::log() here and there wasn’t exactly efficient or satisfying.

I’ve always used XDebug with PHPStorm (which I use solely for debugging) but all code was always executed within the browser.

Long story short, if you want to debug code in the CLI or executed by cron there are a few extra steps you need to take.

Note that many of these settings are system/config dependent but there’s still a pretty good chance this will work for you. For reference, my dev setup is a CentOS x64 6.4 LAMP config running in Virtual Box and managed by Vagrant.

php.ini

zend_extension="/usr/lib64/php/modules/xdebug.so"
xdebug.remote_enable=1
xdebug.idekey = "PHPSTORM"
xdebug.remote_host=x.x.x.x
  • Replace x.x.x.x with your physical machine IP
  • Replace PHPSTORM with your IDE key (PHPSTORM by default)

CLI

$ PHP_IDE_CONFIG="serverName=mysite.dev" XDEBUG_CONFIG="remote_host=x.x.x.x idekey=PHPSTORM" php script.php
  • Replace mysite.dev with the PHP->Servers->Name in PHPStorm
  • Replace x.x.x.x with your physical machine IP

CLI Alias
Save yourself some keystrokes by aliasing the command. Add the following to your global bashrc which is typically in /etc/bashrc:

alias phpdebug='PHP_IDE_CONFIG="serverName=mysite.dev" XDEBUG_CONFIG="remote_host=x.x.x.x idekey=PHPSTORM" /usr/bin/php

You can now debug in the CLI using:

phpdebug script.php

crontab

SHELL="/bin/bash"
PHP_IDE_CONFIG="serverName=mysite.dev"
XDEBUG_CONFIG="remote_host=x.x.x.x idekey=PHPSTORM"
* * * * * /usr/bin/php -f /vagrant/cron.php
  • Replace mysite.dev with the PHP->Servers->Name in PHPStorm
  • Replace x.x.x.x with your physical machine IP
  • Replace PHPSTORM with your IDE key (PHPSTORM by default)

Couple of notes

  • You’ll want to make sure PHPStorm is configured with Xdebug
  • Make sure PHPStorm is listening for XDebug by clicking the phone icon in the PHPStorm toolbar
  • Comment out the PHP_IDE_CONFIG and XDEBUG_CONFIG in crontab when not debugging
  • PHPStorm may debug every request even if there’s no break point. To fix this: Preferences->PHP->Debug and uncheck Force break at the first line when no path mapping specified

Installing a Magento extension on a Mac: Merging files and folders

In order to install a Magento extension, the first step is usually to add the required files and folders to your current Magento installation. This can be a real pain on a Mac since its merge utility is rudimentary at best.

This is where rsync (which is available from the command line) comes in handy.

Common options
-a archive mode
-r recursive
-v verbose

Option 1
Merge all files and folders from source to destination (will overwrite files, not folders, in destination if source file exist with the same name under the same path)

rsync -arv SOURCE_DIR DEST_DIR

Option 2
Merge all files and folders from source to destination with the following rules:

  • Do not overwrite files which already exist
  • Skip destination files that are newer than the source
rsync -arvu SOURCE_DIR DEST_DIR --ignore-existing

Learning Ember.js: A Journey

EmberJS

I’ve got this tendency to work on ambitious projects. I think it’s a good way to get extra value from a project. If I can learn something new while developing a website or application, I see that as an earn! Of course it doesn’t always lead to speedy results and every extra hour I work drives down my hourly earn… but in the end, the newly acquired knowledge and experience helps drive my progression and results in a better product.

Having said that, I’ve turned to Ember.js as my framework of choice for an, you guessed it, ambitious application…

1 month later… So I started writing this post about a month ago and the original idea was to just post things I’ve learnt about Ember. Since then, Ember released v.1.0.0-pre.2 with a new router API (v.2) and just a few days later, a build from the master branch reveals a slightly modified router on its way to v.2.1. This rapid development cycle is mainly due to the fact that Ember is approaching v.1.final or whatever you want to call it.

Anyway, because Ember.js is like a budding teenager, documentation gets dated real quick. So what I’ve decided to do is maintain (for the time being) a list of official docs, non-official docs, gists, GitHub repos, jsfiddles, blog posts, screencasts, irc logs, napkins and stone engravings relating to Ember.js & Ember Data.

TL;DR

I hope this helps!

[Most recent discoveries at the top + all links update at least weekly. Resources which are no longer relevant are struck-through]

Last updated: 28.01.2013

You’ve reached the bottom! If you have an Ember.js or Ember Data resource that you think would enhance this list, please post it in the comments and I’ll gladly add it to the list.

Copy Images and Layers from Illustrator to Photoshop with pixel perfect accuracy

Part of my website development cycle is receiving the website design as an Illustrator file from my graphic designer. From there, I often have to extract design elements (images, layers, outlines) from the Illustrator file, import them (copy/paste) into Photoshop, perhaps do a few manipulations and finally save for web.

In 99% of cases, I required pixel perfect accuracy. Up until today, I used to struggle with retaining the design element size when I’d import it into Photoshop. For example, I’d select an element in Illustrator which is 100px*100px, copy it and paste it in Photoshop. Once in Photoshop it would then be about 98px*99px.

Turns out it’s because anti-aliasing is on by default when you confirm a pasted element into Photoshop. So the solution, simply enough, is to disable anti-aliasing before you confirm the placing of the element in photoshop.

I’ve created a short screencast to cover this issue (view in 1080p to get the full effect):

Getting Tar and Excluding Folders/Files to Work on Mac OSX

Sometimes it’s the seemingly simplest things that become the biggest pain in the ass…
All I wanted to do was create a tar.gz archive of a project and exclude some files and folders.

I typed $ man tar, followed the instructions and had little success.

Turns out tar is really finicky and differs slightly by distro… I’ll spare you the long story and just give you my working solution.

The working command
$ COPYFILE_DISABLE=true tar -c --exclude-from=.tarignore -vzf ee.tar.gz .

The break down:
COPYFILE_DISABLE=true: Prevent the ._ problem as outlined here
tar: Execute tar
-c: Set to create
–exclude-from=.tarignore: Ignore all files and folders listed in .tarignore (Just like .gitignore if you use Git)
-vzf: In order, v for verbose(show us what you’re doing), z for compress in gzip and f for compress to file
ee.tar.gzc: The name of the output file
.: Archive everything in the current working directory. You can also replace the . with * which will ignore all system files such as .htaccess.

My .tarignore file (Some are files some are directories, no trailing slash required)

.DS_Store
.git
.gitignore
.sass-cache
db_dumps
logs
scss
source

Sources: A Better TAR on Mac OS X – Excluding Save/Backup Files, SVN Metadata, and Resource Forks, Removing ._ (dot underscore) files on Leopard, Extended attributes

Magento 1.6 Menu Link Active State

Ahh Magento. So powerful but what a pain in the ass when you don’t work with it regularly.

So you’ve added custom menu items to your top.phtml

app/design/frontend/default/<strong>theme_name</strong>/template/navigation/top.phtml

It all works great but the .active class isn’t being applied to the menu item when you’re on said page.

For the home link

    <li class="home <?php echo (Mage::helper('core/url')->getCurrentUrl() === Mage::helper('core/url')->getHomeUrl()) ? "active" : ""; ?>"><a href="<?php echo $this->getUrl('')?>"><?php echo $this->__('Home') ?></a></li>

Note: What we’re doing here is we’re using built-in Magento methods and comparing the current url with the home url. If they’re the same, we append the active class to whatever other class we might have.

For any other link

    <li class="the-story <?php echo (strstr(Mage::helper('core/url')->getCurrentUrl(),"URL KEY HERE")) ? "active" : ""; ?>"><a href="<?php echo $this->getUrl('the-story')?>"><?php echo $this->__('The Story') ?></a></li>

Note: Similar to the home link code but this time we use the php function strstr() to see if the current page URL contains the URL key of the menu item page. If it does that mean we’re on that particular page so we append the .active class, same as above.

Hope this helps!