<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>pingVision</title>
  <subtitle>Interactive Design + Development for Drupal websites</subtitle>
  <link rel="alternate" type="text/html" href="http://pingv.com/blog/rad/200710/changing-blocks-output-using-block-template"/>
  <link rel="self" type="application/atom+xml" href="http://pingv.com/node/3702/atom/feed"/>
  <id>http://pingv.com/node/3702/atom/feed</id>
  <updated>2007-10-11T18:15:26-05:00</updated>
  <entry>
    <title>Changing a Block&#039;s Output</title>
    <link rel="alternate" type="text/html" href="http://pingv.com/blog/rad/200710/changing-blocks-output-using-block-template" />
    <id>http://pingv.com/blog/rad/200710/changing-blocks-output-using-block-template</id>
    <published>2007-10-11T18:15:26-05:00</published>
    <updated>2007-10-11T18:15:26-05:00</updated>
    <author>
      <name>Rad</name>
    </author>
    <category term="Drupal" />
    <category term="theming" />
    <content type="html"><![CDATA[<h3>Block Template</h3>
<p>Sometimes the incredible power that Drupal gives me comes at the pain-in-the-assification of smaller things I took for granted in my pre-Drupal world.</p>
<p>For example, a client had given me a comp with a really small (100px wide by 50px tall) block for the login. Using logintoboggan, the default output for a logged in user is<br />
<blockquote>[username] | Log out</p></blockquote>
<p> on a single line and was wider than the box for most usernames. If this were a static html page, I could just replace the pipe (|) with a line break (&lt;br /&gt;). Going into the module and replacing it wouldn't be much more difficult, but upgrading the module at some future date would eliminate that change. You could try to remember to make the same change again, but that will cause headaches even if you do remember. Plus, if you have that mindset, it probably won't be the only thing you changed that your updates broke!</p>
<p>The way I solved it (with a little help) was to create a new block template file for that block (I didn't have to worry about a node view) and make the changes I needed within the template. This creates one additional file, but it's tiny and preserves your abiility to make clean backups and clean upgrades.</p>
<p>The first thing I did was to view the source code for the page I wanted, looking for the block name. I scrolled through until I found this line:</p>
<blockquote><p>&lt;div id="block-logintoboggan-0" class="block block-logintoboggan"&gt;</p></blockquote>
<p>which gave me the name of the block. I then made a copy of <code>block.tpl.php</code> in my theme's folder and renamed it <code>block-logintoboggan.tpl.php</code> cutting and pasting from the line above.</p>
<p>I then opened this file in a text editor and found the line that is displaying the html. I quickly found <code><span style="color: #000000"><span style="color: #0000BB">&lt;?php </span><span style="color: #007700">print </span><span style="color: #0000BB">$block</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">content</span><span style="color: #007700">; </span><span style="color: #0000BB">?&gt;</span></span></code>, which displays the content element of the block object. I treated that element as a black box and simply modified its content on output. The only thing I had to do was replace this line with a line that does a regular expression replacement. That's it! I didn't have to touch anything anywhere else.</p>
<p>Here's the new line to replace that one:</p>
<div class="codeblock"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /> </span><span style="color: #007700">print </span><span style="color: #0000BB">preg_replace</span><span style="color: #007700">(</span><span style="color: #DD0000">"/ \| /"</span><span style="color: #007700">, </span><span style="color: #DD0000">'&amp;lt;br /&amp;gt;'</span><span style="color: #007700">, </span><span style="color: #0000BB">$block</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">content</span><span style="color: #007700">); <br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
<p>This goes through the output, looking for the pipe character with a space on either side and replaces it with the line break. I had to escape (\) the pipe because it is a special character.</p>
<hr />
<p>So everything worked and I was excited enough to write this up for others, but then I found out that this isn't the standard way to do this! Although this method is fairly clean and easy, I was just informed that the more standard way is to override the function in <code>template.php</code> and is called a <strong>theme override</strong>.</p>
<hr />
<h3>Theme Override</h3>
<p>The pipe is created by a function in the logintoboggan module. If you open the main file (<code>logintoboggan.module</code>) and search for "|" or "log out" you'll find the function:</p>
<div class="codeblock"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">theme_lt_loggedinblock</span><span style="color: #007700">(){<br />&nbsp; global </span><span style="color: #0000BB">$user</span><span style="color: #007700">;<br />&nbsp; return </span><span style="color: #0000BB">check_plain</span><span style="color: #007700">(</span><span style="color: #0000BB">$user</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">name</span><span style="color: #007700">) .</span><span style="color: #DD0000">' | ' </span><span style="color: #007700">. </span><span style="color: #0000BB">l</span><span style="color: #007700">(</span><span style="color: #0000BB">t</span><span style="color: #007700">(</span><span style="color: #DD0000">'Log out'</span><span style="color: #007700">), </span><span style="color: #DD0000">'logout'</span><span style="color: #007700">);<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
<p>Now copy and paste that whole function into <code>template.php</code> in your theme folder and rename the function to <code>phptemplate_lt_loggedinblock</code>. You can override any function that has the prefix "theme_" by changing the prefix to "phptemplate_". (You could alternately change the prefix to your theme's name, but that would have the small disadvantage of breaking if you're theme name is changed.) This all works only if you are using the default theme engine, phptemplate. If you aren't, you presumably know a lot more than I do and aren't reading this.</p>
<p>Once you've pasted the function into template.php and renamed the prefix, you simply edit the function. In my case, I simply changed the pipe to a line break. Here's how it looked:</p>
<div class="codeblock"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">phptemplate_lt_loggedinblock</span><span style="color: #007700">(){<br />&nbsp; global </span><span style="color: #0000BB">$user</span><span style="color: #007700">;<br />&nbsp; return </span><span style="color: #0000BB">check_plain</span><span style="color: #007700">(</span><span style="color: #0000BB">$user</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">name</span><span style="color: #007700">) .</span><span style="color: #DD0000">'&lt;br /&gt;' </span><span style="color: #007700">. </span><span style="color: #0000BB">l</span><span style="color: #007700">(</span><span style="color: #0000BB">t</span><span style="color: #007700">(</span><span style="color: #DD0000">'Log out'</span><span style="color: #007700">), </span><span style="color: #DD0000">'logout'</span><span style="color: #007700">);<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
<blockquote><p>In case you weren't counting, that's only three quick steps: Find the function, paste it into template.php with a new prefix, and make your changes!</p></blockquote>
<p>If this html isn't overrideable, you should file a bug with the module and (try) to attach a patch that fixes it!</p>
<p>If you'd like to learn more about the guts behind this override, a good place to start is the well commented theme engine file, found here in your drupal install: <code>themes/engines/phptemplate/phptemplate.engine</code>.</p>
<p>I had fun peeking under Drupal's hood and was glad that something that would have been so daunting not long ago ended up seeming easy in the end!</p>
    ]]></content>
  </entry>
</feed>
