Smarty Hacks

While trying to solve someone elses problems, I came across the following: If you call {have_posts}, this will return a number as long as you are not on the last post to be displayed on the page. This is a standard WP function, but it is interesting to see it works under WP-MU. {the_post} will increment the post counter: basically skip a post, but will cause SQL errors. • My biggest hassle so far is that it doesn’t seem to be possible to assign stuff created by template tags to variables, other than by the very ugly {capture name=foo}{bar}{/capture} ; {$smarty.capture.foo} trick, which doesn’t work for Arrays: it just sets $smarty.capture.foo to ‘Array’, not very much use at all. {section} might be promising, but I doubt it: {foreach value=get_the_category item=each}{$each}{/foreach} just returns ‘get_the_category’.

Japanese Name

My japanese name is 中村 Nakamura (center of the village) 誠 Makoto (sincerity).
Take your real japanese name generator! today!
Created with Rum and Monkey’s Name Generator Generator.

Jaq’s is 藤原 Fujiwara (wisteria fields) 千秋 Chiaki (very fine in autumn). Amusingly, if you use Matt and Jaqueline, you get the same first name. Deep. 松尾 Matsuo (tail of a pine tree).

Unwell

Those of you who actually know me may know I’ve been off work for nearly a week: I’ve had some sort of a viral infection, which resulted in me having horrible head and body aches, sweating and coughing fits. I’m almost all better now (was about to leave for work this mornng at 7:30 when I got all lightheaded and needed to call in sick. Daily Manager wasn’t happy - supposed to call in by 7:00am when not coming in), but it really held me down. To the extent I wasn’t able to write anything on my blog. For 5 days!

Blogsome Themes, Part 2.

In the last post in this series, we learned how to upload images, and modify the StyleSheet so that these images were referenced by that. What we need to do now is to start putting the rest of the files into the right places. Before we can do this, we need to learn two things:

  • How the WordPress Template system and Loop ‘work’.
  • How Smarty Tags are created from a PHP function call.

We might start with the second one, just to be creative!

Smarty and PHP

PHP is a language used mainly in web page design and layout. It provides the ability to have complex, dynamic pages that are generated on-the-go. It is, however, a fully fledged language, and if someone has unfettered access to it on a server, they could do stuff that could bring the whole server down. This is usually not a problem for a blog, where you host your own server, or pay someone to host it for you. However, services that offer free blog hosting are perhaps more likely to be targetted, perhaps accidentally, perhaps deliberately, bu badly formed or malicious PHP code. Smarty Tags are a way to get around this. Basically, it’s a different way to write PHP code, designed to be used in template files. The syntax is very simple to understand: mostly you’ll come across things such as {bloginfo show='description'}. This was the last thing in my clipboard, it would, when placed in a template, display the Description (or Tagline, as Blogsome calls it) in the page. The first thing you’ll notice is that it is wrapped in curly brackets. Any Smarty Code must be wrapped in these for it to be interpreted: otherwise it will just be displayed as text. The second notable part is the function name. In this case, bloginfo. You can almost always find out more about a function call from the WordPress Codex. The final part is the argument. In this example, there is one argument, called show, with the value 'description'. This is where Smarty and PHP diverge: Smarty parameters or arguments must be named. Most of the pages in the Codex on Template Tags will give you a list of the arguments and their possible values. Lets see a couple more examples: One tag you will certainly need to use in your template is the_content. This will insert the text from an entry into the page. According to the Codex, it’s form is:

    <?php the_content('more_link_text', strip_teaser, 'more_file'); ?>

