Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CMS模板生成扩展

这是一个基于laravel框架,为CMS模板引擎生成HTML实现的扩展包。 支持对属性值,列表自定义标签。

image image image

安装

composer require githen/cmsengine

# 迁移配置文件
php artisan vendor:publish --provider="Githen\CmsEngine\CmsProvider"

配置文件说明

return [
    // 基础配置
    'config' => [
        'namespace' => 'eol',  // 标记名
        'tagstart' => '{',     // 标记开始符
        'tagend' => '}',       // 标记结束符
        'tagmaxlen' => 60,     // 标签名最长长度
        'tolow' => TRUE,       // 标签大小写不敏感
        'home' => storage_path('template'), // 模板根目录
        'disk' => 'local',     // 存储引擎
        'include_deep' => 3, // 默认3级
    ],

    // 标签白名单,只有在此定义才可解析通过
    // type 目前有三种  field(属性值),list(列表), page(分页)
    // taget 实现类,通过 app('cms.field') 方式调用出来
    'tags' => [
        'site' => ['type' => 'field', 'taget' => 'cms.field'],  
        'school' => ['type' => 'field', 'taget' => 'cms.field'],
        'arclist' => ['type' => 'list', 'taget' => 'cms.list'],
        'page' => ['type' => 'page', 'taget' => 'cms.page'],
    ],

];

标签说明

目前标签解析支持三种方式:

  1. 获取属性值

{eol:tag.title/}

{eol:tag name="title"/}

  1. 对列表/分页进行渲染

{eol:arclist id=1 row=60 order='desc'}

<li>[field:title/]</li>

{/eol:tag}

  1. 内置标签
  • include

标签举例

{eol:include filename='footer.html'/}

引擎将会把 app('html.tpl')中 $homeDir/footer.html进行渲染生成html替换此标签

  • foreach

数据遍历

{eol:foreach array="field:category"}

[field:key/] -- [field:val/]

{/eol:foreach}

array: 需要遍历的数组

  1. 支持数组索引的方式调用 [field:index/]

  2. 使用内置标签,前提是数组中不存在 key/val 两个索引

[field:key/]:获取数组索引

[field:val/]:获取数组值(字符串,整形)

  • global

全局定义的属性

{eol:global.page_total/} // 总条数

{eol:global.page_size/} // 每页数据

{eol:global.page_num/} // 总页数

{eol:global.page_index/} // 当前页数

{eol:global.page_url/} // 分页规则

{eol:global.domain/} // 静态资源域名

{eol:global.tplid/} // 模板id

{eol:global.resource_url/} // 静态资源调用地址

{eol:global.build_time/} // 构建时间

注:此地址是将domain和tplid进行组装,若tplid未设置或为0,则不拼接

$domain = 'https://www.test.com';

$tplid = 0

则$resource_url 为 'https://www.test.com/'

若$tplid = 10 或 $tplid = 'addd'

则$resource_url 为 'https://www.test.com/10/' 或 'https://www.test.com/addd/'

  1. 标签处理方法
  • 针对每个标签,支持扩展方法对数据进行处理,格式如下
{eol:global.resource_url function='limit(@, 10, ...)' /}
  • 引擎已内置了部分数据处理的方法如下
说明 :限长处理
举例:limit(@, 3, '...')
参数说明:第一个: @ 固定写法,执行时被替换为实际值
        第二个: 最长长度,非必填,默认15
        第三个:截断后追加字符,非必填,默认...
  • 扩展方法

内置方法不足以满足数据处理或其它需求时,支持扩展自定义的方法,可在模板进行fetch或saveTo的时候,通过注入类的方式实现,代码如下:

$tpl = clone app('html.tpl');

// 参数支持类名或实例化后的类
// 若标签标记的方法名为abc, {eol:global.resource_url function='abc(@)' /}
// 那么在此类中必须有abc方法,并且参数要兼容模板中配置的abc的参数
$tpl->->setFunctions(Functions::class);

使用举例

项目中调用

$tpl = clone app('html.tpl');
$tpl->setNameSpace('eol', '{', '}')->loadTemplate('index.html');

// 获取渲染后的html
$html = $tpl->fetch();

// 渲染后的html直接保存到文件()
// 需要在config/filesystems.php中声明 cms.php中定义 的 disk 驱动
$tpl->saveTo('index.html');

//分页调用,直接返回需要页面的html代码
$html = $tpl->fetch(2);

// 遍历生成文件, {page}将会生成对应的页码数,
// 如果存在第二个参数,则首页的文件将为此参数的值,其它页的文件名不变
$tpl->saveTo('aa/list{page}.html', 'new.html');

注册自定义数据服务提供者

