• 1 رای - 5 میانگین
  • 1
  • 2
  • 3
  • 4
  • 5
ساخت کلاس template engine baker! (کار خودم)
#1
سلام ! یه template engine ساختم به اسم baker! می تونید خیلی راحت تم خامتون رو بهش بدید تا براتون بپزه تحویلتون بده! (لطفا اگه مشکلی چیزی دیدین بگین ویرایش کنم و پیشنهادی چیزی دارین بگین چون من خیلی حرفه ای نیستم (لااقل خودم اینطور فکر میکنم!))

خیلی تمپلیت انجین ساده و در عین حال جالبی هست(از نظر خودم)
یکی از مزیت هایی که نسبت به بقیه template engine ها داره اینه که compile و view رو تو دو مرحله انجام میده! یعنی template شما رو میگیره و compile میکنه(اگه کامپایل شدش موجود نباشه) و بعد نمایش میده! و قالب کامپایل شده رو با پسوند baked.php. (به صورت پیشفرض یا پسوندی که خودتون بهش میدید تو مسیری که بهش دادید ذخیره میکنه و تو اجرا های بعدی دیگه نیازی به کامپایل نیست!(که هیچ template engine ـی این کار رو نمیکنه! یا لااقل من ندیدم و متوجه نشدم)(البته اگه حالت edit رو true بدید خودش براتون هر بار کامپیایل میکنه))

قابلیت ها
  • تعریف متغیر با @set
  • به ارث بری با @extend (برای تعریف مستر پیج)
  • دسترسی به متغیر ها به صورت {{ $value }}(هنگام کامپایل کلی جایگزین میشه) و {% $value %}(قبل از کامپایل کلی جایگزین میشه)
  • اینکود مثال {~ include app.html ~}
  • پشتیبانی از حلقه foreach با داشتن قابلیت تایین تعداد دور اجرا (مثالش رو پایین خواهید دید (تو تملیپ انجین های دیگه ندیدم! اینو))
  • تعریف section و GetSection (با کمی تقلید از blade)
  • و...

اگه مثال های این تمپلیت انجین رو ببینید متوجه شباهت زیاد طرز نوشتنش با blade میشین
اول که نوشتم تمپلین انجین رو syntax ش اینجوری نبود اما بعد از دیدن blade تغییرش دادم!(یعنی کللا از اول نوشتمش و با قبلی خداحافظی کردم!)

در کل هر قابلیتی فکر میکردم ضروریه رو اضاف کردم و هر چی رو دیدم اضافه کنار گذاشتم مثل حلقه های for و while (البته احتمالا بعدا for رو اضاف کنم)

خوب توضیح بسه بری سراغ مثال

نمای کلی استفاده از baker template engine در یک قالب (سعی کردم همه قابلیت های این تملیپ engine رو توش استفاده کنم برای همین طولانیه وحشت زده نشید!Big Grin)
کد پی‌اچ‌پی:
@section(content)
    @if(
count($users)>0)
        <
ul>
            @foreach(
$users as $user){3}
                @
set($user['id']=$user['id']+1)

                @if(
$user['sath']=='admin')

                    <
li style="color:green">{{$user['id']}}: {{ $user['name'] }} {{$user['family']}}</li>

                @elseif(
$user['sath']=='premium')

                    <
li style="color:blue">{{$user['id']}}: {{ $user['name'] }} {{$user['family']}}</li>

                @else
                    <
li style="color:red">{{$user['id']}}: {{ $user['name'] }} {{$user['family']}}</li>
                @
endelse
                
            
@endforeach
        </
ul>
    @else
        (~
h1 style="red"~) هیچ کاربری موجود نیست! (/h1)
    @
end

@stop

@extend(app.html)
<!--or 
you can user {~include app.html~} --> 


اینم سورس قالب پز ماTongue
کد پی‌اچ‌پی:
<?php 

class baker
{
    public static 
$data;
    public static 
$tmp;
    public static 
$Current=[];
    public static 
$ta;
    public static 
$edit=true;
    public static 
$extension='.baker.php';
    public static 
$baked_extension='.baked.php';
    public static 
$root_of_theme='';
    public static 
$root_of_baked_theme='';
    function 
baker($vals=[])
    {
        
self::$data=$vals;
    }
    function 
var_replace($data){
        
$fore='~\$([a-zA-Z0-9_]+)~';
        
$foreRe='self::$data["$1"]';

        
$datapreg_replace($fore,$foreRe$data);
        
        return 
$data;
    }