Now, because we are going to be using Smarty, we can make it look much nicer. The simplest version will be: {the_content} But, if we want to change the text, we’ll need to pass a value to the more_link_text argument: {the_content more_link_text='<BR /><BR />Read More' (Two line breaks, followed by the text Read More… will appear whenever the quicktag is used in any entry: this will only apply on an index page, the full entry will be shown on the individual page). Our last example will be to use the the_time tag. This will display the time and/or date of the post, depending on the argument that is given.

    <?php the_time('format'); ?>

You can see that the argument name appears to be format, however, it’s really d. This took me some time to figure out, and I only discovered it because I was using a previous Blogsome template to crib from. The value needs to be a valid PHP date format string. {the_time d='D j M Y'} Will give Mon 7 Jul 2020, or whatever the post date is. If you put a value in, and get only the time back (ie, 2:36pm), and this was not what you asked for, the argument or value may be incorrect. Okay, that’s all I’m going to write about how to get from PHP to Smarty: by all means read the Smarty Documentation if you don’t yet understand!

WordPress Templates

WordPress is pretty flexible in terms of template filenames, but generally there will be seven or so:

  • index.php • The main template file. Gets called when an index page is requested (such as the main page of the site).
  • sidebar.php • Contains the data that will go into the menu that usually appears on the side of a blog. Will be inserted when get_sidebar(); is called in PHP code.
  • header.php, footer.php • Contains the data that tells the top or bottom of the page what to look like.
  • post.php • The specific layout instructions for a post view.
  • comments.php • Will only be included if comments are active on the post.
  • page.php • For Page layout, rather than Posts. New to WordPress 1.5

The reason the files are split up is that this means they can be re-used: header and footer will be used at the top/bottom of post and page, as well as index, and sidebar will probably be used in several places as well. The problem with Blogsome is that there are only four files that can be edited: and one of them is the StyleSheet, which we have already done! So, we need to squeeze six or seven files into three. The easiest way to go is to understand that post.php needs to be placed into post.html, and comments.php needs to go into comments.html, and everything else needs to go into index.html. However, we cannot just copy and paste the data, we need to convert it. Before you start, it’s a good idea to make a copy of the data in each of the Blogsome files, so you can see how the theme that was there was doing it, and that should give you some ideas as to how might be a good way to do it yourself. We’ll start with post.html: it’s probably the simplest.

    <p class="post-date"><?php the_time('D j M Y'); ?></p>
    <div class="post-info"><h2 class="post-title"><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link: <?php the_title(); ?>"><?php the_title(); ?></a></h2>
    Posted by <?php the_author(); ?> under <?php the_category(' , '); ?><?php edit_post_link('(edit this)'); ?><br/><?php comments_popup_link('No Comments', '1 Comment', '[%] Comments'); ?>&nbsp;</div>
    <div class="post-content">
        <?php the_content(); ?>
        <div class="post-info">
            <?php wp_link_pages(); ?>                                           
        </div>
        <!--
            <?php trackback_rdf(); ?>
        -->
        <div class="post-footer">&nbsp;</div>
    </div>

This is the code that Patricia created for Connections, the theme I use. Let us try to understand the code so we can Smarty-fy it. The first line is the post date, using one of the tags we looked at before. The next two lines contain all of the post meta-data: it’s permalink, categories and so on. From there we have some layout tags (everything with a div is an HTML construct to divide the page up nicely), and then the actual content. This is followed by the link pages (Next/Previous Pages of a multi-page post), and then the Trackback info. Then we have the post footer (different to the footer.php I mentioned above!), and that’s about it. Do notice that the div tags that are opened on this page are all closed on this page: that makes it much easier to validate code. I also tend to indent my code so it’s clearer to follow, but that’s probably because I’d rather be coding in python. Convert all of your PHP function calls to the relevant Smarty Code: basically replace <?php by {, and ?> by }, and the arguments as discussed above. Remember to check the Codex if you run into trouble. Here’s what I changed mine into:

    <p class="post-date">{the_time d= 'D j M Y'}</p>
    <div class="post-info"><h2 class="post-title"><a href="{the_permalink}" rel="bookmark" title="Permanent Link: {the_title}">{the_title}</a></h2>
    Posted by {the_author} under {the_category}{php edit_post_link}<br/>{comments_popup_link zero='No Comments' one='1 Comment' more='[%] Comments'}&nbsp;</div>
    <div class="post-content">
        {the_content}
        <div class="post-info">
            {wp_link_pages}                                         
        </div>
        <!--
            {trackback_rdf}
        -->
        <div class="post-footer">&nbsp;</div>
    </div>

You can repeat these instructions with comments.php. There is some more stuff there that might require a bit of explanation, but have a crack. You should now be able to see some of your handiwork on any posts that are already in your blog. Now is a chance to check that out, and see if there are any inconsistencies that need to be ironed out.

Enclosures

Podcasting is what all of the kids are doing now: basically, from what I can tell, you just have an enclosure that is part of the post, and RSS readers can automatically download them. Blogsome doesn’t really have the ability to upload non-image filetypes (other than by renaming them to have an image-like extension), and anyway file sizes are limited to 300k, but it is possible to have enclosures that are files hosted elsewhere. Anyway, I found a page detailing how to set up enclosures, but it wouldn’t work for me. It turns out there is an array of arrays, and these need to be stepped through. The code I added to display a link to the enclosure after the post is as follows:

    {custom_fields}
    {if $enclosure != ''}
        <div class="enclosures">
            {foreach from=$enclosure item=enc}
                <div class="enclosure"><b>Attached Enclosure</b><br />
                    File: <a href="{$enc.0}">{$enc.0}</a><br />
                    Length: {$enc.1} bytes<br />
                    Type: {$enc.2}<br />
                </div>
            {/foreach}
        </div>
        {assign var='enclosure' value=''} <!-- reset enclosure variable again! -->
    {/if}

The only part I haven’t got working yet is the Length and Type fields: they are both blank. I’ll work harder….

Blogsome Page Templates

(This is an extension on the previous post). One of the major drawbacks of Blogsome is the handling of Pages _is not complete. You can create and manage Pages, but the display of them is sub-standard: there is no page.html template file as there is for _Posts _(post.html). However, I have figured out a stop-gap method of running pages through a template. I tried first to do this by adding a _Custom Field, as noted in the WordPress Codex, called _wp_page_template, and setting this value to post.html. This did not work, mainly (as far as I could tell) because the value did not ‘stick’. This seems to be a known issue with WordPress 1.5.1. I was able to get enclosure Custom Fields to work (almost: they only ever appeared to be an Array). The next way I figured out how to do it was by finding a variable that has a different value when a Page is being rendered, as opposed to a Post or Index, or Category, or Archive. The variable I discovered is {$smarty.server.SCRIPT_NAME}. This appears as '/wp-inst/pages' or '/wp-inst/index.php' under Blogsome. Fantastic! My next step was to have the following code where {$content} used to be in the Main Page Template:

    {if $smarty.server.SCRIPT_NAME == '/wp-inst/pages'}
        {assign var=page value=true}
        {capture name=the_content}{$content} {/capture}
        {include file='post.html'}
    {else}
        {assign var=page value=false}
        {$content}	
    {/if}

The first line, the {if} clause, finds out if it is indeed a page. The second line assigns ‘true’ to the variable {$page}, just as a way of making it less cumbersome to test again later. The third line stores the text that would normally appear in the body of the Page into the variable {$smarty.capture.the_content}. This will be used in place of {$the_content} in the post.html template. The fourth line puts the contents of the post.html file into the HTML stream. Just to be safe, I set the value of {$page} to false before the post.html file gets called normally by the {$content} tag. Then, in the post.html template file, I added the following code:

  • Where the content needs to go: {if $page == 'true'}{$smarty.capture.the_content}{$content}{/if}{the_content} There is no {else} required here, as {the_content} has no value.
  • Where the Post Title normally is, I made it: <a href="{if $page == 'true'}{$Smarty.server.PHP_SELF}{else}{permalink_link}{/if}" rel="bookmark" title="Permanent Link: {if $page == 'true'}{single_post_title}{/if}{the_title_rss}">{if $page == 'true'}{single_post_title}{/if}{the_title}</a> Basically, this replaces {permalink_link} by the URL of the current Page. I’ll have a bit of a think about how multi-page documents work if I can get them working. It replaces the {the_title} value by {single_post_title}, which works quite nicely.
  • I also made it so that the Date information is replaced by a Non-Breaking Space - in my template this means that a nice coloured box appears where the Date normally goes: this box is too small otherwise. {if $page == 'true'}&nbsp;{/if} The date data will be empty, so this should work okay.
  • Finally, I used {if $page != 'true'} ... {/if} to remove information that was not pertinant to a Page, such as the Post time, number of comments, category and so on. I also needed to have the {edit_post_link} skipped in this manner.

I have not yet made comments work properly: I’m not sure that this can be done with this hack, but they will not appear if you just do the things I’ve shown above. If you {include file=comments.html}, you will get the Comment Closed Notification.

Blogsome Pages

It’s no secret the Blogsome doesn’t have working Page Templates. The following code snippet is a starter on formatting of Pages like Posts:

    {if $smarty.server.SCRIPT_NAME == '/wp-inst/pages'}
        <!-- Do Stuff Here -->
    {/if}

At the moment, I’ve only figured out how to get the content to appear twice (!), but it’s a start: it only occurs with Pages! Update: I’ve got it working. It’s a bit ugly at the moment, and I’ll probably redo it with a function, but, still it works. See the Contact and About Pages in the Menubar for examples!

Converting Themes to Blogsome, Part 1

This is the first post in a series that will deal with Blogsome theme conversions. Part 2 can be found at Blogsome Themes, part 2. To begin with, you will need the following things:

  • A blog created with Blogsome. I suggest that if you already have a blog that has posts on it, you create a new one, just to tweak until the theme is just right. That way, your real blog will continue to work, no matter what. I’ll assume you have a Blogsome blog to test on, and know a bit about the backend (Dashboard, and where to find the various options/tools).
  • The files required for your theme. Alex King has a great list of themes, and runs competitions occasionally, so go visit there if you want to find one, and don’t have one already.
  • Firefox, with the EditCSS extension installed, or the [EditCSS][7] bookmark
  • Patience

You should also bookmark the following sites:

  • The [WordPress Codex][8], especially [Template Tags][9]
  • The [Smarty documentation][10]
  • The Blogsome [Forums][11]

I will use the following conventions in this document:

  • Button: a button that you click on. Will look different in each browser - usually it looks like the buttons in your Operating System, but not always.
  • Links that you need to click on will be bold.
  • Code that you modify will either look like this or this
  • Filenames will look like this.
  • Important, or unusual terms will be italic.

Converting a WordPress theme to Blogsome is not always easy, but is very rewarding, and you may learn something along the way. Finally, whilst I have gone to a lot of effort to ensure everything in this document is correct, I take no responsibility for any data loss. You should not have been working on your ‘proper’ blog anyway;).

