📜 ⬆️ ⬇️

My Smarty Plugins

Recently, a PHP blog was flying on an article about template inheritance in Smarty , which made me think: I have been using Smarty for several years as the main template engine and I have a lot of plug-ins written by me to extend the basic functionality. Why not share your experience with the community and listen to others? I think many have something to share on this topic ...

0. Disclaimer


  1. This article is not written to convince / dissuade the use of Smarty. Use - maybe you will find something interesting here, no - please refrain from holivars. I know perfectly well how ugly, vile and slow Smarty is compared to [insert the name of your favorite template engine] . The article is not about that.
  2. Plug-ins were created over several years, so the style is somewhat mixed, in some situations they are not very friendly with each other. I share ideas that are very simple to implement, so it’s not worth finding fault with my implementation. Nevertheless, I will be grateful for reasonable criticism.
  3. Plug-ins often revolve as part of a self-made micro-framework that supports multilingualism. In the above sources, I replaced all the calls to the framework functions with variables, so the code looks demo due to variables, global and other adjustments.


1. Modifiers


The standard Model-View-Controller (MVC) architecture implies the separation of logic, data and appearance. In theory, everything is beautiful. But in practice, what about, say, the date of birth, which lies in the database as “1980-01-19”, and the user needs to output “January 19, 1980”? Who should do this? This is where many developers who are known to me start to break the logic. This is the very transformation of the appearance where they just don’t stick in (yes, yes, it was possible to meet even those who keep it in the database as a text string).

I think it is clear from the title of the article that I consider it right to load the template with these transformations: let the mapping itself decide in what form and how to display the data.
')
So let's get started ...

1.1. Date Output

It would seem - there is a standard date_format modifier, what else is needed? But I am such a bore, and it's not enough for me:


1.1.1. Date modifier

Appearance: {$ variable | date: 'format'}. The 'date', 'datetime' or 'time' is used as an optional format. The modifier solves all the problems described earlier.

File smarty / plugins / modifier.date.php ( download )
/ **
* Date modifier: unix_timestamp => date
*
* param string $ string
* param string $ format
* return string
* /
function smarty_modifier_date ($ string , $ format = 'datetime' )
{
global $ Language;
if (! is_numeric ($ string ))
{
trigger_error ( 'Modifier date: invalid input data!' );
}

if ($ format == 'date' )
{
$ format = $ Language [ 'global' ] [ 'date_format' ];
}
elseif ($ format == 'datetime' )
{
$ format = $ Language [ 'global' ] [ 'datetime_format' ];
}
elseif ($ format == 'time' )
{
$ format = $ Language [ 'global' ] [ 'time_format' ];
}
else
// Clinical case
trigger_error ( 'Modifier date: invalid format specified!' );

$ format = str_replace ( '% B' , $ Language [ 'months' ] [date ( 'n' , $ string )], $ format);

return strftime ($ format, $ string );
}


I draw attention to the magic global variable $ Language, which stores the output formats of dates for different languages ​​and the normal names of the months in the native language of the visitor.

Those. for English:
$ Language [ 'global' ] [ 'date_format' ] = '% B% d,% Y' ;
$ Language [ 'global' ] [ 'time_format' ] = '% H:% M' ;
$ Language [ 'global' ] [ 'datetime_format' ] = '% B% d,% Y% H:% M' ;

And for Russian:
$ Language [ 'global' ] [ 'date_format' ] = '% d% B% Y' ;
$ Language [ 'global' ] [ 'time_format' ] = '% H:% M' ;
$ Language [ 'global' ] [ 'datetime_format' ] = '% d% B% Y% H:% M' ;


The contents of $ Language ['months'] leave for an independent composition;)

In some projects, this modifier additionally lays down the task of recalculating the time zone, depending on the user's settings. A trifle, but it's nice - you do not need to make sharp gestures for this in the code of the modules.

1.1.2. Date_sql modifier

