
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!
What is Smarty and Why You Need It Right Now
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!
The Benefits of Using Smarty Are Massive:
- Perfect Separation of Logic and Presentation: Smarty forces you to build properly layered applications. Your business logic stays in PHP files, while presentation logic lives in template files – making your code incredibly maintainable.
- Eliminates Code Duplication: Stop writing the same presentation code over and over! Smarty provides pre-built solutions for common presentation tasks, saving you countless hours.
- Enhanced Security: Smarty automatically escapes variables to prevent XSS attacks, protecting your application from common security threats.
- Improved Team Collaboration: Designers can work on templates without touching PHP code, while developers focus on business logic – resulting in faster development cycles.
- Built-in Caching: Smarty’s advanced caching system dramatically improves application performance with minimal effort.
Why Choose Smarty Over Other Template Engines?
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:
- Maturity: Smarty has been around since 2001 and powers thousands of production websites.
- Active Community: With a vibrant community, you’ll always find support when needed.
- Performance: Smarty compiles templates to PHP code, delivering exceptional speed.
- Flexibility: From simple websites to complex applications, Smarty scales beautifully.
While alternatives like Twig, Blade, or Plates each have their merits, Smarty remains the most comprehensive and battle-tested solution for PHP template needs.
Getting Started: Installation and Setup
Let’s dive right into setting up Smarty in your project!
Installation
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.
Configuration
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 in Action: Basic Usage
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.
Creating Your First Smarty Template
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.
Essential Smarty Syntax: Templates That Do Heavy Lifting
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 and Modifiers
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)
Conditional Logic
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)
Loops and Iterations
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)
Built-in HTML Helpers
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)
Advanced Features That Make Smarty Unbeatable
Once you’re comfortable with the basics, these advanced features will take your Smarty skills to the next level.
Custom Functions and Plugins
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)
Template Inheritance
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)
Caching for Performance
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)
Real-World Example: Building a Dynamic Blog
Let’s put everything together with a real-world example of building a simple blog using Smarty.
Controller Code (PHP)
<?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)
Template Files
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)
Common Pitfalls and Pro Tips
After years of working with Smarty, I’ve learned some valuable lessons:
Pitfalls to Avoid:
- Putting Business Logic in Templates: Keep templates focused on presentation. Complex calculations and data manipulation belong in PHP code.
- Not Using Template Inheritance: Duplicating code across templates leads to maintenance nightmares. Always leverage template inheritance for consistent layouts.
- Forgetting to Escape Output: While Smarty provides auto-escaping, be vigilant about security, especially when handling user input.
- Ignoring Caching: In high-traffic applications, failing to implement caching can result in poor performance.
Pro Tips:
- Use Custom Plugins: Create reusable custom plugins for complex UI components that appear throughout your application.
- Organize Templates Logically: Structure your templates in directories that mirror your application’s organization.
- Leverage Modifier Chaining: Combine multiple modifiers for powerful transformations: smarty
{$description|strip_tags|truncate:200:"..."|escape}
- Debug with {debug}: Insert
{debug}
anywhere in your template to display a debugging console with all available variables. - Learn Smarty’s Configuration Files: Use .conf files for storing translations and application settings that templates can access.
Conclusion: Level Up Your PHP Development with Smarty
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!
Further Resources
To deepen your Smarty knowledge, check out these valuable resources:
Have questions about implementing Smarty in your project? Drop a comment below! Happy coding! 😊
Discover more from CodeSamplez.com
Subscribe to get the latest posts sent to your email.
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.