Starting: Upload Image Files

Okay, let’s get started. The first thing you will want to do is upload all of your image files to your Blogsome blog. This is a much more time consuming process on Blogsome, as there is no automated way to do it. Under normal WordPress installations, you can usually FTP into the server, and dump all of the files you need. We need to click on the Upload button in the backend, and then on the Browse… button. Navigate to where the images you have as part of the theme are on your computer, and select the first one. Click the Upload button. When the page loads, record the information it gives you in a place you won’t lose it. Blogsome doesn’t provide the ability to look at lists of images, so if you forget it, you’ll need to try by trial and error to find it. Most of the images will have names that aren’t mangled by Blogsome’s server, so you should end up with a list of files like: /images/header.jpg /images/search.png /images/logo.gif What files you have will really depend on the theme you are using. There are some standard file names, but don’t expect them to be the same as everywhere else!

Update Style Sheet

You now are ready to insert your Style Sheet data. In the backend, click on Manage, and then on Files. Scroll down to the bottom of the page, and click on Site Style Sheet. After a few seconds, your Style Sheet will appear in the text editing box. We need to replace the entire contents of the text view with the contents of the theme’s stylesheet. This could have one of several names: typically it will end in .css, and more than likely it will be the only one. wp-layout.css, stylesheet.css and style.css are all likely candidates. We now need to examine the Style Sheet, and replace all instances of image filenames with their equivalent URL on your server. You can use relative URLs, so if you find something that looks like:

        background:url(img/content_bg.gif) repeat;

