Create new template - Part 6 - Cutomize widget output
From TomatoCMS Documentation
In the previous post, you know how to use HTML widget from core module to show HTML content. Hene, it's similar to show dynamic data in first and second 12-columns containers for our template. In this post, I will show you how to customize the output of widget.
The first container show the hotest (popular) articles. You can use hotest widget from news module to do this. As I said in previous post, you should open widget information file (about.xml) in widget directory to get the full list of widget parameters.
In this case, app/modules/news/widget/hotest/about.xml file lets you know that this widget have only one parameter named limit which defines limit number of hotest articles.
So, I decide to use this widget. Let's insert this widget configuration to our home.xml file:
// app/templates/sample/layouts/home.xml
BEFORE:
... <widget module="core" name="html"> <params> <param name="content"> <value><![CDATA[Display slide of hotest aritcles]]></value> </param> </params> </widget> ...
AFTER:
... <widget name="hotest" module="news"> <params> <param name="limit"> <value><![CDATA[3]]></value> </param> </params> </widget> ...
(I want to make a slide that consist of 3 hotest articles, so I set 3 for value of limit parameter)
Then, what will happens to our homepage?
What is file TomatoCMS uses to show the output of widget?
In each widget directory, TomatoCMS will find show.phtml file and uses it to show the output of widget.
In this case, app/modules/news/widget/hotest/show.phtml was used to show the output of widget.
How to customize the output of widget in new template?
Fortunately, TomatoCMS allows you to customize the default output of widget in current template.
In template directory (app/templates/sample), create sub-directories, files as following structure:
TomatoCMS_Root_Dir |_app |_templates |_sample |_layouts |_views |_news |_widgets |_hotest |_show.phtml
In structure above:
- views directory consist of default output of widgets and scripts
- views/news: news is name of module
- views/news/widgets: this directory consist of customized output of widgets belonging to news module
- views/news/widgets/hotest: This directory consist of customized output of hotest widgets
TomatoCMS will uses app/templates/sample/views/news/widgets/hotest/show.phtml to show the output of hotest widget.
// app/templates/sample/views/news/widgets/hotest/show.phtml
<h1>Output of hotest widgets goes here!</h1>
Our homepage now looks like:
Now, open the default output of hotest widget (app/modules/news/widgets/hotest/show.phtml) and you will see the code that make of loop through the hotest articles:
<?php if ($this->articles != null) : ?> <?php foreach ($this->articles as $index => $article) : ?> <ul style="<?php if ($index == 0) : ?>dispaly: block<?php else : ?>display: none<?php endif; ?>"> <li> <?php if ($article->image_crop != null) : ?> <a href="<?php echo $this->url($article->getProperties(), 'news_article_details'); ?>"> <img src="<?php echo $article->image_crop; ?>" width="292px" height="219px" /> </a> <?php endif; ?> <h4><a href="<?php echo $this->url($article->getProperties(), 'news_article_details'); ?>"><?php echo $article->title; ?></a></h4> <div><?php echo $this->subString($article->description, 350); ?></div> </li> </ul> <?php endforeach; ?> <?php endif; ?>
Use this script and make some change to suit with our HTML output:
// app/templates/sample/views/news/widgets/hotest/show.phtml
<link rel="stylesheet" type="text/css" href="/js/jquery_plugins/jcarousel/jquery.jcarousel.css" /> <script type="text/javascript" src="/js/jquery_plugins/jcarousel/jquery.jcarousel.pack.js"></script> <div class="t_new_hotest"> <div id="t_new_hotest_slide"> <div id="t_new_hotest_content"> <?php if ($this->articles != null) : ?> <ul> <?php foreach ($this->articles as $index => $article) : ?> <li> <?php if ($article->image_crop != null) : ?><img src="<?php echo $article->image_crop; ?>" /><?php endif; ?> <div> <h2><a href="<?php echo $this->url($article->getProperties(), 'news_article_details'); ?>"><?php echo $article->title; ?></a></h2> <p><?php echo $this->subString($article->description, 300); ?></p> <p class="t_new_hotest_more"> <a href="<?php echo $this->url($article->getProperties(), 'news_article_details'); ?>"> <?php echo $this->translator()->widget('more'); ?> </a> </p> </div> </li> <?php endforeach; ?> </ul> <?php endif; ?> </div> <a href="javascript:void(0);" id="t_new_hotest_prev"><img src="/skin/sample/plus/images/prev.png" /></a> <a href="javascript:void(0);" id="t_new_hotest_next"><img src="/skin/sample/plus/images/next.png" /></a> </div> </div> <script type="text/javascript"> $(document).ready(function () { function carouselInitCallback(carousel) { $('#t_new_hotest_next').bind('click', function () { carousel.next(); return false; }); $('#t_new_hotest_prev').bind('click', function () { carousel.prev(); return false; }); // Disable autoscrolling if the user clicks the prev or next button. carousel.buttonNext.bind('click', function () { carousel.startAuto(0); }); carousel.buttonPrev.bind('click', function () { carousel.startAuto(0); }); // Pause autoscrolling if the user moves with the cursor over the clip. carousel.clip.hover(function () { carousel.stopAuto(); }, function () { carousel.startAuto(); }); }; $('#t_new_hotest_slide').jcarousel({ scroll: 1, auto: 5, // Sets the time delay between automatic scrolling of the panel wrap: 'last', initCallback: carouselInitCallback, // This tells jCarousel NOT to autobuild prev/next buttons buttonNextHTML: null, buttonPrevHTML: null }); }); </script>
Here, I use jquery.jcarousel plugin to slide the list of hotest articles. So, first, download the jcarousel library from http://sorgalla.com/jcarousel/ and put them to /js/jquery_plugins/jcarousel directory:
TomatoCMS_Root_Dir |___js |___jquery_plugins |___jcarousel |___jquery.jcarousel.css |___jquery.jcarousel.pack.js
Also, I add styles for this slide:
// skin/sample/plus/default.css
... /* ========== Widgets ======================================================= */ /** * news/hotest */ .t_new_hotest { width: 100%; color: #333333; background-color: #B2C629; } #t_new_hotest_slide { position: relative; margin: 0 auto 0; display: block; width: 840px; height: 260px; padding: 20px 50px; overflow: hidden; font-size: 12px; font-family: Verdana, Arial, Helvetica, sans-serif; } #t_new_hotest_slide a { color: #FFFFFF; background-color: #B2C629; } #t_new_hotest_slide a, #t_new_hotest_slide ul, #t_new_hotest_slide img { margin: 0; padding: 0; border: none; outline: none; list-style: none; text-decoration: none; } #t_new_hotest_slide h1, #t_new_hotest_slide h2 { margin: 15px 0 10px 0; padding: 0; line-height: normal; font-size: 36px; font-weight: normal; font-family: Georgia, "Times New Roman", Times, serif; } #t_new_hotest_content, #t_new_hotest_content ul { display: block; width: 840px; height: 260px; margin: 0; padding: 0; list-style: none; overflow: hidden; } #t_new_hotest_content li { display: block; position: relative; width: 840px; height: 260px; overflow: hidden; margin-left: 0px; } #t_new_hotest_content img { display: block; float: right; width: 380px; height: 250px; margin: 0 10px 0 0; padding: 4px; border: 1px solid #FFFFFF; } #t_new_hotest_content li div:first-child { display: block; float: left; width: 400px; height: 250px; margin: 0 0 0 10px; padding: 0; overflow: hidden; } #t_new_hotest_content p { margin: 0 0 20px 0; padding: 0; line-height: 1.6em; } #t_new_hotest_content p.t_new_hotest_more { display: block; width: 100%; margin: 0; padding: 0; text-align: right; line-height: normal; font-weight: bold; } #t_new_hotest_content p.t_new_hotest_more a { padding: 8px 15px 10px; color: #FFFFFF; background-color: #95AD19; } #t_new_hotest_prev, #t_new_hotest_next { display: block; position: absolute; top: 118px; width: 36px; height: 64px; } #t_new_hotest_prev { left: 5px; } #t_new_hotest_next { right: 5px; }
Notes that I named t_new_hotest for maintaining easy later. This name allows me to know that this styles is for hotest widget from news module.
Our homepage now looks like:
Repeat steps to customize output of news/newest widget
Now, it's easy to repeat similar steps to show the newest articles in second 12-columns container.
- Configure home.xml:
// app/templates/sample/layouts/home.xml
BEFORE:
... <widget module="core" name="html"> <params> <param name="content"> <value><![CDATA[Display 3 newest articles]]></value> </param> </params> </widget> ...
AFTER:
... <widget name="newest" module="news"> <params> <param name="limit"> <value><![CDATA[3]]></value> </param> </params> </widget> ...
- Create directory named newest in app/templates/sample/views/news/widgets directory.
Create show.phtml in the directory you have just created above.
- Open the default output of widget (app/modules/news/widgets/newest/show.phtml) to know how to get the data:
// app/modules/news/widgets/newest/show.phtml
<?php if ($this->articles != null) : ?> <?php foreach ($this->articles as $index => $article) : ?> <?php if ($index % 5 == 0) : ?><ul style="<?php if ($index == 0) : ?>dispaly: block<?php else : ?>display: none<?php endif; ?>"><?php endif;?> <li> <?php if ($article->image_square) : ?> <a href="<?php echo $this->url($article->getProperties(), 'news_article_details'); ?>"> <img src="<?php echo $article->image_square; ?>" width="60px" height="60px" /> </a> <?php endif; ?> <strong><a href="<?php echo $this->url($article->getProperties(), 'news_article_details'); ?>"><?php echo $article->title; ?></a></strong> <div><?php echo date($this->globalConfig('datetime')->date_time_format, strtotime($article->activate_date)); ?></div> </li> <?php if ($index % 5 >= 0 && $index % 5 <= 3) : ?> <li style="margin: 0; padding-top: 5px; height: 5px; line-height: 5px"><hr class="t_g_dot" /></li> <?php endif; ?> <?php if ($index % 5 == 4) : ?></ul><?php endif; ?> <?php endforeach; ?> <?php endif; ?> ...
Copy it and paste it in new output. Make some changes to customize the output:
// app/templates/sample/views/news/widgets/newest/show.phtml
<div class="t_news_newest"> <?php if ($this->articles != null) : ?> <ul> <?php foreach ($this->articles as $index => $article) : ?> <li> <h2> <?php if ($article->image_square) : ?><img src="<?php echo $article->image_square; ?>" width="60px" height="60px" /><?php endif; ?> <?php echo $article->title; ?> </h2> <p><?php echo $this->subString($article->description, 300); ?></p> <p class="t_news_newest_more"> <a href="<?php echo $this->url($article->getProperties(), 'news_article_details'); ?>"><?php echo $this->translator()->widget('more'); ?></a> </p> </li> <?php endforeach; ?> </ul> <?php endif; ?> <div class="clearfix"></div> </div>
- Add styles for this widget:
// skin/sample/plus/default.css
... /** * news/newest */ .t_news_newest { display: block; width: 960px; margin: 15px 0 0 0; padding: 20px 0; color: #777777; background-color: #FFFFFF; } .t_news_newest a { color: #95AD19; background-color: #FFFFFF; } .t_news_newest ul { margin: 0; padding: 0; list-style: none; } .t_news_newest li { display: block; float: left; width: 300px; margin: 0 30px 0 0; padding: 0; } .t_news_newest li:last-child { margin-right: 0; } .t_news_newest li h2 { display: block; width: 100%; height: 65px; margin: 0 0 15px; padding: 0 0 8px; font-size: 18px; font-weight: normal; line-height: normal; border-bottom: 1px solid #E7E6E6; } .t_news_newest li h2 img { float: left; margin: -15px 8px 0 0; padding: 5px; border: 1px solid #999999; } .t_news_newest p { margin: 0 0 25px 0; padding: 0; line-height: 1.6em; height: 155px; } .t_news_newest p.t_news_newest_more { display: block; text-align: right; line-height: normal; font-weight: bold; height: auto; } .t_news_newest p.t_news_newest_more a { padding: 8px 15px 10px; color: #FFFFFF; background-color: #95AD19; }
The most complete result:
Our homepage after performing this step:
But it does not look like our design exactly. In next post, I will guide you do some changes that make our homepage is the same as design version.
(To be continued ...)