Completely similar to the previous case. The only difference is in the input data. This one expects not UNIX_TIMESTAMP, but MySQL DATETIME or DATE.

File smarty / plugins / modifier.date_sql.php ( download )
/ **
* Date_sql modifier: convert sql date / datetime to date
*
* param string $ string
* param string $ format
* return string
* /
function smarty_modifier_date_sql ($ string , $ format = 'datetime' )
{
global $ Language;

// Is it a date?
if (! preg_match ( '/ ^ (\ d {4}) - (\ d {1,2}) - (\ d {1,2}) $ /' , $ string , $ result))
// Is it datetime?
if (! preg_match ( '/ ^ (\ d {4}) - (\ d {1,2}) - (\ d {1,2}) (\ d {1,2}): (\ d {1 , 2}): (\ d {1,2}) $ / ' , $ string , $ result))
// I understood! It is not what!
trigger_error ( 'Invalid data for date_sql modifier!' );

$ replace = array (
'% d' => $ result [3],
'% B' => $ Language [ 'months' ] [( int ) $ result [2]],
'% Y' => $ result [1],
'% H' => $ result [4],
'% M' => $ result [5],
'% S' => $ result [6],
);

if ($ format == 'date' )
{
$ format = $ Language [ 'global' ] [ 'date_format' ];
}
elseif ($ format == 'datetime' )
{
$ format = $ Language [ 'global' ] [ 'datetime_format' ];
}
elseif ($ format == 'time' )
{
$ format = $ Language [ 'global' ] [ 'time_format' ];
}
else
// Clinical case
trigger_error ( 'Invalid modifier date for date_sql modifier!' );

return strtr ($ format, $ replace);
}


UPDATE: A number of commentators have a question: why do I use the creepy combination of strtr () and regular expressions instead of strtotime () ? The answer is simple: for correct processing of incomplete dates like "1980-00-00" (everyone knows my age, but not the day of birth) or "0000-01-19" (everyone congratulates me on my birthday, but no one knows how much I years old).

Here a natural question arises: what for in general 2 modifiers? Let there be one that internally understands the input data. I think this is an interesting decision, which I cannot yet implement due to a number of technical features of the framework (or maybe it's just laziness?).

UPDATE: A number of sensible comments encouraged me to glue and simplify these two plugins, as I had intended, but for a bunch of reasons I did not dare. It turned out this:

File smarty / plugins / modifier.date.php ( download )
<? php
/ **
* Date modifier: unix_timestamp, date, datetime => date in human language
*
* param string $ string
* param string $ format - 'date', 'time', 'datetime'
* return string
* /
function smarty_modifier_date ($ string , $ format = 'datetime' )
{
global $ Language;

if (! isset ($ Language [ 'global' ] [$ format. '_format' ]))
{
trigger_error ( 'Modifier date: invalid format specified!' );
return '' ;
}

$ format = $ Language [ 'global' ] [$ format. '_format' ];

if (! is_numeric ($ string ))
{
// Try to read date and datetime
$ timestamp = strtotime ($ string );
if ($ timestamp! == FALSE && $ timestamp! = - 1 /*PHP<5.1*/ )
{
$ string = $ timestamp;
}
}

// Does this look like unix_timestamp?
if (is_numeric ($ string ))
{
// Month in human language
$ format = str_replace ( '% B' , $ Language [ 'Month' ] [date ( 'n' , $ string )], $ format);

return strftime ($ format, $ string );
}

// Are we still here? Something is amiss ...
trigger_error ( 'Invalid data for date modifier!' );
return '' ;
}
?>


Thank you for your help.

At this point, I want to stop, although there are five more interesting plug-ins. Since I spent a lot of time on writing (the Chukchi is not a writer), I don’t know the community’s interest in this subject: whether rotten tomatoes will fly into me or the article will simply be lost unclaimed - I don’t know.

UPDATE: Already written and posted the second part .

PS Strongly do not scold, for PPNH;)

Source: https://habr.com/ru/post/38283/


All Articles