Customising Magento .phtml view files and creating CMS blocks

Ok in yesterdays post, I showed you how you can start bringing in the Bootstrap files into Magento by defining them in the theme’s page.xml. We finished up by tweaking the layout .phtml files.

Now we’ll start editing our header. Open /app/design/frontend/fashion/default/template/page/html/header.phtml and put some placeholder bootstrap HTML into place:

<div id="top-bit">
    <div class="container">
        <div class="row">
            <div class="col-md-8">
                 ...
            </div>
            <div class="col-md-4">
                ...
            </div>
        </div>
    </div>
</div>

<div id="header">
    <div class="container">
        <div class="row">
            ...
        </div>
    </div>
</div>

<nav>
    ...
</nav>

We’ll stick some custom links in, the logo, and shopping basket, and nav bars with menu and search form. To make the top header div, we will create a CMS block with custom links, and a user area. To create a CMS Block, in the Magento Admin Panel, click on CMS > Static Blocks, and Add new block. I gave mine a title of Top Links, an ID of top_links, and in the content I added an inline bootstrap <ul>

<ul class="list-inline">
    <li><span class="glyphicon glyphicon-phone-alt"></span>&nbsp;<strong>Call Us: +39 (0) 55 11 22</strong></li>
    <li><a href="{{store_url=''}}">About Us</a></li>
    <li><a href="{{store_url=''}}">Delivery</a></li>
    <li><a href="{{store_url=''}}">FAQ</a></li><li><a href="{{store_url=''}}">Contacts</a></li>
</ul>

Then in the header.phtml, you add within the div#top-bit container row col-md-8:

<?= $this->getChildHtml('top_links'); ?>

Ok, in any Magento shop, we should have a welcome message, and Login | Register links. In the col-md-4 div, stick the following in:

<span class="welcome pull-left">
    <?= $this->getLayout()->getBlock('header')->getWelcome(); ?>
</span>
<ul class="list-inline pull-left">
    <?php
    if ($this->helper('customer')->isLoggedIn()) { ?>
        <li><a title="<?= $this->__('My Account'); ?>" href="<?= $this->getUrl('customer/account') ?>"><?= $this->__('My Account'); ?></a></li>
        <li><a title="Log Out" href="<?= $this->getUrl('customer/account/logout'); ?>"><?= $this->__('Logout'); ?></a></li>
    <?php } else { ?>
        <li><a href="<?= $this->getUrl('customer/account/login/')?>"><?= $this->__('Login') ?></a></li>
        <li><a href="<?= $this->getUrl('customer/account/create/')?>"><?= $this->__('Create Account') ?></a></li>
    <?php } ?>
</ul>

Now we can customise the CSS for our top bit. Open up /skin/frontend/fashion/default/css/styles.css and add the following styling rules:

div#top-bit
{
    background:none repeat scroll 0 0 #000;
    color:#FFF;
    font-size:12px;
    padding:10px 0 0;
    border-bottom:3px solid #FA9221;
}
div#top-bit ul
{
    margin:5px 0 0;
}
div#top-bit a
{
    color:#9F9F9F;
}
div#top-bit a:hover
{
    color:#f89223
}
div#top-bit .user-links .welcome
{
    padding:10px;
}
div#top-bit .user-links ul
{
    background: none repeat scroll 0 0 #FA9221;
    margin: 0;
    padding: 10px;
}
div#top-bit .user-links a
{
    color:#fff;
}

Ok, the section under the top-bit will contain a logo and a shopping cart. To change what the logo is, in the Magento Admin Panel, navigate to System > Configuration > Design > Header and change the Logo Image src.

Stick the following in div#header container row:

<div class="col-md-4">
   <a href="<?= $this->getUrl('') ?>" title="<?= $this->getLogoAlt() ?>" class="logo">
       <img src="<?= $this->getLogoSrc() ?>" alt="<?= $this->getLogoAlt() ?>" />
   </a>
</div>
<div class="col-md-4 col-md-offset-4">
     <?php echo $this->getChildHtml('top_cart') ?>
</div>

Now we actually need a top_cart section. Create app/design/frontend/fashion/default/template/checkout/cart/topcart.phtml.

<?php 