You will want to make it look like:

        background:url(/images/content_bg.gif) repeat;

You need to ensure you get every filename - otherwise the correct images will not appear! When you are done, you must save your changes. The Update Template! button will do this nicely. Righto! That’s the easy parts done. Next time, you will learn which template files Blogsome uses, and what data needs to go into each of them. You will also learn how to convert a PHP function to Smarty Tags. The next part of this article can be found at Blogsome Themes, part 2.

[7]: javascript:(function()%7Bfunction%20init()%7Bvar%20newline=unescape(%22%25%22+%220A%22),importCount=0,L=%5B%5D;dead=false;oldCSS=null;x=opener;ta=document.f.ta;ta.select();if(x.editStyles)%7Bta.value=x.editStyles.innerHTML;update();return;%7Dta.value=%22/%20Type%20CSS%20rules%20here%20and%20they%20will%20be%20applied%22+newline+%22to%20pages%20from%20’%22+location.host+%22’%22+newline+%22immediately%20as%20long%20as%20you%20keep%20this%20window%20open.%20/%22+newline+newline;function%20add(s)%7Bif(!s.disabled)%7Bvar%20y=%7Bsheet:s,readable:true,label:%22Imported%22,inline:false,shorturl:%22%22,fulltext:%22%22%7D;try%7Bfor(var%20k=0,m;m=s.cssRules%5Bk%5D;++k)if(m.type==3)add(m.styleSheet);%7Dcatch(er)%7By.readable=false;%7DL.push(y);if(s.ownerNode)%7By.label=s.ownerNode.tagName.toUpperCase()+%22-tag%22;if(!s.ownerNode.getAttribute(%22src%22)&&!s.ownerNode.href)y.inline=true;%7Dif(y.inline)%7By.label=%22Inline%20%22+y.label;y.fulltext=fix(s.ownerNode.innerHTML);%7Delse%20if(s.href.substr(0,13)==%22data:text/css%22)%7By.shorturl=%22%20contained%20in%20a%20data:%20URL%22;y.fulltext=fix(unescape(s.href.slice(14)));%7Delse%7B++importCount;y.importtext=%22@import%20%5C%22%22+s.href+%22%5C%22;%22;y.shorturl=%22%20%22+s.href.split(‘/’).reverse()%5B0%5D;if(!y.readable)%7By.fulltext=%22/%20Out-of-domain;%20imported%20above.%20/%22;%7Delse%20if(s.href.substr(0,5)!=%22http:%22)%7By.fulltext=%22/%20Non-http;%20imported%20above.%20/%22;%7Delse%7Bvar%20loadingText=%22/%20Loading%20(%22+(L.length-1)+%22)%20/%22;y.fulltext=loadingText;var%20p=new%20XMLHttpRequest();p.onload=function(e)%7Bta.value=ta.value.replace(y.importtext+newline,%22%22);y.fulltext=p.responseText;ta.value=ta.value.replace(loadingText,fix(y.fulltext));ta.value=ta.value.replace(firstNote+newline,%22%22);%7D;p.open(%22GET%22,s.href);p.send(null);%7D%7D%7D%7Dfunction%20fix(s)%7Bwhile((s%5B0%5D==newline)&&s.length%3E1)s=s.slice(1);while((s%5Bs.length-1%5D==newline)&&s.length%3E1)s=s.substr(0,s.length-1);s=s.replace(/@import.;/ig,function()%7Breturn%20%22/%20%22+RegExp.lastMatch+%22%20/%22;%7D);return%20s;%7Dfor(var%20i=0,ss;ss=x.document.styleSheets%5Bi%5D;++i)add(ss);var%20imports=%22%22,main=%22%22;var%20firstNote=%22/%20Style%20sheets%20whose%20contents%20could%20be%20loaded%20were%20/%22+newline+%22/%20imported%20instead.%20%20Rule%20order%20may%20be%20incorrect%20%20%20/%22+newline+%22/%20as%20a%20result.%20/%22+newline;if(importCount)%7Bta.value+=firstNote;%7Dfor(var%20i=0;ss=L%5Bi%5D;++i)%7Bif(ss.importtext)%7Bimports+=ss.importtext+newline;%7Dmain+=%22/%20%22+ss.label+%22%20style%20sheet%22+ss.shorturl+%22%20*/%22+newline;main+=newline;main+=ss.fulltext;main+=newline;main+=newline;main+=newline;%7Dta.value+=imports+newline+main;update();%7Dfunction%20update()%7Btry%7Bif(!x%7C%7Cx.closed)%7Bta.style.backgroundColor=%22%23ddd%22;return;%7Dx.editStyles;%7Dcatch(er)%7Bta.style.backgroundColor=%22%23fdc%22;setTimeout(update,150);dead=true;return;%7Dif(dead)%7Bdead=false;ta.style.backgroundColor=%22%22;oldCSS=null;%7Dif(!x.editStyles)%7Bvar%20newSS;newSS=x.document.createElement(%22style%22);newSS.type=%22text/css%22;x.document.getElementsByTagName(%22head%22)%5B0%5D.appendChild(newSS);x.editStyles=newSS;oldCSS=null;for(var%20i=0,ss;ss=x.document.styleSheets%5Bi%5D;++i)ss.disabled=true;%7Dif(oldCSS!=ta.value)%7BoldCSS=ta.value;x.editStyles.innerHTML=ta.value;%7DsetTimeout(update,150);%7Dy=open(‘’,’’,’resizable,scrollbars=yes,width=550,height=520’);y.document.write(‘%3Ctitle%3EEdit%20Styles%3C/title%3E%3Cstyle%3E.ec%20%7B%20width:%20100%25;%20height:%20100%25;%20border:%20none;%20margin:%200px;%20padding:%200px;%20%7D%3C/style%3E%3Cbody%20class=%22ec%22%3E%3Cform%20name=%22f%22%20style=%22margin:%200px;%22%20class=%22ec%22%3E%3Ctextarea%20name=%22ta%22%20wrap=%22soft%22%20style=%22margin:%200px;%20border:%200px;%20width:100%25;%20height:100%25;%22%20class=%22ec%22%3E%3C/textarea%3E%3Cscript%3E’+update+init+’init();%3C’+’/script%3E’);y.document.close();%7D)() [8]: http://codex.wordpress.org [9]: http://codex.wordpress.org/Template_Tags [10]: http://smarty.php.net/manual/en/ [11]: http://www.blogsome.com/forum/index.php

Internet Explorer Blocking

I just noticed a lovely little “Privacy Report” icon in the corner of my Blogsome Dashboard pages. Clicking it revealed the following: MS IE 6 Privacy Report: Blogsome Dashboard. I wonder what the rule is: is it to stop anything with the word Firefox in it?

Using /commands in Adium

I had a thought as to why it might not be a good idea to use /commands, instead of %_commands in Adium. If the text you type is part of a URL, then it will be replaced by the substituted text. For instance, http://itunes.schinckel.net/ would be replaced by http:/♫ The Chemical Brothers (Feat. The Flaming Lips) • The Golden Path.schinckel.net/, which is probably not desired behaviour. I’m not sure if this is a big enough deal for me to stop using them. I did also note that an afp:// had a smiley inserted into it instead… Update: You can add the following to the Info.plist:

                <key>Prefix Only</key>
                <true/>

Where the keyword appears. This will mean that the tag must be at the start of a ‘word’ for it work. Thanks, Reikon!