I’ve been using Smarty for a while now, and I absolutely MUST tell you – it’s a game-changer for PHP development. If you’re still mixing HTML and PHP code in your projects, you’re missing out on one of the most powerful tools in web development.
Smarty has completely transformed how I build web applications, and in this guide, I’ll show you everything you need to know about this incredible template engine. Whether you’re just starting out or looking to level up your PHP skills, this tutorial will take you from zero to Smarty hero in no time!
Smarty is the most powerful PHP template engine available today. Originally developed as part of PHP (hosted on smarty.php.net), it later evolved into an independent open-source project with its own dedicated website: Smarty.net.
“But why do I need a template engine when PHP can already do everything?” I hear you ask. Great question!
When I first started exploring template engines, I had the same question. After extensive research and years of practical experience, I can confidently say PHP Smarty template engine stands above the rest for several reasons:
While alternatives like Twig, Blade, or Plates each have their merits, Smarty remains the most comprehensive and battle-tested solution for PHP template needs.
Let’s dive right into setting up Smarty in your project!
First, download the latest Smarty library from the official website.
After downloading, extract the package and copy the ‘smarty’ directory to your application’s libraries folder. This is where you typically store third-party components.
To use Smarty effectively, we need to create a custom class that initializes all the necessary settings. This approach makes Smarty integration clean and maintainable.
Here’s a powerful custom class that handles all the configuration:
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
require_once(APPPATH.'libraries/smarty/Smarty.class.php');
/**
* MySmarty Class
*
* Initializes Smarty with custom settings for our application
*
* @final MySmarty
* @category Libraries
* @author Your Name
*/
class MySmarty extends Smarty {
/**
* Constructor - sets up all directory paths and configuration
*/
function __construct() {
parent::__construct();
// Define essential directory paths
$this->template_dir = APPPATH."/views/";
$this->config_dir = APPPATH."/conf/";
$this->compile_dir = APPPATH."/cache/";
// Disable caching for development (enable for production)
$this->caching = 0;
// Security settings (recommended for production)
$this->security_policy = new Smarty_Security($this);
$this->security_policy->php_handling = Smarty::PHP_REMOVE;
}
}Code language: HTML, XML (xml) With this class in place, you’re ready to start using Smarty throughout your application!
Smarty template files use the .tpl extension. Before writing your first template, make sure your IDE supports this extension. If you’re using VS Code, PhpStorm, or Netbeans, install the appropriate Smarty plugin for syntax highlighting and autocompletion.
Let’s create a simple example to demonstrate how Smarty works. First, here’s the PHP code for your controller:
<?php
// Create a new Smarty instance using our custom class
$smarty = new MySmarty();
// Assign variables to the template
$smarty->assign('pageTitle', 'Welcome to My Website');
$smarty->assign('userName', 'John Doe');
$smarty->assign('products', [
['name' => 'Laptop', 'price' => 999],
['name' => 'Smartphone', 'price' => 699],
['name' => 'Tablet', 'price' => 499]
]);
// Display the template
$smarty->display('homepage.tpl');Code language: HTML, XML (xml) Now, let’s create the corresponding template file homepage.tpl:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{$pageTitle}</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header>
<h1>Welcome, {$userName}!</h1>
</header>
<main>
<h2>Our Products</h2>
<ul class="product-list">
{foreach $products as $product}
<li class="product-item">
<span class="product-name">{$product.name}</span>:
<span class="product-price">${$product.price}</span>
</li>
{/foreach}
</ul>
</main>
<footer>
© {$smarty.now|date_format:"%Y"} My Company
</footer>
</body>
</html>Code language: HTML, XML (xml) When rendered, this template will display the user’s name, a list of products, and a dynamic copyright year.
Now that you’ve seen a basic example, let’s explore the most commonly used Smarty syntax features that will make your templates powerful and flexible.
Variables in Smarty are enclosed in curly braces: {$variableName}. You can also apply modifiers to transform how variables are displayed:
{* Basic variable output *}
<p>{$userName}</p>
{* Upper case modifier *}
<p>{$userName|upper}</p>
{* String truncation with ellipsis *}
<p>{$longDescription|truncate:100:"..."}</p>
{* Number formatting *}
<p>{$price|number_format:2}</p>
{* Date formatting *}
<p>{$timestamp|date_format:"%B %e, %Y"}</p>Code language: HTML, XML (xml) Smarty provides powerful conditional statements to control what gets displayed:
{if $user.isLoggedIn}
<div class="welcome-message">Welcome back, {$user.name}!</div>
<a href="/dashboard">Go to Dashboard</a>
{elseif $user.hasVisitedBefore}
<div class="returning-visitor">Welcome back! Please log in.</div>
{else}
<div class="new-visitor">First time here? Sign up now!</div>
{/if}Code language: HTML, XML (xml) Working with collections is easy using Smarty’s loop constructs:
{* Foreach loop - modern and recommended *}
<ul class="menu">
{foreach $menuItems as $item}
<li class="{if $item.isActive}active{/if}">
<a href="{$item.url}">{$item.label}</a>
</li>
{foreachelse}
<li>No menu items available</li>
{/foreach}
</ul>
{* Section loop - older style but still useful *}
<div class="gallery">
{section name=photo loop=$photos}
<div class="photo-item" id="photo-{$smarty.section.photo.iteration}">
<img src="{$photos[photo].url}" alt="{$photos[photo].caption}">
</div>
{sectionelse}
<p>No photos found</p>
{/section}
</div>Code language: HTML, XML (xml) Smarty provides powerful helpers for generating HTML elements:
{* Generate select dropdown *}
{html_options name="country" options=$countries selected=$userCountry}
{* Generate checkboxes *}
{html_checkboxes name="interests" options=$availableInterests selected=$userInterests}
{* Generate radio buttons *}
{html_radios name="subscription" options=$planOptions selected=$currentPlan}
{* Generate a table *}
{html_table loop=$tableData cols=5 tr_attr=$rowAttributes td_attr=$cellAttributes}Code language: PHP (php) Once you’re comfortable with the basics, these advanced features will take your Smarty skills to the next level.
Smarty allows you to create custom functions to extend template capabilities:
<?php
// Register a custom function in PHP
$smarty->registerPlugin('function', 'profile_url', 'generate_profile_url');
function generate_profile_url($params, $smarty) {
$userId = isset($params['id']) ? $params['id'] : 0;
return '/profile/' . $userId;
}Code language: HTML, XML (xml) Then use it in your template:
<a href="{profile_url id=$user.id}">View Profile</a>Code language: HTML, XML (xml) One of Smarty’s most powerful features is template inheritance, which allows you to create a base layout and extend it with specific content:
Base template (layout.tpl):
<!DOCTYPE html>
<html>
<head>
<title>{block name="title"}Default Title{/block}</title>
<link rel="stylesheet" href="/css/main.css">
{block name="stylesheets"}{/block}
</head>
<body>
<header>
{include file="partials/navbar.tpl"}
</header>
<main>
{block name="content"}
Default content
{/block}
</main>
<footer>
{include file="partials/footer.tpl"}
</footer>
{block name="scripts"}{/block}
</body>
</html>Code language: HTML, XML (xml) Child template (product-page.tpl):
{extends file="layout.tpl"}
{block name="title"}{$product.name} - Our Store{/block}
{block name="stylesheets"}
<link rel="stylesheet" href="/css/product.css">
{/block}
{block name="content"}
<div class="product-detail">
<h1>{$product.name}</h1>
<div class="product-image">
<img src="{$product.image}" alt="{$product.name}">
</div>
<div class="product-info">
<p class="price">${$product.price}</p>
<p class="description">{$product.description}</p>
<button class="buy-now">Add to Cart</button>
</div>
</div>
{/block}
{block name="scripts"}
<script src="/js/product.js"></script>
{/block}Code language: HTML, XML (xml) Smarty’s caching system can dramatically improve performance:
<?php
// Enable caching with a 3600 second (1 hour) lifetime
$smarty->caching = Smarty::CACHING_LIFETIME_CURRENT;
$smarty->cache_lifetime = 3600;
// Cache different versions based on category ID
$smarty->display('products.tpl', 'category_'.$category_id);Code language: HTML, XML (xml) In your template, you can control what parts are cached:
{* This will always be evaluated, even when page is cached *}
{nocache}
User: {$current_user.name} | Time: {$smarty.now|date_format:"%H:%M:%S"}
{/nocache}
{* This content will be cached *}
<div class="product-list">
{foreach $products as $product}
<div class="product-item">{$product.name}</div>
{/foreach}
</div>Code language: HTML, XML (xml) Let’s put everything together with a real-world example of building a simple blog using Smarty.
<?php
class BlogController {
private $smarty;
private $postsModel;
public function __construct() {
$this->smarty = new MySmarty();
$this->postsModel = new PostsModel();
}
public function index() {
// Get latest posts
$posts = $this->postsModel->getLatestPosts(10);
$categories = $this->postsModel->getAllCategories();
// Assign data to template
$this->smarty->assign('pageTitle', 'My Awesome Blog');
$this->smarty->assign('posts', $posts);
$this->smarty->assign('categories', $categories);
$this->smarty->assign('featuredPost', $posts[0]);
// Display template
$this->smarty->display('blog/index.tpl');
}
public function viewPost($postId) {
// Get post details
$post = $this->postsModel->getPostById($postId);
$comments = $this->postsModel->getCommentsForPost($postId);
// Assign data to template
$this->smarty->assign('pageTitle', $post['title']);
$this->smarty->assign('post', $post);
$this->smarty->assign('comments', $comments);
// Display template
$this->smarty->display('blog/post.tpl');
}
}Code language: HTML, XML (xml) Base Layout (blog/layout.tpl):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{block name="title"}{$pageTitle}{/block}</title>
<link rel="stylesheet" href="/css/blog.css">
{block name="styles"}{/block}
</head>
<body>
<header class="site-header">
<div class="container">
<h1 class="site-title"><a href="/blog">My Awesome Blog</a></h1>
<nav class="site-nav">
<ul>
<li><a href="/blog">Home</a></li>
<li><a href="/blog/categories">Categories</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
</div>
</header>
<main class="site-content">
<div class="container">
{block name="content"}{/block}
</div>
</main>
<aside class="sidebar">
<div class="container">
{block name="sidebar"}
<div class="widget categories">
<h3>Categories</h3>
<ul>
{foreach $categories as $category}
<li><a href="/blog/category/{$category.slug}">{$category.name}</a></li>
{/foreach}
</ul>
</div>
{/block}
</div>
</aside>
<footer class="site-footer">
<div class="container">
<p>© {$smarty.now|date_format:"%Y"} My Awesome Blog. All rights reserved.</p>
</div>
</footer>
{block name="scripts"}{/block}
</body>
</html>Code language: HTML, XML (xml) Blog Home Page (blog/index.tpl):
{extends file="blog/layout.tpl"}
{block name="content"}
<div class="featured-post">
<h2><a href="/blog/post/{$featuredPost.id}">{$featuredPost.title}</a></h2>
<div class="meta">
Posted on {$featuredPost.date|date_format:"%B %e, %Y"} in
<a href="/blog/category/{$featuredPost.category.slug}">{$featuredPost.category.name}</a>
</div>
<div class="featured-image">
<img src="{$featuredPost.featured_image}" alt="{$featuredPost.title}">
</div>
<div class="excerpt">
{$featuredPost.excerpt}
</div>
<a href="/blog/post/{$featuredPost.id}" class="read-more">Read More</a>
</div>
<div class="recent-posts">
<h3>Recent Posts</h3>
<div class="post-grid">
{foreach $posts as $post name=posts}
{if !$smarty.foreach.posts.first}
<div class="post-card">
<div class="post-image">
<img src="{$post.thumbnail}" alt="{$post.title}">
</div>
<h4><a href="/blog/post/{$post.id}">{$post.title}</a></h4>
<div class="meta">
{$post.date|date_format:"%B %e, %Y"}
</div>
<div class="excerpt-short">
{$post.excerpt|truncate:100:"..."}
</div>
</div>
{/if}
{/foreach}
</div>
</div>
{/block}Code language: JavaScript (javascript) Single Post Page (blog/post.tpl):
{extends file="blog/layout.tpl"}
{block name="title"}{$post.title} - {$pageTitle}{/block}
{block name="content"}
<article class="single-post">
<header class="post-header">
<h1>{$post.title}</h1>
<div class="meta">
Posted by <span class="author">{$post.author.name}</span> on
<time datetime="{$post.date|date_format:"%Y-%m-%d"}">{$post.date|date_format:"%B %e, %Y"}</time> in
<a href="/blog/category/{$post.category.slug}">{$post.category.name}</a>
</div>
</header>
{if $post.featured_image}
<div class="featured-image">
<img src="{$post.featured_image}" alt="{$post.title}">
</div>
{/if}
<div class="post-content">
{$post.content}
</div>
<div class="post-tags">
{if !empty($post.tags)}
<span>Tags:</span>
{foreach $post.tags as $tag}
<a href="/blog/tag/{$tag.slug}" class="tag">{$tag.name}</a>
{/foreach}
{/if}
</div>
<div class="post-sharing">
<span>Share:</span>
<a href="https://twitter.com/intent/tweet?url={$smarty.server.REQUEST_URI|escape:'url'}&text={$post.title|escape:'url'}" class="twitter" target="_blank">Twitter</a>
<a href="https://www.facebook.com/sharer/sharer.php?u={$smarty.server.REQUEST_URI|escape:'url'}" class="facebook" target="_blank">Facebook</a>
<a href="https://www.linkedin.com/sharing/share-offsite/?url={$smarty.server.REQUEST_URI|escape:'url'}" class="linkedin" target="_blank">LinkedIn</a>
</div>
</article>
<section class="comments">
<h3>{$comments|@count} Comments</h3>
{if !empty($comments)}
<div class="comment-list">
{foreach $comments as $comment}
<div class="comment" id="comment-{$comment.id}">
<div class="comment-avatar">
<img src="{$comment.avatar|default:'/images/default-avatar.png'}" alt="{$comment.name}">
</div>
<div class="comment-content">
<div class="comment-meta">
<span class="comment-author">{$comment.name}</span>
<span class="comment-date">{$comment.date|date_format:"%B %e, %Y at %H:%M"}</span>
</div>
<div class="comment-text">
{$comment.content}
</div>
</div>
</div>
{/foreach}
</div>
{else}
<p class="no-comments">Be the first to comment!</p>
{/if}
<div class="comment-form">
<h4>Leave a Comment</h4>
<form action="/blog/comment/{$post.id}" method="post">
<div class="form-group">
<label for="name">Name</label>
<input type="text" id="name" name="name" required>
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="comment">Comment</label>
<textarea id="comment" name="comment" rows="5" required></textarea>
</div>
<button type="submit" class="submit-comment">Post Comment</button>
</form>
</div>
</section>
{/block}
{block name="sidebar"}
{$smarty.block.parent}
<div class="widget related-posts">
<h3>Related Posts</h3>
<ul>
{foreach $post.related as $related}
<li>
<a href="/blog/post/{$related.id}">{$related.title}</a>
</li>
{/foreach}
</ul>
</div>
{/block}Code language: HTML, XML (xml) After years of working with Smarty, I’ve learned some valuable lessons:
{$description|strip_tags|truncate:200:"..."|escape}{debug} anywhere in your template to display a debugging console with all available variables.Smarty has transformed how I build PHP applications, and I’m confident it will do the same for you. The separation of logic and presentation, combined with powerful features like template inheritance and caching, makes Smarty an essential tool for any serious PHP developer.
Start small by implementing Smarty in a new project or gradually integrating it into existing applications. As you become more comfortable with its syntax and capabilities, you’ll wonder how you ever developed without it!
Also, explore comprehensive PHP Smarty Examples and Tips!
To deepen your Smarty knowledge, check out these valuable resources:
Have questions about implementing Smarty in your project? Drop a comment below! Happy coding! 😊
Ever wondered what happens when you run Python code? The Python runtime environment—comprising the interpreter, virtual machine, and system resources—executes your code through bytecode compilation…
Tired of repetitive tasks eating up your time? Python can help you automate the boring stuff — from organizing files to scraping websites and sending…
Learn python file handling from scratch! This comprehensive guide walks you through reading, writing, and managing files in Python with real-world examples, troubleshooting tips, and…
This website uses cookies.
View Comments
Nice tutorial Ali Ahsan Rana. I like your code in Codeiginter. I also see your Codeiginter plus functionality and CRUD system. That is amazing. Thanks for sharing information.
Thanks bro really useful.
Hi, I am new to smarty and php. I have a query where do you create a smarty object for customized class? is it separate file? and as per your example $smarty->display('index.tpl'), is index.tpl is the file where you are going to show these variables (title and description)?
Thanks
It's nice, I get the lot of information in the site
Thanks to you
hi used smarty. i dont know where this error coming from.MDB2 error: insufficient permissions
can u help me??
Hi
I am new to smarty .
I am getting an error on homepage of mysite. MDB2 error insuffisient permissions.
can anybody help me??
Thanks for your post. I have a question though, how do i use smarty to convert html to tpl that can be hyip compatible? Thanks.