if ($this->getIsNeedToDisplaySideBar())
{
?>
    <div class="block block-cart block-topcart">
        <?php $cart_qty = $this->getSummaryCount(); ?>
        <div class="block-title">
            <div class="block-title">
                <span class="glyphicon glyphicon-shopping-cart"></span>
                <strong><span><?= $this->__('My Cart') ?></span></strong>

                <?php
                    if ($cart_qty > 0)
                    { 
                        $s = $cart_qty == 1 ? '' : 's';
                ?>
                <p class="amount">
                    <?= $this->__('There are <a href="%s">%s items</a> in your cart.', $this->getUrl('checkout/cart'), $cart_qty); ?>
                    <?= Mage::helper('checkout')->formatPrice($this->getSubtotal()) ?>
                </p>
                <?php } else { ?>
                        <p class="empty"><?= $this->__('You have no items in your shopping cart.') ?></p>
                <?php } ?>

                <?php if($cart_qty && $this->isPossibleOnepageCheckout()) { ?>
                    <div class="actions">
                        <?= $this->getChildHtml('extra_actions'); ?>
                        <button type="button" title="<?= $this->__('Checkout');?>" class="button" onclick="setLocation('<?= $this->getCheckoutUrl() ?>')">
                            <span><span><?= $this->__('Checkout') ?></span></span>
                        </button>
                    </div>
                <?php } ?>

                <?php $items = $this->getRecentItems(); ?>
                <?php if(count($items)){ ?>
                    <p class="block-subtitle"><?= $this->__('Recently added item(s)'); ?></p>
                    <ol id="cart-sidebar" class="mini-products-list">
                        <?php foreach($_items as $_item) { ?>
                            <?= $this->getItemHtml($_item) ?>
                        <?php } ?>
                    </ol>
                    <script type="text/javascript">decorateList('cart-sidebar', 'none-recursive')</script>
                <?php } ?>
        </div>
    </div>
<?php } ?>

Then we must declare top_cart in our local.xml:

<reference name="header">
    <block type="checkout/cart_sidebar" name="top_cart" template="checkout/cart/topcart.phtml" before="-">
        <action method="addItemRender"><type>simple</type><block>checkout/cart_item_renderer</block><template>checkout/cart/sidebar/default.phtml</template></action>
        <action method="addItemRender"><type>grouped</type><block>checkout/cart_item_renderer_grouped</block><template>checkout/cart/sidebar/default.phtml</template></action>
        <action method="addItemRender"><type>configurable</type><block>checkout/cart_item_renderer_configurable</block><template>checkout/cart/sidebar/default.phtml</template></action>
        <block type="core/text_list" name="cart_sidebar.extra_actions" as="extra_actions" translate="label" module="checkout">
            <label>Shopping Cart Sidebar Extra Actions</label>
        </block>
    </block>
</reference>

The <reference name=”header”> refers to the ID of a div. Again bung in some CSS:

#header {
    padding-top:10px;
}
#header .logo {
    display:block;
    margin-bottom:20px;
}
#header .block-topcart {
    margin-top: 5px;
    padding: 14px 20px 10px;
}
#header .block-topcart .block-title {
    font-size: 15px;
    margin-bottom: 5px
}
#header .block-topcart p.empty {
    font-size: 12px;
    color: #666;
    font-style: italic
}
#header .block-topcart .block-content {
    display: none
}

Now in the <nav> tag in the header.phtml, we can add the navbar code:

<nav class="navbar navbar-default navbar-main" role="navigation">
    <div class="container">
        <div class="row">
            <div class="navbar-header">
                <a class="navbar-brand visible-xs" href="#">
                    <?php echo $this->__('Categories') ?>
                </a>
                <button type="button" class="navbar-toggle" data-toggle="collapse"
                        data-target=".navbar-main-collapse">
                    <span class="sr-only"><?php echo $this->__('Toggle Navigation') ?></
                    span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
            </div>
            <div class="collapse navbar-collapse navbar-main-collapse">
                <?php echo $this->getChildHtml('topMenu') ?>
                <?php echo $this->getChildHtml('topSearch') ?>
            </div>
        </div>
    </div>
</nav>

We now have a very bootstrappy looking search box! As you can see from the code above, we are also wanting the ChildHtml of topMenu. So lets add that. Edit /app/design/ frontend/fashion/default/template/page/html/topmenu.phtml :

 

<?php
    $_menu = $this->getHtml('level-top');
    if ($_menu) { ?>
        <ul class="nav navbar-nav">
            <li><a href="<?php echo $this->getUrl('') ?>" title="<?php echo $this->getLogoAlt() ?>">Home</a></li>
            <?= $_menu; ?>
        </ul>
<?php }

We need to add a little jQuery to dynamically add a couple of our bootstrap classes, so in /skin/frontend/fashion/default/js/jquery/jquery.scripts.js

 

$j = jQuery.noConflict();

$j(document).ready(function(){
    jQuery('.navbar .parent').addClass('dropdown');
    jQuery('.navbar a.level-top').addClass('dropdown-toggle');
    jQuery('.navbar li.parent ul').addClass('dropdown-menu');
    jQuery('.navbar li.level1 ul').wrap('<li class="dropdown-submenu" />');
    jQuery('.navbar ul.nav li.level0.dropdown').hover(function() {
        jQuery(this).find('.level0.dropdown-menu').stop(true, true).fadeIn();
    }, function() {
            jQuery(this).find('.level0.dropdown-menu').stop(true, true).fadeOut();
        });
});

Lastly (at least in this post) we’ll sort out a footer. Edit /app/design/frontend/ bookstore/default/template/page/html/footer.phtml

<div class="row">
    <div class="col-md-4">
        <?= $this->getChildHtml('footer-company') ?>
    </div>
    <div class="col-md-8">
        <div class="row">
            <?= $this->getChildHtml('footer-cmslinks') ?>
            <hr>
        </div>
        <div class="row">
            <div class="col-md-6">
                <?= $this->getChildHtml('footer-newsletter') ?>
            </div>
            <div class="col-md-6">
                <?= $this->getChildHtml('footer-social') ?>
            </div>
        </div>
    </div>
</div>
<div class="row">
    <div class="col-md-12">
        <hr>
    </div>
    <div class="col-md-8">
        <?= $this->getCopyright() ?>
    </div>
    <div class="col-md-4">
        <?= $this->getChildHtml('footer-cards') ?>
    </div>
</div>

There are six things being called here. Four items will be CMS blocks, and the other two normal blocks (newsletter and copyright). We define our blocks in the local.xml in the footer reference:

<reference name="header">
    <block type="checkout/cart_sidebar" name="top_cart" template="checkout/cart/topcart.phtml" before="-">
        <action method="addItemRender"><type>simple</type><block>checkout/cart_item_renderer</block><template>checkout/cart/sidebar/default.phtml</template></action>
        <action method="addItemRender"><type>grouped</type><block>checkout/cart_item_renderer_grouped</block><template>checkout/cart/sidebar/default.phtml</template></action>
        <action method="addItemRender"><type>configurable</type><block>checkout/cart_item_renderer_configurable</block><template>checkout/cart/sidebar/default.phtml</template></action>
        <block type="core/text_list" name="cart_sidebar.extra_actions" as="extra_actions" translate="label" module="checkout">
            <label>Shopping Cart Sidebar Extra Actions</label>
        </block>
    </block>
</reference>

<reference name="footer">
    <block type="cms/block" name="footer-company" as="footer-company">
        <action method="setBlockId"><block_id>footer-company</block_id></action>
    </block>
    <block type="cms/block" name="footer-cmslinks" as="footer-cmslinks">
        <action method="setBlockId"><block_id>footer-cmslinks</block_id></action>
    </block>
    <block type="cms/block" name="footer-social" as="footer-social">
        <action method="setBlockId"><block_id>footer-social</block_id></action>
    </block>
    <block type="cms/block" name="footer-cards" as="footer-cards">
        <action method="setBlockId"><block_id>footer-cards</block_id></action>
    </block>
</reference>

Ok, the CMS blocks then. Log in to the admin panel, and go to CMS > Static Blocks. Click add new block, call it footer_company

<h4>About Our company</h4> <p>Our company are awesome, we use Bootstrap 3.0 and Magento version
       1.19. We are developing solutions and blah blah blah<a href="https://github.com/delboy1978uk">Visit Our Github!</a>

Add footer-cmslinks :

 

<div class="col-md-3">
    <h4>Column Name</h4>
    <ul>
        <li><a href="{{store_url=''}}about-magento-demo-store">About Us</a></li>
        <li><a href="{{store_url=''}}customer-service">Customer Service</a></li>
        <li class="last privacy"><a href="{{store_url=''}}privacy-policy-cookie-restriction-mode">Privacy Policy</a></li>
    </ul>
</div>
<div class="col-md-3">
    <h4>Column Name</h4>
    <ul>
        <li><a href="{{store_url=''}}about-magento-demo-store">About Us</a></li>
        <li><a href="{{store_url=''}}customer-service">Customer Service</a></li>
        <li class="last privacy"><a href="{{store_url=''}}privacy-policy-cookie-restriction-mode">Privacy Policy</a></li>
    </ul>
</div>
<div class="col-md-3">
    <h4>Column Name</h4>
    <ul>
        <li><a href="{{store_url=''}}about-magento-demo-store">About Us</a></li>
        <li><a href="{{store_url=''}}customer-service">Customer Service</a></li>
        <li class="last privacy"><a href="{{store_url=''}}privacy-policy-cookie-restriction-mode">Privacy Policy</a></li>
    </ul>
</div>
<div class="col-md-3">
    <h4>Column Name</h4>
    <ul>
        <li><a href="{{store_url=''}}about-magento-demo-store">About Us</a></li>
        <li><a href="{{store_url=''}}customer-service">Customer Service</a></li>
        <li class="last privacy"><a href="{{store_url=''}}privacy-policy-cookie-restriction-mode">Privacy Policy</a></li>
    </ul>
