Browse Source

feat:new tag

igb 3 months ago
parent
commit
64578c7f2e

+ 32 - 0
app/Models/SitePage.php

@@ -14,6 +14,8 @@ class SitePage extends Model
         'post_date' => 'datetime:Y-m-d'
     ];
 
+
+
     public function tags()
     {
         return $this->belongsToMany(
@@ -23,4 +25,34 @@ class SitePage extends Model
             'tag_id'
         );
     }
+
+
+    // 根据 ID 获取文章
+    public static function getPageById($id)
+    {
+        return self::where('dist_id', getDistId())->find($id);
+    }
+
+    // 根据标题获取文章
+    public static function getPageByTitle($title)
+    {
+        return self::where('dist_id', getDistId())->where('title', $title)->first();
+    }
+
+    // 根据 Slug 获取文章
+    public static function getPageBySlug($slug)
+    {
+        return self::where('dist_id', getDistId())->where('slug', $slug)->first();
+    }
+
+    // 获取多个文章
+    public static function getPages($limit = 10)
+    {
+        return self::where('dist_id', getDistId())
+            ->where('status', 1)
+            ->limit($limit)   // 限制结果数量
+            ->orderBy('post_date', 'desc')  // 按照发布日期降序排序
+            ->get();  // 返回结果集合
+    }
+
 }

+ 13 - 0
app/Models/SitePageTag.php

@@ -22,4 +22,17 @@ class SitePageTag extends Model
             ->orderBy('id', 'desc')
             ->paginate($perPage); // 支持分页
     }
+
+    // 根据slug获取标签和关联的页面
+    public static function getBySlug($slug, $perPage = 10)
+    {
+        $tag = self::where('slug', $slug)->first();
+
+        if (!$tag) {
+            return null; // 没找到标签
+        }
+
+        // 获取与标签关联的页面
+        return $tag->pages($perPage);
+    }
 }

+ 5 - 24
app/Services/LiquidRenderer.php

@@ -2,6 +2,7 @@
 
 namespace App\Services;
 
+use App\Services\LiquidTags\LiquidTagCollection;
 use Illuminate\Support\Facades\Cache;
 use App\Http\Controllers\ProductController;
 use App\Services\LiquidTags\LiquidTagProduct;
@@ -31,8 +32,9 @@ class LiquidRenderer
         self::initializeBaseTemplatePath();
 
 
+
         // 如果提供了缓存键,则检查和设置缓存
