<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>giancarlo.dimassa.net &#187; php</title>
	<atom:link href="http://giancarlo.dimassa.net/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://giancarlo.dimassa.net</link>
	<description>A web programmer&#039;s blog</description>
	<lastBuildDate>Sun, 01 Feb 2009 20:33:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Website localization in PHP episode 1: Translate strings</title>
		<link>http://giancarlo.dimassa.net/2009/02/01/website-localization-in-php-episode-1-translate-strings/</link>
		<comments>http://giancarlo.dimassa.net/2009/02/01/website-localization-in-php-episode-1-translate-strings/#comments</comments>
		<pubDate>Sun, 01 Feb 2009 19:52:21 +0000</pubDate>
		<dc:creator>giancarlo</dc:creator>
				<category><![CDATA[Localization]]></category>
		<category><![CDATA[Pear]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://giancarlo.dimassa.net/2009/02/01/website-localization-in-php-episode-1-translate-strings/</guid>
		<description><![CDATA[Presenting a web site in multiple languages is a serious problem even when using dynamic server side technologies. In this article series, we'll try to figure out how to come out of common troubles. We'll start talking about string translation using a Pear module called Translation2.
 

Before doing that, allow me to make a premise.
Back [...]]]></description>
			<content:encoded><![CDATA[<p>Presenting a web site in <strong>multiple languages</strong> is a serious problem even when using <strong>dynamic server side technologies</strong>. In this article series, we'll try to figure out how to come out of common troubles. We'll start talking about <strong>string translation</strong> using a <a href="http://pear.php.net/"  target="_blank">Pear</a> module called <a target="_blank" href="http://pear.php.net/package/Translation2" >Translation2</a>.</p>
<p> <span id="more-173"></span>
</p>
<p>Before doing that, allow me to make a <strong>premise</strong>.</p>
<p>Back in the old days, we could <strong>copy</strong> our site structure <strong>as many times</strong> as the number of languages we had to work on, go deep into the pages and <strong>make necessary changes</strong>.</p>
<p>This worked well enough for <strong>static content</strong>, but had its <strong>downsides</strong>:</p>
<ul>
<li><font color="#55554e">There were problems <strong>updating</strong> content</font> </li>
<li><font color="#55554e">If you wanted to <strong>send</strong> the <strong>text</strong> to a <strong>translation service</strong>, you had to pull it from the pages <strong>yourself</strong></font> </li>
<li><font color="#55554e">When the text <strong>came back</strong> from the translator, you had to work <strong>again</strong> to insert it into the pages</font> </li>
<li><font color="#55554e">There isn't a <strong>standard way</strong> to format the text and many translation services <strong>don't understand HTML</strong>, so you had to exchange <strong>Word documents</strong> and manually convert the text into HTML again to preserve code <strong>cleaniness</strong></font> </li>
<li><font color="#55554e">There are problems with foreign <strong>character sets</strong>, you have to translate the <strong>HTML entities</strong> or convert between <strong>encodings</strong></font> </li>
<li><font color="#55554e">The first page on your site was nothing more than a <strong>list of languages</strong> and <strong>flags</strong>, that meant the <strong>first</strong> and <strong>most important</strong> page of all the site has <strong>no content</strong></font> </li>
<li><font color="#55554e">If you made a <strong>guess</strong> choosing your first page <strong>language</strong>, your other languages had to be <strong>manually selected</strong> by the user to make the switch.</font> </li>
<li><font color="#55554e">If you <strong>positioned certain elements</strong> into the text, you had to <strong>insert them manually again</strong> when you put the new content.</font> </li>
<li><font color="#55554e">There was no way for the <strong>translators to make the changes their selves</strong> without asking the webmaster, if they had not basic design skills.</font> </li>
<li><font color="#55554e">If they claimed such skills, <strong>you had to trust them enough</strong> to give them access the site source files and have faith in the fact they will not screw up anything.</font> </li>
</ul>
<p>The list can go on forever. Guess what? <strong>Dynamic websites are even worse!</strong> The problem is that most of the programmers build up websites <strong>pulling data</strong> from an <strong>archive</strong> (text files, a database connection, a service on the Intertubes) and <strong>put</strong> this materials into <strong><a href="http://giancarlo.dimassa.net/2007/07/06/how-to-separe-php-code-and-html-presentation-with-smarty-part-1/"  target="_blank">template</a> pages</strong>. When preparing or upgrading a site to be multilanguage, you had to have a way to pull <strong>different data</strong> from database <strong>for each idiom</strong>. Then you have to <strong>figure out</strong> how to translate the text into the templates.</p>
<p>There are many ways to solve these problems.</p>
<p><strong>You could manually change all the tables to hold the data for all idioms, and prepare a very big array that holds the strings you put into the template</strong>, put this big array in different files, one array for each language, and include the files as the user switches language.</p>
<p>This would be only the beginning, because then you should <strong>mantain</strong> all these arrays <strong>in sync</strong>. If you wanted to <strong>change</strong> this data from a control panel you have to <strong>put all the strings in a database</strong>. Manage language <strong>fallbacks</strong> (what if a string is not translated in a language?). What about <strong>caching</strong>? Then you had to <strong>write the procedures</strong> for <strong>querying, inserting and modifying</strong> such data.</p>
<p>Meet <a href="http://pear.php.net/package/Translation2"  target="_blank">Translation2</a>, the <a href="http://pear.php.net/"  target="_blank">Pear</a> module that does all of this for us, <strong>and much more</strong>. After installing it from the repository, we initialize it using this code:</p>
<blockquote><p>require_once 'Translation2.php';</p>
<p>$tr =&amp; Translation2::factory('mdb2',$db, array(      <br />'langs_avail_table'&#160;&#160;&#160;&#160;&#160;&#160;&#160; =&gt; 'translation_langs',       <br />'lang_id_col'&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; =&gt; 'id',       <br />'lang_name_col'&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; =&gt; 'name',       <br />'lang_meta_col'&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; =&gt; 'meta',       <br />'lang_errmsg_col'&#160;&#160;&#160;&#160;&#160;&#160;&#160; =&gt; 'error_text',       <br />'lang_encoding_col'&#160;&#160;&#160;&#160;&#160;&#160;&#160; =&gt; 'encoding',       <br />'strings_default_table'&#160;&#160;&#160; =&gt; 'translation_strings',&#160; <br /> 'string_id_col'&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; =&gt; 'ID',&#160; <br /> 'string_page_id_col'&#160;&#160;&#160; =&gt; 'page_id',&#160; <br /> 'string_text_col'&#160;&#160;&#160;&#160;&#160;&#160;&#160; =&gt; '%s',&#160; <br /> 'autoCleanCache'&#160;&#160;&#160;&#160;&#160;&#160;&#160; =&gt; true&#160; <br /> ) );</p>
</blockquote>
<p>Translation2 uses <a href="http://giancarlo.dimassa.net/2009/01/18/database-abstraction-in-php-with-mdb2/"  target="_blank">MDB2</a> as an archive foundation, so you have either to <strong>create</strong> a MDB2 connection, or <strong>reuse</strong> an existing one by passing the database object. As I presume you already use a database connection, I'll skip this part. Let's assume the database object is called $db. </p>
<p>Next we pass an array of <strong>parameters</strong>, specifying the <strong>gory details </strong>of the <strong>tables</strong> holding out our translation data. The example depicts two tables, <strong>translation_langs</strong> (that lists all <strong>languages</strong>) and <strong>translation_strings</strong> (that contains all the <strong>text</strong>). </p>
<p>The table that holds all the <strong>languages</strong> needs a column for the language <strong>id</strong> (like for example '<em>it</em>' or '<em>en</em>' or '<em>fr</em>'), <strong>name</strong> (like '<em>English</em>', or '<em>Espanol</em>', '<em>Italiano</em>',' '<em>Francais</em>'), <strong>meta</strong> (extended name, like '<em>American English</em>', usually matches the name), <strong>error text</strong> (when the string is not translated, for example '<em>not available</em>','<em>non disponibile</em>','<em>non traduit</em>') and encoding ('<em>iso-8859-1</em>','<em>utf-8</em>' and so on). You can call these columns and tables <strong>as you want</strong>, you just need to pass the names into the parameters array.</p>
<p>The <strong>strings table</strong> instead has an <strong>ID</strong> column (I put there an MD5 hash of the strings I want to be translated, but any text will do), the <strong>page ID</strong> column (so you separate and query strings for different pages), the <strong>text column</strong> for each language ('<em>%s</em>' in the example means the columns are called after the language ID) and any other parameter you wish to use.</p>
<p>To set the <strong>language ID</strong> and <strong>page ID</strong>, simply issue these two commands:</p>
<blockquote><p>$tr-&gt;setLang("it");     <br />$tr-&gt;setPageID("LOGIN_PAGE");</p>
</blockquote>
<p>You then start to initialize the so called '<strong><em>decorators</em></strong>', additional <strong>features</strong> of the translation system. The most useful ones are the <strong>Cache</strong> decorator (that uses the <a href="http://pear.php.net/package/Cache_Lite"  target="_blank">Cache Lite</a> Pear module) and the <strong>fallback</strong> decorator (to provide fallback strings in other languages).</p>
<p>An initialization sample of the Cache decorator follows:</p>
<blockquote><p>require_once &quot;Cache/Lite.php&quot;;&#160; <br /> $tr =&amp; $tr-&gt;getDecorator 'CacheLiteFunction');&#160; <br /> $tr-&gt;setOption('cacheDir', '/cache/lang/');&#160; <br /> $tr-&gt;setOption('lifeTime', 3600);</p>
</blockquote>
<p>with <em>getDecorator</em> you call the decorator. As you see we had to <strong>require</strong> the cache module file. Then we set the <strong>options</strong>: the <strong>time</strong> the system has to cache strings and the <strong>directory</strong> to use for caching. There are other options, feel free to explore.</p>
<p>The fallback system is even easier:</p>
<blockquote><p>$tr =&amp; $tr-&gt;getDecorator('Lang');      <br />$tr-&gt;setOption('fallbackLang', 'en');      <br />$tr-&gt;setOption('fallbackLang', 'it');</p>
</blockquote>
<p>that means "<em>if you can't find the string in the chosen language, fall back to english. If there isn't an english string, fall back to italian</em>". You can <strong>cascade languages</strong> as you wish. <strong>The function works on a string level</strong>, so you can have a complete translated website with only a pair of strings defaulted to another language.</p>
<p>To do queries you use commands like:</p>
<blockquote><p>$tr-&gt;get('PLEASE_LOGIN');</p>
</blockquote>
<p>to ask for a translated string,</p>
<blockquote><p>$tr-&gt;getRaw('PLEASE_LOGIN','LOGIN_PAGE');</p>
</blockquote>
<p>to ask all translations for a string specifying the Page ID,</p>
<blockquote><p>$tr-&gt;getLangs();</p>
</blockquote>
<p>to enumerate all languages, and so on.</p>
<p>You can at this point insert data into the tables yourself, or use the <strong>handy administration API</strong> that the translation system exposes. Simply initialize it (the parameters array is the same):</p>
<blockquote><p>$tr_admin = &amp;Translation2_Admin::factory([...continue the same way as the Translation2 constructor...]);</p>
</blockquote>
<p>Then you can <strong>issue commands</strong> like:</p>
<blockquote><p>$tr_admin -&gt;cleanCache();</p>
</blockquote>
<p>to <strong>clean the cache</strong></p>
<blockquote><p>$tr_admin-&gt;add("PLEASE_LOGIN', 'LOGIN_PAGE', array("en"=&gt;"Please insert your user name and password in the fields","it"=&gt;"Prego inserire il tuo nome utente e password"));</p>
</blockquote>
<p>to <strong>insert a new string</strong> into the database. </p>
<p>The API enables to easily <strong>add, modify and remove languages and strings</strong>.</p>
<p>If you want, Translation2 can use as a <strong>data source</strong> even an <strong>XML</strong> file or <strong>Gettext GNU .po / .mo compiled files</strong>. The decorators can also be used to <strong>convert between encodings</strong>.</p>
<p><strong>That's all, folks</strong>!</p>
<p>I hope you liked the article, stay tuned for the next episode of <strong>Web localization in PHP: language detection</strong> by subscribing to the <strong><a href="http://giancarlo.dimassa.net/feed/"  target="_blank">RSS</a> feed</strong>. </p>
<p>I would also be happy to answer to any <strong>questions</strong> you could have on the Translation2 module. In particular, I've tightly integrated it into a Markdown parser (a PHPBB code like language) and some plugins to provide realtime translations into <a href="http://giancarlo.dimassa.net/2007/07/06/how-to-separe-php-code-and-html-presentation-with-smarty-part-1/"  target="_blank"><strong>Smarty</strong></a><strong> templates</strong>.</p>
<p class="fbconnect_share"><fb:share-button class="url" href="http://giancarlo.dimassa.net/2009/02/01/website-localization-in-php-episode-1-translate-strings/" /></p>]]></content:encoded>
			<wfw:commentRss>http://giancarlo.dimassa.net/2009/02/01/website-localization-in-php-episode-1-translate-strings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Database abstraction in PHP with MDB2</title>
		<link>http://giancarlo.dimassa.net/2009/01/18/database-abstraction-in-php-with-mdb2/</link>
		<comments>http://giancarlo.dimassa.net/2009/01/18/database-abstraction-in-php-with-mdb2/#comments</comments>
		<pubDate>Sun, 18 Jan 2009 17:20:05 +0000</pubDate>
		<dc:creator>giancarlo</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Pear]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://giancarlo.dimassa.net/2009/01/18/database-abstraction-in-php-with-mdb2/</guid>
		<description><![CDATA[Coming from a Windows environment, the first thing I noticed about PHP was the lack of a standardized way to access databases across vendors. That is, you want to connect to a MySQL server, you use the command mysql_connect(); , for PostgreSQL it is pg_connect(); , for Microsoft SQL server is mssql_connect(); .

On Windows, instead, [...]]]></description>
			<content:encoded><![CDATA[<p>Coming from a Windows environment, the first thing I noticed about PHP was the <strong>lack of a standardized way</strong> to access databases <strong>across vendors</strong>. That is, you want to connect to a MySQL server, you use the command mysql_connect(); , for PostgreSQL it is pg_connect(); , for Microsoft SQL server is mssql_connect(); .</p>
<p><span id="more-169"></span></p>
<p>On <strong>Windows</strong>, instead, there is a layer called Open Database Connectivity (<strong>ODBC</strong>) that translates the calls from the software to the database, providing a <strong>common interface</strong> and <strong>emulating missing features</strong>. Each vendor provides a <strong>specific driver</strong>, that plugs into the architecture. Via ODBC even a <strong>text file</strong> or an <strong>Excel spreadsheet</strong> can be <strong>connected</strong> and <strong>queried</strong> like it was a <strong>database</strong>.</p>
<p>It has been natural to me to start searching the net for a PHP equivalent of that layer. Shortly after starting I found the <strong>de facto standard</strong> for database abstraction in PHP, called <strong>MDB2</strong>. Even if it has <strong>not the flexibility</strong> of a real ODBC layer, it's <strong>lack of complexity</strong> made it very popular among fellow web programmers at first, just to find out it's <strong>ability to grow</strong> via <strong>extensions</strong> and performing in a <strong>relatively easy way</strong> a set of very <strong>powerful</strong> and <strong>demanding operations</strong>.</p>
<p>MDB2 is a <strong>Pear</strong> library, so you need to follow a procedure to install it. Refer to the <a target="_blank" href="http://pear.php.net" >Pear website</a> for details.</p>
<p>Just after <strong>including</strong> the MDB2 scripts into your PHP file</p>
<blockquote><p>&lt;?</p>
<p>require_once ("MDB2.php");</p>
<p>?&gt;</p></blockquote>
<p>you need toÂ  create an <strong>instance</strong> of the database class, like this</p>
<blockquote><p>&lt;?</p>
<p>$dsn = "your database type://your user name:your password@your server/your database name";</p>
<p>$db = MDB2::factory($dsn);</p>
<p>?&gt;</p></blockquote>
<p>so you have a <strong>connection string</strong> that explains how to connect to the database, and an <strong>object</strong> with multiple methods to perform database operations. You don't need to know other details about the database apart from the ones you put in the Data Source Name (<strong>DSN</strong>), everything else is handled by the MDB2 object.</p>
<p>After that, you perform <strong>vendor agnostic</strong> <strong>queries</strong> like this</p>
<blockquote><p>$result = $db-&gt;queryAll ($sql);</p></blockquote>
<p>But, as said, the real power behind MDB2 is it's <strong>extensions system</strong>, for example</p>
<blockquote><p>$db-&gt;loadModule('Extended');</p>
<p>$tablename = "customers";</p>
<p>$data = array("name"=&gt;"Bob","surname"=&gt;"Michael");</p>
<p>$result= $db-&gt;extended-&gt;autoExecute($tablename,$data, MDB2_AUTOQUERY_INSERT);</p></blockquote>
<p>I've effectively <strong>inserted</strong> a new customer into my table <strong>without writing a single word of SQL</strong>, and without <strong>worrying</strong> of the actual<strong> table structure</strong>.</p>
<p>The same applies to <strong>interrogation queries</strong>, like this</p>
<blockquote><p>$tablename = "customers";</p>
<p>$where = "`NAME` = 'BOB' AND `SURNAME` = 'MICHAEL'";</p>
<p>$result= $db-&gt;extended-&gt;autoExecute($tablename,null,<br />
MDB2_AUTOQUERY_SELECT,<br />
$where,null,true,true);</p></blockquote>
<p>the only SQL here is the <strong>where clause</strong>, everything else is managed by the library.</p>
<p>You can even store an <strong>XML backup</strong> of your entire database with a few commands</p>
<blockquote><p>$db_schema_options = array(<br />
'use_transactions' =&gt; true,<br />
'log_line_break' =&gt; '&lt;br&gt;',<br />
'idxname_format' =&gt; '%s',<br />
'debug' =&gt; true,<br />
'quote_identifier' =&gt; true,<br />
'force_defaults' =&gt; true,<br />
'portability' =&gt; true<br />
);</p>
<p>$schema = MDB2_Schema::factory($dsn, $db_schema_options);</p>
<p>$definition = $schema-&gt;getDefinitionFromDatabase();</p>
<p>$schema_dump = $schema-&gt;dumpDatabase($definition, array(<br />
'output_mode' =&gt; 'file',<br />
'output' =&gt; $dumpfile<br />
), MDB2_SCHEMA_DUMP_ALL);</p></blockquote>
<p>where $dumpfile is the <strong>file name</strong> you want your backup to go to.</p>
<p>The notion of <strong>schemas</strong> enables your application to <strong>seamless</strong> <strong>update</strong> the <strong>database</strong> across <strong>updates</strong>. The MDB2 can made <strong>automatic modifications</strong> of your table definitions to match the ones into the schema.</p>
<p>The library enables to use complex database functions, like <strong>transactions</strong>, to make your web applications <strong>secure</strong> and overcome stability problems when <strong>delicate procedures</strong> are performed, like the cart checkout on a e-commerce website, a money transfer, or any other situation where a <strong>power outage</strong> or a <strong>software interruption</strong> can lead to an <strong>partial update</strong>. Transactions <strong>group</strong> the <strong>operations</strong> so that any error will lead to a <strong>rollback</strong>, preserving the state your data was prior to updating.</p>
<p>If later in the process you want to <strong>change</strong> your database, for example from MySQL to Microsoft SQL server? Simply <strong>change</strong> your <strong>DSN</strong> from mysql to mssql and <strong>you are ready</strong>!</p>
<p>Did you like this article? Subscribe to my <em>transactional</em> feeds and leave a comment!</p>
<p class="fbconnect_share"><fb:share-button class="url" href="http://giancarlo.dimassa.net/2009/01/18/database-abstraction-in-php-with-mdb2/" /></p>]]></content:encoded>
			<wfw:commentRss>http://giancarlo.dimassa.net/2009/01/18/database-abstraction-in-php-with-mdb2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to separe PHP code and HTML presentation with Smarty, part 2: installation</title>
		<link>http://giancarlo.dimassa.net/2007/07/10/how-to-separe-php-code-and-html-presentation-with-smarty-part-2-installation/</link>
		<comments>http://giancarlo.dimassa.net/2007/07/10/how-to-separe-php-code-and-html-presentation-with-smarty-part-2-installation/#comments</comments>
		<pubDate>Tue, 10 Jul 2007 12:05:23 +0000</pubDate>
		<dc:creator>giancarlo</dc:creator>
				<category><![CDATA[Smarty]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[presentation]]></category>
		<category><![CDATA[template]]></category>

		<guid isPermaLink="false">http://giancarlo.dimassa.net/2007/07/10/how-to-separe-php-code-and-html-presentation-with-smarty-part-2-installation-2/</guid>
		<description><![CDATA[Note: this is article is cut in parts, this is the the second one. Visit the first one if you don't know what Smarty is and why to use it. The post supposes basic PHP programming skills.
Ok, last time we examined the goods and bads of using Smarty, this time we'll install it.

First, make sure [...]]]></description>
			<content:encoded><![CDATA[<p>Note: this is article is cut in parts, this is the the second one. <a href="http://giancarlo.dimassa.net/2007/07/06/how-to-separe-php-code-and-html-presentation-with-smarty-part-1/" >Visit the first one</a> if you don't know what <a target="_blank" href="http://smarty.php.net" >Smarty</a> is and why to use it. The post supposes basic PHP programming skills.</p>
<p>Ok, last time we examined the goods and bads of using Smarty, this time we'll install it.</p>
<p><span id="more-27"></span></p>
<p>First, make sure you got the right PHP version, it needs at least the 4.0.6. This can be seen by writing an empy page and writing in it, then calling that page.</p>
<p>Next, download the <a target="_blank" href="http://smarty.php.net/download.php" >latest stable release</a> from the smarty web site.</p>
<p>I prefer to have all my external libraries and programs in the /lib folder, I strongly racommend it, so decompress the source in the /lib/smarty folder.</p>
<p>I group all my site files in the /site folder, that's very useful too, so create a site folder and put a php file in it, let's call it page.php.</p>
<p>First line in you should configure and initialize smarty, then put your commands to produce some data, and at the end call smarty to output the data in the templates.</p>
<p>The reduced minimal sample is</p>
<blockquote><p>&lt;?<br />
require ('/absolute/path/to/your/website/root/lib/smarty/Smarty.class.php');<br />
$smarty = new Smarty;<br />
?&gt;</p></blockquote>
<p>Keep an eye on capitals, as the code is case sensitive! This sample initializes adds the smarty code on top of your php file by inclusion. You'll need the absolute path to your smarty class, substitute as needed.</p>
<p>The smarty code defines a class, it explains to php what a "Smarty" is.<br />
Second line actually defines a variable, called $smarty. This variable points to a new object called Smarty. An object is an "istantiation" of a class, speaking simple an "item" made by following the "instructions". You can have more than a Smarty object in a php file, but rarely you need to.<br />
This Smarty item (let's call it object again and from now on) has properties (attributes) and can execute commands.</p>
<p>Now let's configure a thing or two. As I find it boring to always go checking out the document and site root and substituting, before going on let's write some code to autodetect this.</p>
<p>add this code on top</p>
<blockquote><p>define('DR', $_SERVER['DOCUMENT_ROOT']);</p></blockquote>
<p>Now the constant DR contains our document root, we can then modify the subsequent line this way:</p>
<blockquote><p>require (DR . '/lib/smarty/Smarty.class.php');</p></blockquote>
<p>each time you need the absolute path to your document root, you can refer to it by using DR.</p>
<p>Ok, this is all good, but if you load the script in the browser, it spits out a blank page.</p>
<p>What remains to do? Configure and execute some commands with the smarty object, of course! But before going on, I need to make a break for a security advice: templates doesn't "need" to be in your document root, they can stay everywhere, and it's highly suggested moving them outside this folder because they could be accessible from the web directly otherwise! Also, you'll need to set some permissions, if you're too loose it's possible you enable complete strangers to write their files everywhere, compromising your hosting server.</p>
<p>Now that I did some information technology terrorism, we can go on!</p>
<p>To give Smarty a command, you use the PHP syntax</p>
<blockquote><p>$smarty -&gt; command(argument [...]);</p></blockquote>
<p>while to set a property we use</p>
<blockquote><p>$smarty -&gt; property = value;</p></blockquote>
<p>We'll need to set up at least two directories, better three, and two of them should be writable by the web server (not the web users!).</p>
<p>So we create the /templates, /templates_compiled and /templates_cache folders, have templates_compiled and templates_cache writable (you can chmod them 770 from shell or even from the majority of the ftp clients, including the one in Dreamweaver!). Then we make smarty aware of the presence of these directories by adding these lines on bottom of the php file:</p>
<blockquote><p>$smarty-&gt;template_dir = DR . '/templates';<br />
$smarty-&gt;compile_dir = DR . '/templates_compiled';<br />
$smarty-&gt;config_dir = DR . '/site';<br />
$smarty-&gt;cache_dir = DR . '/templates_cache';</p></blockquote>
<p>Perfect, and we added en passant the config_dir, that tells the Smarty object where to find auxiliary configuration files. We set it to the /site folder itself.</p>
<p>Now, to assign some templates variables, use this</p>
<blockquote><p>$smarty-&gt;assign('firstname','Giancarlo');<br />
$smarty-&gt;assign('lastname','Di Massa');</p></blockquote>
<p>to load, parse and output a template, use</p>
<blockquote><p>$smarty-&gt;display('page.tpl');</p></blockquote>
<p>This will make the Smarty object go fetch the page.tpl file in the templates directory, so better have something here. Create a page.tpl file and put in it</p>
<blockquote><p>Hi {$firstname} {$lastname}, how are you?</p></blockquote>
<p>Save and reload the page.php file. It should output</p>
<blockquote><p>Hi Giancarlo Di Massa, how are you?</p></blockquote>
<p>Smarty substituted the two tags with the assigned variables in the page.php file!</p>
<p>If you are a programmer, go study the smarty syntax for programmers, it tells all the commands you can issue on the smarty object. If you're a designer instead, there is a list of all the tags you can use in the templates, you can edit them as if they were static HTML files sprinkled with "programmer's magic".</p>
<p>Most of the other template engines work the same way, for example the <a target="_blank" href="http://en.wikipedia.org/wiki/VlibTemplate" >VlibTemplate</a> or the <a target="_blank" href="http://www.raintpl.com/" >RainTPL </a>libraries.</p>
<p>One last word is about the MVC architectures. MVC stays for Model-View-Controller, is a way of separating content (the model) from the code (the controller) and the html (the view). A complete MVC system that takes care of all the aspects of data fetching and manipulation, from database queries to the output, is often called a framework. Smarty can be part of a MVC framework but it's not itself one. Some good PHP frameworks are <a target="_blank" href="http://www.cakephp.org/" >CakePHP</a> and <a target="_blank" href="http://www.symfony-project.com/" >Symfony</a>.</p>
<p>I use a MVC framework I did myself called Presenza.</p>
<p>Next time we'll better organize our php code and start having something more complex of an Hello World template, so stay tuned.</p>
<p class="fbconnect_share"><fb:share-button class="url" href="http://giancarlo.dimassa.net/2007/07/10/how-to-separe-php-code-and-html-presentation-with-smarty-part-2-installation/" /></p>]]></content:encoded>
			<wfw:commentRss>http://giancarlo.dimassa.net/2007/07/10/how-to-separe-php-code-and-html-presentation-with-smarty-part-2-installation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to separe PHP code and HTML presentation with Smarty, part 1</title>
		<link>http://giancarlo.dimassa.net/2007/07/06/how-to-separe-php-code-and-html-presentation-with-smarty-part-1/</link>
		<comments>http://giancarlo.dimassa.net/2007/07/06/how-to-separe-php-code-and-html-presentation-with-smarty-part-1/#comments</comments>
		<pubDate>Thu, 05 Jul 2007 23:09:03 +0000</pubDate>
		<dc:creator>giancarlo</dc:creator>
				<category><![CDATA[Smarty]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[presentation]]></category>
		<category><![CDATA[template]]></category>

		<guid isPermaLink="false">http://giancarlo.dimassa.net/2007/07/06/how-to-separe-php-code-and-html-presentation-with-smarty-part-1/</guid>
		<description><![CDATA[Note: this is article is cut in parts, this is the only the first one. More to come.
Programming in PHP without separating content and code can lead to unwanted results, low mantainability and slower production. Even nowadays you can find tons of scripts written by filling HTML pages with chunks of code.
If you do that,

Web [...]]]></description>
			<content:encoded><![CDATA[<p>Note: this is article is cut in parts, this is the only the first one. More to come.</p>
<p>Programming in PHP without separating content and code can lead to <strong>unwanted results</strong>, <strong>low mantainability </strong>and <strong>slower production</strong>. Even nowadays you can find tons of scripts written by filling HTML pages with chunks of code.</p>
<p><span id="more-20"></span>If you do that,</p>
<ul>
<li><strong>Web designers </strong>with no programming skills <strong>will not be able </strong>to customize easily your script's appearance.</li>
<li>If you want to change a site, for example a festivity or a redesign, you will need to face a <strong>big amount of work </strong>adding again all the PHP code to the new HTML pages.</li>
<li>You will <strong>not be able to focus </strong>on the project because you'll have to manage yourself all the aspect of HTML production, from loops to file inclusion.</li>
</ul>
<p>At my first web works I had these problems too. Building a new site required more work that I expected, because it was also difficult to reuse the code built for preceding customers. Then I started putting all my HTML in separate files, reading it with PHP and doing substitutions where needed. That was really better, I was able to change HTML when I wanted, but nothing more. Data that needed to be presented by "looping" the same HTML needed to be built in PHP, and in some situations I needed some sort of conditional programming in these so called 'template files'. I started to write a full fledged 'template engine' myself when a project saved me. I customized an e-commerce script for a project, and that script used an open source template engine. At first I was... how to say? Puzzled! As I looked over the template files I saw heaps of strange code.. it wasn't PHP so I tought that It was a really bad idea to push the things so further. Half of the script functionality lied in the template files themselves, and I was even a bit angry because <strong>I tought I had to learn a new language... inside the language</strong>!<br />
But as I was changing the look and feel of that site, so was my opinion of that system. It's not bad after all... no, it's good indeed.. wait, <strong>it's great</strong>! I <strong>never went back</strong> and used that engine myself for all my other projects: <strong>it's name is <a target="_blank" href="http://smarty.php.net" >Smarty</a></strong>.<br />
Here are some interesting functions:</p>
<ul>
<li>You can <strong>edit the template files </strong>as if they are HTML documents and <strong>separe </strong>them from the code with a <strong>little effort</strong>, if you don't want to learn the Smarty language.</li>
<li>Smarty language is much <strong>natural </strong>and <strong>template oriented </strong>than PHP, some things like iterate an array and outputting the same HTML code with the array data inside are <strong>very easy </strong>to do.</li>
<li>You can <strong>include other files </strong>from your templates, these files <strong>will be parsed </strong>too.</li>
<li>There's <strong>support </strong>for <strong>variables </strong>and <strong>constants</strong></li>
<li>You can <strong>produce </strong>a piece of HTML, then save it into a variable and <strong>reuse </strong>it later in the page, even modify it.</li>
<li>You can <strong>put decisional code in the templates</strong>, do <strong>math operations </strong>and <strong>store results </strong>in new variables.</li>
<li>Smarty has a <strong>plugin system </strong>with a very good repository, it's <strong>easy to write </strong>new plugins and they are <strong>autoloaded </strong>after you put them into their folder.</li>
<li>Has an <strong>advanced cache system </strong>that builds already decoded chunks of templates for <strong>speed </strong>purposes, so you actually can go <strong>even faster </strong>than mixing PHP with HTML.</li>
<li>There are many <strong>output buffering </strong>functions that give you abilities to change the whole page after it is generated and before is sent to the client, just for example <strong>you can with a single line change all your website</strong> and tell the system to add target="_new" to all external links.</li>
<li>You can "<strong>skin</strong>" your site as you want, it's really possible to do a complete makeup of a whole web project in a day or two, even <strong>change skins in realtime</strong>!</li>
<li>There's a <strong>template debugger</strong> to show data being passed to the engine!</li>
</ul>
<p>So, by now you would think that <strong>Smarty is the best thing after chocolate milk</strong>, but it has some negative aspects worth exploring:</p>
<ul>
<li><strong>All the HTML</strong> is sent <strong>at the same time</strong>, while with PHP you can send the page in chunks. However that required special attention when you wanted to set cookies, because these need to be sent before everything else.</li>
<li>Smarty is <strong>written in PHP itself</strong>. A C++ templating engine maybe would be faster (there are some out there), but then you would need to write new plugins in C++ too. You use smarty by <strong>actually loading it entirely in memory</strong> each time you need to access template files. If you need to output really simple HTML code in little pieces of code, and these pieces are in separate pages, don't use it. Just an example, if <strong>your script just outputs "OK"</strong> after the computations, it's <strong>better to use echo </strong>for the text.</li>
<li>You will need to <strong>learn a new language</strong>. It's simple and everything, but it's not rich as PHP itself, it's only a template language. The thing I miss more is the switch conditional construct, you need a series of if..elseif...elseif to emulate it. However this language is always used only to produce the presentation, you'll end up moving everything related to visualization to the templates, <strong>never using echo again</strong> if not for debug purposes.</li>
<li>It's <strong>not always easy to upgrade</strong> an existing project to using a template engine.</li>
<li>If you use an <strong>aggressive caching </strong>mode and make changes to the templates, those <strong>will not reflect online </strong>until you clean the template cache directory.</li>
<li>Smarty <strong>adds memory </strong>to your <strong>requirements</strong>, better have a look at the PHP memory_limit setting.</li>
<li>It has some good builtin plugins to produce drop downs listboxes, radio buttons and dates inputs in forms, but <strong>these elements require formatting the data in a certain way</strong>.</li>
<li>If you dive other scripts directly into the page, some symbols, like the <strong>curly braces</strong>, <strong>can collide with Smarty</strong>, that will think you are initiating a template command sequence, so you'll need to surround these pieces of code with literal tags, that tell Smarty not to parse them.</li>
</ul>
<p>As this argument is very long, I decided to cut it in parts. Next part will be about installing Smarty and starting using it. We'll also have a look at other template engines, and talk about full PHP frameworks that use the MVC paradigm, but don't worry about that right now.</p>
<p class="fbconnect_share"><fb:share-button class="url" href="http://giancarlo.dimassa.net/2007/07/06/how-to-separe-php-code-and-html-presentation-with-smarty-part-1/" /></p>]]></content:encoded>
			<wfw:commentRss>http://giancarlo.dimassa.net/2007/07/06/how-to-separe-php-code-and-html-presentation-with-smarty-part-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