// 数据获取服务提供者,自我声明服务提供者,并在config/app.php中加载

    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        // 注册服务方式
        $this->app->singleton('cms.field', function ($app) {
            return new Fields();
        });
        $this->app->singleton('cms.list', function ($app) {
            return new Lists();
        });
        
        $this->app->singleton('cms.page', function ($app) {
            return new Pages();
        });
    }

取数据值实例

config/cms.php中的tags中,声明的标签typefield时,会自动调用此类,标签名为类中的方法名。

class Fields
{
    /**
     * 缓存数据
     */
    private $cache;

    /**
     * @param $tag
     * @param $linkData
     */
    public function data($tag, $linkData)
    {
        // 获取标签指定数据
        return $this->{$tag->tagName}($tag, $linkData);
    }

    /**
     * 获取值数据,直接填充
     */
    private function site($tag, $linkData)
    {
        // 获取站点缓存类
        $cacheKey = $linkData['site_id'].'.site';
        if(! $site = data_get($this->cache, $cacheKey, false)){
            $site = Site::select('name','school_id', 'domain', 'title', 'keywords', 'description')->where('id', $linkData['site_id'])->first();
            data_set($this->cache, $cacheKey, $site);
            dump("查询了下site:".$linkData['site_id']);
        }

        return $site->{$tag->getAttribute('name')};
    }
}

获取列表实例

config/cms.php中的tags中,声明的标签typelist时,会自动调用此类,标签名为类中的方法名。

class Lists
{
    /**
     * 缓存数据
     */
    private $cache;

    /**
     * @param $tag
     * @param $linkData
     */
    public function data($tag, $linkData)
    {
        // 获取标签指定数据
        return $this->{$tag->tagName}($tag, $linkData);
    }

    /**
     * 获取列表数据
     *  
     */
    private function arclist($tag, $linkData)
    {
        // 必要参数检测

        // code ...

        // 获取站点缓存类
        $unikey = "{$tag->getAttribute('id')}_{$tag->getAttribute('row')}";
        $cacheKey = $linkData['site_id'].'.arclist.'.$unikey;
        if(! $arclist = data_get($this->cache, $cacheKey, false)){
            $arclist = News::select('type','title', 'cover', 'content', 'created_at', 'description')->where('category_id', $tag->getAttribute('id'))->limit($tag->getAttribute('row'))->get();
            data_set($this->cache, $cacheKey, $arclist);
            dump("查询了下栏目id为".$tag->getAttribute('id').'下面的文章,site_news');
        }

        return $arclist->toArray();
    }
}

获取分页实例

config/cms.php中的tags中,声明的标签typepage时,会自动调用此类,标签名为类中的方法名。 分页中若展示页码,可通过global获取分页信息,通过js渲染

<?php

namespace App\Extend\Cmss;

use App\Models\School;
use App\Models\Site;

class Pages
{
    /**
     * 缓存数据
     */
    private $cache;

    /**
     * @param $tag
     * @param $linkData
     */
    public function data($tag, $linkData)
    {
        // 获取标签指定数据
        return $this->{$tag->tagName}($tag, $linkData);
    }

    /**
     * 获取列表数据
     */
    private function list($tag, $linkData)
    {
        // 必要参数检测

        // code ...
        // 栏目ID是否填写,学校id,站点id是否有权限等

        // 需要生成分页的第几页
        $page = $linkData['page_index'];

        // 获取站点缓存类
        $unikey = "{$tag->getAttribute('size')}_{$tag->getAttribute('per')}_{$page}";
        $cacheKey = $linkData['site_id'].'.list.'.$unikey;
        if(! $data = data_get($this->cache, $cacheKey, false)){
            // 获取总条数
            $count = News::where('category_id', $linkData['category_id'])->count();
            $arclist = News::select('type','title', 'cover', 'content', 'created_at', 'description')
                ->where('category_id', $linkData['category_id'])
                ->skip(($page-1) * $tag->getAttribute('per'))
                ->take($tag->getAttribute('per'))->get();
            
            // 伪造数据,为测试foreach标签    
            $arclist = $arclist->map(function ($item, $key){
                $item->setAttribute('test', ['a' => '1'.$item->title, 'b' =>'2'.$item->title]);
                return $item;
            });

            $data = [
                'total' => (int)$count,  // 总条数
                'size' => (int)$tag->getAttribute('per'), // 每页
                'items' => $arclist->toArray() // 当前页列表数据
            ];

            data_set($this->cache, $cacheKey, $arclist);
            dump("查询了下栏目id为".$linkData['category_id'].'下面的文章分页,page:'.$page);
        }

        return $data;

    }
}

About

基于laravel框架,为CMS模板引擎生成HTML实现的扩展包

Resources

Stars

5 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages