Requesting remote JSON or XML from a Smarty template

Joor Loohuis, December 19, 2010, 12029 views.

Occasionally it is necessary to get data from another domain to display on a webpage. Using Smarty templates it is very easy to fetch and display remote data in JSON or XML format.

Tags: , , , ,

One of the more common features of modern websites is displaying information that is fetched from external sources. This information is most often provided as structured data in the form of XML or JSON. A typical example is an RSS or Atom feed, but depending on the source it can be just about anything. The typical approach to displaying data is to create a script that fetches the data and passes it to the display subsystem. The essence of the process is that there rarely is any logic involved, and it is just about displaying data. It should be sufficient to do it all in a template.

HTTP requests from within a template

Conveniently enough, loading data from within a Smarty template is actually quite simple. Since Smarty allows us to use any PHP function as a template, we can feed the URL to the file_get_contents() function, and assign the result to a variable:

{assign var=data value='http://path.to/JSON'|file_get_contents}
{assign var=json value=$data|regex_replace:'/(^\(|\)$)/':''|json_decode}

As you can see above, we feed the result to the json_decode() function after cleaning up the leading and trailing parentheses. I've broken up the statement into two lines for the sake of readability. The result is that we have the complete JSON data in structured form in the $json template variable, and we can proceed with displaying the information we're interested in.

Normally speaking you would display JSON from within Javascript, but there are reasons why you would do it this way:

  • It avoids the Same Origin Policy in JavaScript, which essentially prevents requesting JSON from a piece of JavaScript that is not hosted on the same domain as the JSON itself.
  • The data will be displayed in the HTML that is generated on the server, rather than that it is added through JavaScript in the client, which is convenient because search engine crawlers and other clients that don't support JavaScript can access the data.

Similarly, XML data can be loaded into a variable and parsed into an XML structure:

{assign var=xml value='http://path.to/XML'|simplexml_load_file}

The $xml template variable will now contain a SimpleXMLElement object, from which you can access the subelements as a regular PHP object. The SimpleXML extension is part of PHP5, but there are similar solutions for PHP4 if you're still stuck with that.

The examples above use simple URLs, but of course there is no reason why you couldn't complicate matters. You could create a dynamic URL within your template, in which you could for example use information from the $smarty.request array, to forward page request parameters straight to the data request. Similarly, sources like $smarty.server $smarty.session could prove very useful.

Caveats

Of course there are some aspects that need to be taken into account. For a start, information fetched from an external source should not be trusted, and handled as you would handle any other untrustworthy data. Secondly, allowing file_get_contents() and simplexml_load_file to work with URLs requires that allow_url_fopen is enabled in the PHP configuration, which may introduce security vulnerabilities. If this is not an option, you could use some kind of proxy script that fetches the data with Curl or something similar, so that your template can access the data as a local file. A third point fo concern is that the data are fetched every time the template is displayed, which may affect performance. There are situations where it is desirable to always fetch the data, but in case it is not, a proxy script may again be the solution. It could test the age of the locally stored data, and in case it is too old, refresh it.

Social networking: Tweet this article on Twitter Pass on this article on LinkedIn Bookmark this article on Google Bookmark this article on Yahoo! Bookmark this article on Technorati Bookmark this article on Delicious Share this article on Facebook Digg this article on Digg Submit this article to Reddit Thumb this article up at StumbleUpon Submit this article to Furl

Talkback

respond to this article