-        if ($cacheKey) {
+        if (config('liquid.cache_enabled')&&$cacheKey) {
             $cacheDuration = config('liquid.cache_duration', 300); // 默认缓存时间为 300 秒
 
             // 检查缓存是否存在
@@ -49,29 +51,7 @@ class LiquidRenderer
         // 如果没有提供缓存键,直接渲染模板
         return self::processTemplate($templateName, $data);
 
-//        $template = self::createTemplateInstance();
-//
-//        $template->registerTag('page', LiquidTagPage::class);
-//        $template->registerTag('product', LiquidTagProduct::class);
-//        $template->registerTag('video', LiquidTagVideo::class);
-//        $template->registerTag('contact', LiquidTagContactUs::class);
-//        $template->registerTag('banner', LiquidTagBanner::class);
-//        $template->registerTag('contactus', LiquidTagContactUs::class);
-//        $template->registerFilter(Filters::class);
-//
-//
-//        //获取全局配置,合并到当前配置
-//        $config = self::getGlobalConfig();
-//        $data['site'] = array_merge($data['site'] ?? [], $config);
-//
-//
-//        try {
-//            $parsedTemplate = $template->parseFile($templateName);
-//        } catch (\Exception $e) {
-//            throw new \RuntimeException("Template not found: {$templateName}", 0, $e);
-//        }
-//
-//        return $parsedTemplate->render($data);
+
     }
 
 
@@ -86,6 +66,7 @@ class LiquidRenderer
         $template->registerTag('contact', LiquidTagContactUs::class);
         $template->registerTag('banner', LiquidTagBanner::class);
         $template->registerTag('contactus', LiquidTagContactUs::class);
+        $template->registerTag('collection', LiquidTagCollection::class);
         $template->registerFilter(Filters::class);
 
         // 获取全局配置,合并到当前配置

+ 83 - 0
app/Services/LiquidTags/LiquidTagCollection.php

@@ -0,0 +1,83 @@
+<?php
+
+namespace App\Services\LiquidTags;
+
+use App\Models\SitePageTag; // 引入 SitePageTag 模型
+use Liquid\AbstractBlock;
+use App\Services\LiquidRenderer;
+
+class LiquidTagCollection extends AbstractBlock
+{
+    private $tagSlug;
+    private $limit;
+    private $templateFile;
+
+    // 构造函数解析传入的参数
+    public function __construct($markup, array &$tokens, $file_system = null)
+    {
+        // 初始化默认值
+        $this->tagSlug = null;
+        $this->limit = 10; // 默认显示 10 篇
+        $this->templateFile = null;
+
+        // 正则表达式解析传入的参数
+        $syntax = '/(\w+)=("[^"]*"|\'[^\']*\'|\d+)/';
+
+        if (preg_match_all($syntax, $markup, $matches, PREG_SET_ORDER)) {
+            foreach ($matches as $match) {
+                $key = $match[1];
+                $value = trim($match[2], '\"\''); // 去除引号
+
+                switch ($key) {
+                    case 'slug':
+                        $this->tagSlug = $value;  // 获取 slug 参数
+                        break;
+                    case 'limit':
+                        $this->limit = (int)$value; // 设置文章数量限制
+                        break;
+                    case 'template':
+                        $this->templateFile = $value; // 设置模板文件
+                        break;
+                }
+            }
+        }
+    }
+
+    // render 方法执行逻辑并返回渲染结果
+    public function render($context)
+    {
+        // 如果传入了 slug,就根据 slug 获取文章
+        if ($this->tagSlug) {
+            return $this->renderTagPages();
+        }
+
+        // 如果没有提供 slug,则返回空字符串
+        return '';
+    }
+
+    // 根据 tagSlug 获取与标签关联的文章
+    private function renderTagPages()
+    {
+        // 调用 SitePageTag 模型的 getBySlug 方法来获取与标签关联的页面
+        $pages = SitePageTag::getBySlug($this->tagSlug, $this->limit);
+
+
+        if (!$pages) {
+            return ''; // 如果没有找到页面,返回空字符串
+        }
+
+        // 如果有文章,渲染模板
+        return $this->renderTemplate(['pages' => $pages->toArray()]);
+    }
+
+    // 渲染模板
+    private function renderTemplate(array $data)
+    {
+        if (!$this->templateFile) {
+            return ''; // 如果未提供模板文件,返回空字符串
+        }
+
+        // 使用 LiquidRenderer 渲染模板
+        return LiquidRenderer::render($this->templateFile, $data);
+    }
+}

+ 117 - 15
app/Services/LiquidTags/LiquidTagPage.php

@@ -1,32 +1,134 @@
 <?php
 namespace App\Services\LiquidTags;
 
-class LiquidTagPage
+use App\Models\SitePage; // 假设 SitePage 是存储文章的模型
+use Liquid\AbstractBlock;
+use App\Services\LiquidRenderer;
+
+class LiquidTagPage extends AbstractBlock
 {
-    private $articleId;
+    private $mode;
+    private $pageId;
+    private $pageTitle;
+    private $pageSlug;
+    private $limit;
+    private $templateFile;
+
 
-    // 构造函数用于解析传入的参数
+    // 构造函数解析传入的参数
     public function __construct($markup, array &$tokens, $file_system = null)
     {
-        // 正则表达式解析传入的文章 ID,例如 `{% page 1 %}`\
-        $this->articleId= $markup;
-//        $syntax = '/(\d+)/';
-//        if (preg_match($syntax, $markup, $matches)) {
-//            $this->articleId = (int)$matches[1];
-//
-//        }
+
+        // 初始化默认值
+        $this->mode = 'single'; // 默认模式为单篇文章
+        $this->pageId = null;
+        $this->pageTitle = null;
+        $this->pageSlug = null;
+        $this->limit = 10; // 默认显示 10 篇
+        $this->templateFile = null;
+
+
+        // 正则表达式解析传入的参数
+        $syntax = '/(\w+)=("[^"]*"|\'[^\']*\'|\d+)/';
+
+        if (preg_match_all($syntax, $markup, $matches, PREG_SET_ORDER)) {
+            foreach ($matches as $match) {
+                $key = $match[1];
+                $value = trim($match[2], '\"\''); // 去除引号
+
+                switch ($key) {
+                    case 'mode':
+                        $this->mode = $value;  // 获取 mode 参数
+                        break;
+                    case 'id':
+                        $this->pageId = (int)$value;
+                        break;
+                    case 'title':
+                        $this->pageTitle = $value;
+                        break;
+                    case 'slug':
+                        $this->pageSlug = $value;
+                        break;
+                    case 'limit':
+                        $this->limit = (int)$value;
+                        break;
+                    case 'template':
+                        $this->templateFile = $value;
+                        break;
+                }
+            }
+        }
     }
 
     // render 方法执行逻辑并返回渲染结果
-    public function render(&$context)
+    public function render($context)
     {
-        if ($this->articleId) {
+        // 根据 mode 渲染不同的内容
+        if ($this->mode === 'list') {
+            return $this->renderList();
+        }
 
-                return $this->articleId;
+        // 单篇模式
+        return $this->renderSingle();
+    }
+
+
+    // 渲染多篇文章列表
+    private function renderList()
+    {
+        // 获取文章列表
+        $pages = SitePage::getPages($this->limit);
+
+        // 如果有文章,渲染模板
+        if ($pages->count() > 0) {
+            return $this->renderTemplate(['pages' => $pages->toArray()]);
+        }
+
+        // 如果没有文章,返回空字符串
+        return '';
+    }
 
+
+    // 渲染单篇文章
+    private function renderSingle()
+    {
+        // 根据传入的参数获取单篇文章
+        if ($this->pageId) {
+            return $this->renderPage(SitePage::getPageById($this->pageId));
+        }
+
+        if ($this->pageTitle) {
+            return $this->renderPage(SitePage::getPageByTitle($this->pageTitle));
+        }
+
+        if ($this->pageSlug) {
+            return $this->renderPage(SitePage::getPageBySlug($this->pageSlug));
+        }
+
+        // 如果没有提供有效参数,返回空字符串
+        return '';
+    }
+
+    // 渲染文章
+    private function renderPage($page)
+    {
+        // 如果文章存在,渲染模板
+        if ($page) {
+            return $this->renderTemplate(['page' => $page->toArray()]);
+        }
+
+        // 如果文章不存在,返回空字符串
+        return '';
+    }
+
+    // 渲染模板
+    private function renderTemplate(array $data)
+    {
+        if (!$this->templateFile) {
+            return ''; // 如果未提供模板文件,返回空字符串
         }
 
-        // 如果文章不存在,则返回空
-        return '<p>文章不存在。</p>';
+        // 使用 LiquidRenderer 渲染模板
+        return LiquidRenderer::render($this->templateFile, $data);
     }
 }