</div>

Now the footer-social block:

<ul class=”list-inline footer-social”>
<li><a class=”ico-facebook” href=”#”><span></span>Facebook</a></li>
<li><a class=”ico-twitter” href=”#”><span></span>Twitter</a></li>
<li><a class=”ico-google” href=”#”><span></span>Google+</a></li>
</ul>

Finally footer-cards:

<a href="#">
       <span style="font-size:12px; padding-right:10px;">Secure
       Payments</span>
       <img src="{{skin_url='images/cards.png'}}">
       </a>

Now we have our CMS blocks, we still need the other two. The newsletter block wont appear, because the default goes in the left hand side for whatever reason. Back in the xml, we add this:

<reference name="left">
    <remove name="left.newsletter"/>
</reference>

And in the footer reference, we add this:

<block type="newsletter/subscribe" name="footer.newsletter" as="footer-newsletter" template="newsletter/subscribe.phtml"/>

Now we create app/design/ frontend/base/default/template/newsletter/subscribe.phtml :

<div class="block block-subscribe">
    <form action="<?= $this->getFormActionUrl() ?>" method="post"
          id="newsletter-validate-detail">
        <div class="input-group">
           <span class="input-group-addon"><?= $this->__('Newsletter'); ?></span>
            <input type="text"
                   class="form-control input-sm required-entry validate-email"
                   title="<?= $this->__('Sign up for our newsletter') ?>"
                   id="newsletter"
                   name="email">
           <span class="input-group-btn">
               <button class="btn btn-default btn-sm" title="<?= $this->__('Subscribe') ?>" type="submit"><?= $this->__('Subscribe') ?></button>
           </span>
        </div>
    </form>
    <script type="text/javascript">
        //<![CDATA[
        var newsletterSubscriberFormDetail = new VarienForm('newsletter-validate-detail');
        //]]>
    </script>
</div>

Finally, add a splodge of CSS:

#footer {
    background-color:#FA9221;
    color:rgba(0,0,0,0.3);
    padding:20px 0;
    border-bottom:5px solid #333;
    font-size:12px,;
}
#footer h4 {
    color:rgba(0,0,0,0.6);
    font-size:14px;
}
#footer ul {
    list-style-position:inside;
    padding:0;
    margin:0;
}
#footer a {
    color:rgba(0,0,0,0.5);
    font-size:12px;
}
#footer a:hover {
    color:rgba(0,0,0,0.8);
}
#footer hr {
    border-color:rgba(0,0,0,0.2);
    border-style:dotted;
}
/* Social Icons */
#footer .footer-social a {
    display:inline-block;
    font-size:12px;
    line-height:24px;
}
#footer .footer-social a span {
    background: url(../images/sprite-social.png) no-repeat scroll 0 0 rgba(0, 0, 0, 0);
    display: inline-block;
    float: left;
    height: 24px;
    margin-right: 6px;
    padding-left: 20px;
    width:24px;
}
#footer .footer-social a.ico-facebook span {
    background-position:0 0;
}
#footer .footer-social a.ico-twitter span {
    background-position:-40px 0;
}
#footer .footer-social a.ico-google span {
    background-position:-80px 0;
}
#footer .footer-social a.ico-facebook:hover span {
    background-position:0 -28px;
}
#footer .footer-social a.ico-twitter:hover span {
    background-position:-40px -28px;
}
#footer .footer-social a.ico-google:hover span {
    background-position:-80px -28px;
}
#footer hr{
    margin-top: 20px;
    margin-bottom: 20px;
}

And that’s the end of the second chapter of my book! Next post I do, I’ll be blogging my experience customising our home page

Using Emmet in your IDE

Emmet is awesome! It’s a little tool (once called Zen Coding) that gives you loads of keyboard shortcuts for generating HTML and CSS markup! Give it a try! Install an Emmet plugin into your IDE. Then, in a view file, try typing this:

table#applications.table-striped.table-hover.table>thead>tr>td*3^^tbody>tr>td*

In PHPStorm, hit TAB after typing that. In Eclipse/Aptana, you press CTRL-E. Suddenly, it changes to:

<table id="applications" class="table-striped table-hover table">
    <thead>
        <tr>
            <td></td>
            <td></td>
            <td></td>
         </tr>
    </thead>
    <tbody>
         <tr>
             <td></td>
             <td></td>
             <td></td>
         </tr>
    </tbody>
</table>

As you can imagine, this saves a LOT of time! Check out the Emmet Cheatsheet here:
http://docs.emmet.io/cheat-sheet/

You can download the plugin for your IDE here:
http://emmet.io/download/
Have fun!