    function 
loop()
    {
        
$tmp=self::$tmp;

        
$b='<?php ';
        
$e=' ?>';
        
$fore='~@foreach\((.+)\)(\{([0-9]+)\})?~';
        
$foreRe=$b.'
        $i=0;
        foreach($1){
            if(\'$3\'!=null)
            {
                if($i==\'$3\'){
                    break;
                }
            }
            $i++;
            '
.$e;

        
$efore='~@endforeach~';
        
$eforeRe=$b.'}'.$e;
        

        
$Current='~\{\{[ ]*self::\$data\[([\[\'"a-zA-Z0-9_\]]+)\][ ]*\}\}~';
        
$CurrentRe='<?php echo self::$data[$1];?>';
        
$replace_before_exe='~\{\%[ ]*self::\$data\[([\[\'"a-zA-Z0-9_\]]+)\][ ]*\%\}~';
        
$replace_before_exeRe='<?php echo self::$data[$1];?>';

        
$b='<?php ';
        
$e=' ?>';

        
$if='~\@if\((.+)\)~';
        
$ifRe=$b.'if($1){'.$e;
        
$eif='~\@endif~';
        
$eifRe=$b.'}'.$e;
        
        
$else='~@else~';
        
$elseRe=$b.'}else{'.$e;
        
$eelse='~@endelse~';
        
$eelseRe=$b.'}'.$e;

        
$elseif='~@elseif\((.+)\)~';
        
$elseifRe='<?php }elseif($1){ ?>';
        
$eelseif='~@endelseif~';
        
$eelseifRe='<?php } ?>';

        
$section='~@section\((.+)\)~';
        
$sectionRe=$b.'self::$data[$1]=\'';
        
$esection='~@stop~';
        
$esectionRe='\';'.$e;

        
$getsection='~@GetSection\((.+)\)~';
        
$getsectionRe=$b.'echo self::$data[$1];'.$e;

        
$set='~@set\((.+)=(.+)\)~';
        
$setRe=$b.'$1=$2;'.$e;
        
$extend='~(@extend\((.+)\))~';
        
$tags='~\(\~[ ]*([a-zA-Z0-9_]+)[ ]*([a-z:;A-Z0-9_\=\-\'"]+)[ ]*\~\)~si';
        
$tagsRe='<$1 $2>';
        
$etags='~\(/([a-zA-Z0-9_]+)\)~';
        
$etagsRe='</$1>';


        
$include="~\{\~[ ]*include[ ]*([a-zA-Z0-9_\-\.]+)[ ]*\~\}~";
        for(
$i=0;$i>-1;$i++){
            if(
preg_match($include$tmp$matches)){
                
$tmp str_replace($matches[0],file_get_contents($matches[1]),$tmp);
            }else{
                break;
            }
        }

        for(
$i=0;$i>-1;$i++){
            if(
preg_match($extend$tmp$matches)){
                
$tmp str_replace($matches[0],file_get_contents($matches[2]),$tmp);
            }else{
                break;
            }
        }
        
$tmp=self::var_replace($tmp);
        
preg_match($replace_before_exe$tmp,$matches);

        for(
$i=0;$i>-1;$i++){
            if(
preg_match($replace_before_exe$tmp$matches)){
                
$tmp str_replace($matches[0],self::$data[trim($matches[1],'"')],$tmp);
            }else{
                break;
            }
        }
        
$e='~@end~';
        
$eRe='<?php } ?>';

        
$tmppreg_replace($set,$setRe$tmp);

        for(
$i=0;$i>-1;$i++){
            if(
preg_match($section$tmp$matches)){
                
$p='~'.str_replace(')','\\)',str_replace('(''\\('$matches[0])).'(.+)@stop~s';

                
preg_match($p$tmp,$m);
                
self::$data[$matches[1]]=$m[1];
                
$tmp=str_replace($m[0], ''$tmp);
                
            }else{
                break;
            }
        }
        for(
$i=0;$i>-1;$i++){
            if(
preg_match($getsection$tmp$matches)){

                
$tmp str_replace($matches[0],self::$data[$matches[1]],$tmp);
            }else{
                break;
            }
        }
        
$tmppreg_replace($tags,$tagsRe$tmp);
        
$tmppreg_replace($etags,$etagsRe$tmp);
        
$tmppreg_replace($fore,$foreRe$tmp);
        
$tmppreg_replace($efore,$eforeRe$tmp);
        
$tmppreg_replace($Current,$CurrentRe$tmp);
        
$tmppreg_replace($if,$ifRe$tmp);
        
$tmppreg_replace($eif,$eifRe$tmp);
        
$tmppreg_replace($eelseif,$eelseifRe$tmp);
        
$tmppreg_replace($elseif,$elseifRe$tmp);
        
$tmppreg_replace($else,$elseRe$tmp);
        
$tmppreg_replace($eelse,$eelseRe$tmp);
        
$tmppreg_replace($e,$eRe$tmp);

        
        
self::$tmp=$tmp;    
    }
    function 
run(){
        
ob_start ();
        eval(
self::$tmp);
    }

    function 
compile($name){
        
$file_address=self::$root_of_theme.$name.self::$extension;
        
$baked_file_addressself::$root_of_baked_theme.$name.self::$baked_extension;

        
self::$tmp='?>'.file_get_contents($file_address);
        
self::$tmp=str_replace('|>','?>',str_replace('<|''<?php'self::$tmp));
        
        
self::loop();
        
$FileName $baked_file_address;
        
$FileHandle fopen($FileName'w') or die("can't open file");
        
fclose($FileHandle);    
        
file_put_contents($FileNameself::$tmp);    

    }
    function 
view($name){
        
$file_address=self::$root_of_theme.$name.self::$extension;
        
$baked_file_addressself::$root_of_baked_theme.$name.self::$baked_extension;
        if(
self::$edit || !file_exists($baked_file_address)){
            
self::compile($name);
        }else{
            
self::$tmp=file_get_contents($baked_file_address);
        }
        
self::run();

    }    
}
?>

این هم نحوه اجرا و استفاده
کد پی‌اچ‌پی:
include 'baker.class.php';

baker::$data=[
            
'usercount'=>2,
            
'users'=>[
                [
'sath'=>'admin','id'=>'0','name'=>'ali','family'=>'hamidi'],
                [
'sath'=>'premium','id'=>'1','name'=>'reza','family'=>'maleki'],
                [
'sath'=>'user','id'=>'2','name'=>'mortaza','family'=>'faryabi']
            ],
        ];
baker::view($_GET['url']); 


نظر پیشنهادی انتقادی چیزی بود لطفا بگیدSmile
  پاسخ
تشکر شده توسط : Y.P.Y ayoubsys Reza Alaa


پرش به انجمن:


کاربران در حال بازدید این موضوع: 1 مهمان