• Random

    Magento – Applying Security Patches on Windows

    As an addendum to the previous post, I wanted to add Windows specific information.

    I use Cygwin to apply Magento patches. Make sure to configure Cygwin to install the patch binary.

    Now, you’re going to have to make a small edit to the .sh file. Look for the second occurrence of PATCH_BIN – it should look something like this:


    You’ll want to surround $PATCH_BIN with double quotes – that’s because, chances are, the location of Cygwin is going to contain spaces, which is going to cause issues when executed in the command line. So, change it to look something like this:


    Other than that, you should be able to run the patch as detailed in the previous post.

  • Coding,  Random

    Magento – Applying Security Patches and Fixing Conflicts

    As you are probably well aware, Magento has been releasing a steady stream of security patches recently. I’m going to give a quick overview of applying them, and also dealing with possible conflicts.

    Here are the official instructions for applying a patch. As you can see, they recommend running

    sh patch-file-name.sh

    However, as this Stack Overflow question illustrates, sometimes that won’t work. You might get something like

    sh PATCH_SUPEE-5344_CE_1.8.0.0_v1-2015-02-10-08-10-38.sh -R
    PATCH_SUPEE-5344_CE_1.8.0.0_v1-2015-02-10-08-10-38.sh: 14: PATCH_SUPEE-      5344_CE_1.8.0.0_v1-2015-02-10-08-10-38.sh: 127: not found
    PATCH_SUPEE-5344_CE_1.8.0.0_v1-2015-02-10-08-10-38.sh: 14: PATCH_SUPEE-5344_CE_1.8.0.0_v1-2015-02-10-08-10-38.sh: 127: not found
    PATCH_SUPEE-5344_CE_1.8.0.0_v1-2015-02-10-08-10-38.sh: 25: PATCH_SUPEE-5344_CE_1.8.0.0_v1-2015-02-10-08-10-38.sh: 0: not found
    Checking if patch can be applied/reverted successfully...
    Patch was applied/reverted successfully.

    The two most highly rated answers are correct – there are bash specific lines in the patch file, and the default system shell may not be bash. In Ubuntu 6.10+, they have changed /bin/sh to dash. To get around this, make the patch file executable, and then run the patch file directly, without sh. That is,

    chmod +x patch-file-name.sh

    Change patch-file-name.sh to the actual name of your file.

    If all goes well, then you should see the following messages:

    $ ./patch-file-name.sh
    Checking if patch can be applied/reverted successfully...
    Patch was applied/reverted successfully.

    If it was not successful, you’ll see an exhaustive list what changes were applied, and which failed. Usually this happens when you have local changes of a file, or in one of our client’s cases, when Magento did not provide a patch specifically for their version. In that case, you might get something like this:

    $ ./PATCH_SUPEE-5994_CE_1.4.1.0_v1-2015-05-15-04-33-58.sh
    Checking if patch can be applied/reverted successfully...
    ERROR: Patch can't be applied/reverted successfully.
    patching file app/code/core/Mage/Core/Controller/Varien/Router/Admin.php
    Hunk #1 succeeded at 93 with fuzz 2 (offset -2 lines).
    patching file app/code/core/Mage/Core/Controller/Varien/Router/Standard.php
    Hunk #1 succeeded at 206 (offset 1 line).
    Hunk #2 succeeded at 271 (offset -8 lines).
    Hunk #3 succeeded at 307 (offset -8 lines).
    patching file app/code/core/Mage/Customer/Model/Customer.php
    patching file app/code/core/Mage/Dataflow/Model/Convert/Parser/Csv.php
    patching file app/code/core/Mage/Install/Controller/Router/Install.php
    patching file app/code/core/Mage/Install/etc/config.xml
    can't find file to patch at input line 185
    Perhaps you used the wrong -p or --strip option?
    The text leading up to this was:
    |diff --git app/code/core/Mage/Sales/controllers/Recurring/ProfileController.php app/code/core/Mage/Sales/controllers/Recurring/ProfileController.php
    |index 95c66dc..6f5ed5d 100644
    |--- app/code/core/Mage/Sales/controllers/Recurring/ProfileController.php
    |+++ app/code/core/Mage/Sales/controllers/Recurring/ProfileController.php
    File to patch:
    Skip this patch? [y]
    Skipping patch.
    1 out of 1 hunk ignored
    patching file lib/PEAR/PEAR/PEAR.php
    patching file lib/PEAR/PEAR/PEAR5.php
    patching file lib/Varien/Io/File.php
    Hunk #1 succeeded at 224 (offset -2 lines).

    In this case, look for the line around

    app/code/core/Mage/Sales/controllers/Recurring/ProfileController.php. For this example, that file didn’t exist in the client’s version, so I edited the .sh file and removed the entire block, starting from diff --git app/code/core/Mage/Sales/controllers/Recurring/ProfileController.php app/code/core/Mage/Sales to the line just before the next diff.

    If it’s a specific hunk that’s misbehaving, you can apply the change manually and then remove the hunk from the .sh file. It should be fairly easy to tell – lines starting with a + are new lines, lines with - are removed, and lines with neither stay the same. Look for the lines with neither +/- as a reference point, and add/remove lines accordingly. To remove the hunk, remove the hunk starting with @@ to just before the next line starting with @@ For example, in the below snippet, if I wanted to remove hunk #2, I would remove lines 16-33.

    diff --git app/code/core/Mage/Core/Controller/Varien/Router/Standard.php app/code/core/Mage/Core/Controller/Varien/Router/Standard.php
    index efaf186..42c2fe6 100644
    --- app/code/core/Mage/Core/Controller/Varien/Router/Standard.php
    +++ app/code/core/Mage/Core/Controller/Varien/Router/Standard.php
    @@ -205,6 +205,10 @@ class Mage_Core_Controller_Varien_Router_Standard extends Mage_Core_Controller_V
                 // instantiate controller class
                 $controllerInstance = Mage::getControllerInstance($controllerClassName, $request, $front->getResponse());
    +            if (!$this->_validateControllerInstance($controllerInstance)) {
    +                continue;
    +            }
                 if (!$controllerInstance->hasAction($action)) {
    @@ -275,6 +279,17 @@ class Mage_Core_Controller_Varien_Router_Standard extends Mage_Core_Controller_V
    +     * Check if current controller instance is allowed in current router.
    +     * 
    +     * @param Mage_Core_Controller_Varien_Action $controllerInstance
    +     * @return boolean
    +     */
    +    protected function _validateControllerInstance($controllerInstance)
    +    {
    +        return $controllerInstance instanceof Mage_Core_Controller_Front_Action;
    +    }
    +    /**
          * Generating and validating class file name,
          * class and if evrything ok do include if needed and return of class name
    @@ -300,7 +315,6 @@ class Mage_Core_Controller_Varien_Router_Standard extends Mage_Core_Controller_V
             return $controllerClassName;
          * @deprecated
          * @see _includeControllerClass()

    Finally, after you’ve run the patch script successfully, you might need to reset the owner/group of your files back to your web server user – otherwise the patched files will belong to the user you’re running the .sh file as. Quoting from the official docs,

    a. Find the web server user: ps -o "user group command" -C httpd,apache2
    The value in the USER column is the web server user name.
    Typically, the Apache web server user on CentOS is apache and the Apache web server user on Ubuntu is www-data.
    b. As a user with root privileges, enter the following command from the Magento installation directory:

    chown -R web-server-user-name .

    For example, on Ubuntu where Apache usually runs as www-data, enter

    chown -R www-data .

    Good luck in your patch adventures!

  • Coding

    Getting the SQL Query for Magento Fulltext Search

    Short version: Magento searches through the catalogsearch_fulltext table. Reindex the Catalog Search Index if the data in there seems to be incorrect.

    Long version: Ever searched for a keyword of Magento and wondered, “why did this product show up under this keyword search?” If you go to the catalog/product/list.phtml and echoed out the SQL query for the Product Collection (via $_productCollection->getSelectSql(true)), you’ll get a useless SQL query that looks something like this:

    	1 AS `status`, <....> 
    FROM `catalog_product_flat_1` AS `e`
    	INNER JOIN `catalogsearch_result` AS `search_result` ON 
    		search_result.product_id=e.entity_id AND 
    	INNER JOIN `catalog_product_index_price` AS `price_index` ON 
    		price_index.entity_id = e.entity_id AND 
    		price_index.website_id = '1' AND 
    		price_index.customer_group_id = '1'
    	INNER JOIN `catalog_category_product_index` AS `cat_index` ON 
    		cat_index.product_id=e.entity_id AND 
    		cat_index.store_id='1' AND 
    		cat_index.visibility IN(3, 4) AND 
    ORDER BY `position` asc, `e`.`name` asc LIMIT 50

    So, you can see that query results are stored in the catalogsearch_result table, but how is that table built in the first place?

    If you go to Mage_CatalogSearch_Model_Resource_Fulltext (or Mage_CatalogSearch_Model_Mysql4_Fulltext if you’re using an older version of Magento), and scroll down to the prepareResult() function, you can see it building the search query if that keyword hasn’t been searched before (if (!$query->getIsProcessed())). To get the query itself, you can add Mage::log($sql); Mage::log($bind); just before $adapter->query($sql, $bind);. Remember, this will only fire on a keyword that hasn’t been searched before, unless you add a || true on the getIsProcessed() line.

    The log will show something like this:

    INSERT INTO `catalogsearch_result` 
    	(SELECT STRAIGHT_JOIN '19091', 
    		MATCH (`s`.`data_index`) AGAINST (:query IN BOOLEAN MODE), 
    		`catalog_category_product` as `c`,  
    		`catalogsearch_fulltext` AS `s` INNER JOIN `catalog_product_entity` AS `e` ON 
    		((`s`.`data_index` LIKE :likew0)) AND 
    		`s`.`store_id`='1' and 
    		s.product_id = c.product_id) 
    ON DUPLICATE KEY UPDATE `relevance`=VALUES(`relevance`)

    So, you can see that the query checks the catalogsearch_fulltext table. For each product id, it stores a concatenated string of all the data that’s been indexed. It’ll look something like this:

    fulltext_id	product_id	store_id	data_index
    4		1		1		123456789|Taxable Goods|Laptop|Laptop Description|Laptop Description|1200|1

    To control which data fields are indexed in this table, go to the Magento Admin and go to Catalog > Attributes > Manage Attribute. Select an attribute, and then scroll down to Frontend Properties. Toggle the “Use in Quick Search” settings. Then, reindex the Catalog Search Index if necessary.

  • OS X

    Removing the Caps Lock Delay on a Macbook

    Update 9/23/2016: This solution is still going strong in El Capitan. I haven’t installed macOS Sierra yet, but it looks like the functions of Seil might be integrated in the new Karabiner-Elements. Karabiner is broken for now. When I update, I will edit this post with fixes for Sierra, if any.

    I’m glad this post appears to have helped some people!

    Original Post:
    So, I recently ran across what Apple calls a feature, and what I call a pain in the butt. Namely, the caps lock button doesn’t always activate when you press it – you have to press it longer than usual to activate it. I’m a fairly fast typist, and I use a mechanical keyboard at work, so this drove me up the wall. This is supposedly to reduce accidentally activation of the caps lock key when you really meant to type the letter “A”, but that rarely, if ever, happens to me, so it just felt like punishment for typing quickly. I wouldn’t mind it if there was some easy way to turn it off and on, but I think we all realize by now that Apple doesn’t believe in turning off features they deem a part of their vision. (Like say, hiding the full url in the address bar.)

    I found a workaround of a sorts, but it involves turning off and on the caps lock key in System Preferences > Keyboard > Modifier Keys, but there was a catch – sometimes it’ll forget your setting after rebooting or waking up, and you’ll have to do it again. Besides, it sounded like an hack-ish, unintended feature that Apple could take away at any moment. So I decided to go look for a slightly more permanent solution. Unfortunately, it does involve third party programs, but it definitely works (as of writing, on OS X Mavericks, 10.9.4)

    This post and this documentation helped guide me to the right direction, though the names of the program have changed a bit. Here’s what you do:

    1. Install Seil and Karabiner.
    2. As per Seil’s documentation, go to System Preferences > Keyboard > Modifier Keys and change “Caps Lock” to “No Action.”

      OSX Caps Lock No Action

    3. Using Seil, check “Change Caps Lock Key” and change the key code to 110. (Application Key)
      Seil Change Caps Lock
    4. Go to Karabiner, and in the search box, enter “application key to capslock.” Under For PC Users > Change PC Application Key, check off “Application Key to CapsLock.”
      Karabiner Application Key to CapsLock
    5. Close the window. Done! Insanity averted, for now.
  • OS X

    Installing a LAMP Stack and mcrypt on OS X Mavericks

    I can install a LAMP stack in my sleep on Windows, but the process is considerably different on a Mac. For the record, I don’t like installing packages such as XAMPP/MAMP, because I like to have complete control over which versions of each component are installed. Also, I find it a good idea to know how to install each program individually, so you know how to set it up on a non-development server.

    The following is going to be heavy on links and commentary.

    First off, I installed xcode from the Mac App Store. I wanted it anyway for Objective-C testing, but also to install homebrew. (Clever url, that one.) I installed that because I am a definite fan of package management. After installing homebrew, I immediately ran a

    $ brew update

    so it was ready to go.

    I started off with this guide. So, the Apache portion. Turns out that OS X ships with its own version of Apache. (As of writing, 2.2.26.) That was perfect for my purposes (Magento doesn’t support Apache 2.4.x). Apache is located in /etc/apache2, runs as the httpd process, and as the user _www.

    The apache httpd conf is located at /etc/apache2/httpd.conf I changed the ServerName to

    ServerName localhost:80

    Apparently that gets rid of Apache warnings about not finding the fully qualified domain name. I also enabled the PHP module with

    LoadModule php5_module libexec/apache2/libphp5.so

    Now, I needed a vhost. The guide I was following, and others mentioned below, set up their vhost with a VirtualDocumentRoot, so it can change the document root based on the request url. For example, if I request folder123.dev, Apache can look for the files in folder123. For folder456.dev, it’ll look in folder456. So, I created a container for the document root in my home directory,

    $ mkdir ~/Sites

    I also created ~/Sites/sandbox/htdocs, giving ownership to the _www user, and making sure the group (staff) had write access.

    $ sudo chown -R _www htdocs
    $ sudo chmod -R g+w htdocs

    Definitely remember the chmod portion or else you’ll be as confused as I was when you can’t download files into that directory.

    The guides recommended creating a conf in the users directory at /etc/apache2/users/. However, I was curious how it was being included automatically. If you look at httpd.conf, you’ll see this under Supplemental Configuration.

    # User home directories
    Include /private/etc/apache2/extra/httpd-userdir.conf

    If you open that file up, you’ll see the following lines.

    # Users might not be in /Users/*/Sites, so use user-specific config files.
    Include /private/etc/apache2/users/*.conf

    So, I created my own dchan.conf and added these lines to it, changing /Users/username to my own home directory.

      ServerName dev
      DocumentRoot /Users/username/Sites
      VirtualDocumentRoot /Users/username/Sites/%-2/htdocs
      UseCanonicalName Off
        AllowOverride All
        Order allow,deny
        Allow from all

    I restarted Apache using apachectl, and confirmed it was running.

    $ sudo apachectl restart
    $ ps aux | grep httpd

    Next was PHP. PHP is also preinstalled, version 5.4.24 in my case. php.ini had to be created, fortunately there was already a template.

    $ sudo cp /etc/php.ini.default /etc/php.ini

    I enabled display_errors = On. Not much configuration to do at this time. I restarted Apache again.

    The last part, MySQL. I had homebrew install it.

    $ brew install mysql

    I then unset the temp directory and initialized the MySQL data directory/system tables. whoami dynamically retrieves your current user account.

    $ unset TMPDIR
    $ mysql_install_db --verbose --user=`whoami` --basedir="$(brew --prefix mysql)" --datadir=/usr/local/var/mysql --tmpdir=/tmp

    I also wanted MySQL to run automatically upon system startup. Now, this was a new experience. It looks like there isn’t an equivalent to the “Services” GUI in OS X – there’s only launchctl. I thought that was somewhat at odds with the other user friendly aspects of the system, but I rolled with it. To add MySQL to the startup programs, I used these commands, from this guide:

    $ mkdir -p ~/Library/LaunchAgents
    $ ln -sfv /usr/local/opt/mysql/*.plist ~/Library/LaunchAgents
    $ launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist

    There are two types of services – Launch Agents and Launch Daemons. According to this,

    “launch daemons can run without a user logged in. Launch daemons cannot display information using the GUI. Launch daemon configuration plist files are stored in the /System/Library/LaunchDaemons folder (for those provided by Apple et al) and /Library/LaunchDaemons (for the rest). Launch agents run on behalf of a user and therefore need the user to be logged in to run. Launch agents can display information through the window server. As with launch daemons, launch agent configuration plist files are stored in the /System/Library/LaunchAgents and /Library/LaunchAgents. User launch agents are installed in the ~/Library/LaunchAgents folder.”

    Lastly, it was time to set a root password.

    $ /usr/local/Cellar/mysql/5.6.19/bin/mysqladmin -u root -password 'PASSWORD HERE'

    Then I manually started mysql.

    $ mysql.server start

    Now, one thing about connecting to MySQL – you can’t use the “localhost” string. I noticed the same issue in Windows 8 – I had to specifically use There are two solutions to this, both documented here. One is just use, and the other is to create a symlink between /tmp/mysql.sock and /var/mysql/mysql.sock, linking whichever file is missing. I opted for the former solution, as it seemed less hacky.

    Now that all the components are installed, I needed some DNS management. I could edit the /etc/hosts file, but I wanted to see if there was anything more elegant, and indeed there was.

    There’s a utility called dnsmasq, conveniently available via homebrew.

    $ brew install dnsmasq
    $ sudo cp /usr/local/opt/dnsmasq/homebrew.mxcl.dnsmasq.plist /Library/LaunchDaemons

    I then created a conf file at /usr/local/etc/dnsmasq.conf. Like the other guides, I decided to go with a “.dev” wildcard domain for my folders, so my site would be available at sandbox.dev. (Apparently you can’t use the .local domain, because it’s reserved by OS X.)

    # /usr/local/dnsmaq.conf

    I loaded it into launchctl.

    $ sudo launchctl load -w /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist

    Now we need to connect dnsmasq to the OS DNS servers. Per this guide,

    Navigate to System Preferences -> Network -> WiFi (or your most used network interface) Click Advanced, and go the DNS tab. Under DNS servers, add at the top of the list, followed by (or any other nameserver).

    However, apparently you’ll have to do this for each wifi network you connect to. That sounded like a bit too much work, but this handy guide has two scripts that can take care of that.

    There are two files you have to download.

    Then I ran the following commands, per the above guide.

    mv setdns.sh /usr/local/bin
    chmod a+x /usr/local/bin/setdns.sh
    sudo cp com.zizproductions.setdns.plist /Library/LaunchDaemons
    sudo launchctl load -w /Library/LaunchDaemons/com.zizproductions.setdns.plist

    Now going to http://sandbox.dev shows me the files I’ve placed in ~/Sites/sandbox/htdocs. Awesome.

    At this point, I’m almost, but not quite ready to install Magento. I need mcrypt. This is something that was much easier on Windows, because all you have to do is uncomment a line to load in a precompiled .dll file. However, on OS X, there doesn’t seem to be any way around compiling the extension yourself.

    Some sites have you download and compile libmcrypt, but per this site, our ever-handy homebrew, it can take care of that too.

    $ brew install autoconf mcrypt

    I downloaded the PHP source for my version. I extracted it and navigated to the ext/mycrypt folder. I then attempted to run /usr/bin/phpize, but here’s the output I received.

    $ /usr/bin/phpize
    grep: /usr/include/php/main/php.h: No such file or directory
    grep: /usr/include/php/Zend/zend_modules.h: No such file or directory
    grep: /usr/include/php/Zend/zend_extensions.h: No such file or directory
    Configuring for:
    PHP Api Version:        
    Zend Module Api No:     

    I knew this was incorrect because I compared that to the desired output here. Well, this stumped me for quite some time. I was in the correct directory, phpize existed, everything seemed to check out. Some posts mentioned that the xcode command line tools needed to be installed, and I thought they were because both xcode-select and gcc existed and returned output.

    $ xcode-select -p

    However, I found out it was not the case. I had to actually enter

    $ xcode-select --install

    and then say yes to the install dialog box. With that out of the way, phpize now returned the proper output.

    $ /usr/bin/phpize
    Configuring for:
    PHP Api Version:         20100412
    Zend Module Api No:      20100525
    Zend Extension Api No:   220100525

    Now to continue on.

    $ ./configure
    $ make
    $ sudo make install

    Now, I had to enable the newly compiled .so in /etc/php.ini. I added this line


    I restarted Apache for one last time

    sudo apachectl restart

    Finally, we’re in business. I installed Magento, remembering to enter as the database host. And we’re off!

  • OS X

    Mac OS X Mavericks – First Impressions from a Windows User

    I’ve pretty much spent my entire life as a developer on Windows. I mean, of course I had putty to interact with the servers, which were some flavor of Unix, but my personal workstation was always Windows. (Fortunately, I skipped Windows ME, also known as the “the Windows of which we shall not speak.”)

    However, times have changed, and Apple has come very, very far from the sad iMacs and hockey puck mice of my high school days. Also, my laptop was in definite need of replacement, so I decided to go and get a new Macbook Pro. I also wanted to try my hand at iOS app development. I’ve played around briefly with other people’s Macs, and was suitably impressed with the mouse gestures and retina display, but I had no idea about how it like to work with day to day.

    So, here are my initial thoughts and experiences.

    Cut and Paste of Files is Missing?
    I noticed that there was nothing in the context menu to “Cut” files. I could Copy and Paste them, sure, and I could drag them around, but no actual “Cut.” A friend informed me that there’s a hot key, cmd+option+v (Copy and Move), but no corresponding gui option. Why? I have no idea, but it’s slightly annoying.

    No way to sort first by folders or files, and then alphabetically.
    I noticed this the first time I played with a Mac, but you can’t sort things by my preferred method, by files or folders, and then each group alphabetically. You can sort by “kind,” but that doesn’t quite do the trick – because all the files are then sorted by kind, as well. There doesn’t seem to be a workaround at this time.

    Can’t create new empty files from Finder
    I make frequent use of the “create new text file,” in Windows, using it to create new empty files on the fly, changing the extension to the desired file type. Sadly, there’s no equivalent in OS X.

    The Good
    Putting the computer to sleep and waking it up is seamless, and the retina display is gorgeous. Mouse gestures are great and speed things up considerably.

    The Random
    I can feel it venting heat from the keys! My fingers can literally be on fire.

  • Coding

    Magento Community Edition to Enterprise Edition Version Mapping

    Magento Enterprise Edition (EE) is essentially an extension of the Community Edition (CE). Enterprise Edition is a superset of the features of the Community Edition. That is, there no features in Community Edition that aren’t also in Enterprise Edition.

    You can see that when you look at the folder tree.

    Magento Enterprise Edition Folder Tree
    The core Magento files are located in app/code/core/Mage, while all Enterprise related features are in app/code/core/Enterprise.

    As such, you can roughly determine the corresponding CE edition based on your version of EE. Here’s a mapping, based on the release dates of each. It doesn’t cover the minor revisions in between, just major versions. I will attempt to keep this updated as new versions come out.

    Community Edition Enterprise Edition
    Magento CE 1.9 (5/13/14) Magento EE 1.14 (5/13/14)
    Magento CE 1.8 (12/11/13) Magento EE 1.13 (10/17/13)
    Magento CE 1.7 (4/24/12) Magento EE 1.12 (4/24/12)
    Magento CE 1.6 (8/18/11) Magento EE 1.11 (8/18/11)
    Magento CE 1.5 (2/8/11) Magento EE 1.10 (2/8/11)
    Magento CE 1.4 (2/12/10) Magento EE 1.9 (7/19/10)
    Magento EE 1.8 (4/14/10)
    Magento EE 1.7 (1/19/10)
    Magento CE 1.3 (3/30/09) Magento EE 1.6 (10/30/09)

    As you can see, there is some overlap between the base Magento versions of EE 1.7-1.9, most likely because the Magento team were focusing their efforts on developing Enterprise Edition. The next parallel release was Magento CE 1.5 and EE 1.10, and they were kept pretty much in sync since then.

    I found such a mapping helpful when I was looking for bug fixes for the core Magento code. I could say, I’m running EE 1.x, and there’s a bug in the app/code/core/Mage directory, so I can find the information about the bug in the corresponding CE edition.

    Magento Enterprise and Magento Community – The Key Differences
    Infographic – Magento History and Evolution

  • Coding

    Block types in Magento

    Updated 3/25/11: TLDR; If you just want to make a block that displays the contents of a phtml file, use the block type core/template, like so


    Then you can use $this->getChildHtml(‘logos’) in the relevant parent block to display it.

    Original Post:
    Block types are used in the layout XML files, ex,

    Per this post, block types conform to the format “group/specific_class.”

    For example Mage_Core module declares “core” group, which introduces blocks such as:
    * “core/text” – simple block type to show text strings
    * “core/template” – made for rendering templates into html

    Each block type refers to specific class:
    * “core/text” – Mage_Core_Block_Text
    * “core/template” – Mage_Core_Block_Template

    So, how it works that defining the block type essentially modifies the object you get with $this, which affects the data / methods you can use in that phtml template. Here’s a list of the more useful ones:

    • core/template – very simple, inserts the pthml file specified in the template attribute. Example, <block type=”core/template” template=”page.phtml”>