From ab3e3b3f64bc737f18ffd49b814cc114c6880c2e Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Tue, 16 Jun 2026 13:54:02 +0800 Subject: [PATCH] feat: add CMS template functions plugin (get_site_config, get_published_content, get_latest_news) --- plugins/cms_functions.py | 91 ++++++++++++++++++++++++++++++++++++++++ wwwroot/index.ui | 8 ++-- 2 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 plugins/cms_functions.py diff --git a/plugins/cms_functions.py b/plugins/cms_functions.py new file mode 100644 index 0000000..2ef87f6 --- /dev/null +++ b/plugins/cms_functions.py @@ -0,0 +1,91 @@ +""" +CMS Jinja2 模板函数插件 +注册到 ServerEnv,供 index.ui 等模板使用 + +函数: + get_site_config() → dict + get_published_content(content_type, limit) → list[dict] + get_latest_news(limit) → list[dict] +""" +from ahserver.serverenv import ServerEnv +from sqlor.dbpools import DBPools +from appPublic.jsonConfig import getConfig +import os + +_workdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +_config = None +_db = None + + +def _get_db(): + global _config, _db + if _db is None: + _config = getConfig(_workdir) + _db = DBPools(_config.databases) + return _db + + +async def get_site_config(): + """获取站点配置""" + try: + db = _get_db() + async with db.sqlorContext('ocai_cms') as sor: + rows = await sor.sqlExe( + "SELECT config_key, config_value FROM cms_site_config", {} + ) + cfg = {} + for r in rows: + cfg[r['config_key']] = r['config_value'] + return cfg + except Exception: + return {} + + +async def get_published_content(content_type, limit=10): + """获取已发布内容""" + try: + db = _get_db() + async with db.sqlorContext('ocai_cms') as sor: + rows = await sor.sqlExe( + "SELECT c.id, c.title, c.subtitle, c.summary_text, c.image_url, " + "c.tags, c.body, cat.name as category_name " + "FROM cms_content c " + "LEFT JOIN cms_categories cat ON c.category_id = cat.id " + "WHERE c.content_type = %(ct)s AND c.status = 'published' " + "ORDER BY c.sort_order, c.created_at DESC " + "LIMIT %(lim)s", + {"ct": content_type, "lim": int(limit)} + ) + return list(rows) + except Exception: + return [] + + +async def get_latest_news(limit=3): + """获取最新新闻""" + try: + db = _get_db() + async with db.sqlorContext('ocai_cms') as sor: + rows = await sor.sqlExe( + "SELECT c.id, c.title, c.subtitle, c.summary_text, c.image_url, " + "c.published_at, cat.name as category_name " + "FROM cms_content c " + "LEFT JOIN cms_categories cat ON c.category_id = cat.id " + "WHERE c.content_type = 'news' AND c.status = 'published' " + "ORDER BY c.published_at DESC, c.created_at DESC " + "LIMIT %(lim)s", + {"lim": int(limit)} + ) + return list(rows) + except Exception: + return [] + + +def load_cms(): + g = ServerEnv() + g.get_site_config = get_site_config + g.get_published_content = get_published_content + g.get_latest_news = get_latest_news + + +load_cms() diff --git a/wwwroot/index.ui b/wwwroot/index.ui index 944c404..75c47fc 100644 --- a/wwwroot/index.ui +++ b/wwwroot/index.ui @@ -1,7 +1,7 @@ -{% set config = {} %} -{% set products = [] %} -{% set cases = [] %} -{% set news = [] %} +{% set config = get_site_config() %} +{% set products = get_published_content('product', 10) %} +{% set cases = get_published_content('case', 6) %} +{% set news = get_latest_news(2) %} { "widgettype": "VBox", "id": "app",