Contents

使用Conimo框架构建最小化CMS

Conimo是Coni的官方全栈Web框架。它将极其快速的WASM前端功能与健壮的后端服务器环境结合在一起,形成了一个具有凝聚力且精简的开发者体验。

最近,我们通过将核心的Conimo CLI脚本直接嵌入到 conimo 库的 bin 目录中,极大地改善了开发者体验。这意味着您不需要外部的设置脚本——一切都由原生的Coni代码驱动。

在本指南中,我们将带您完成新应用程序的脚手架搭建、运行本地开发服务器,并利用强大的 patom 数据库快速构建一个极简的内容管理系统 (CMS)。

1. 使用 create 搭建脚手架

要开始使用,我们使用内置的 conimo create 命令。Conimo提供了各种内置模板,从最小的SSR设置到完整的实时WebSocket架构,甚至是原生的AI聊天应用程序。

对于CMS,我们需要持久化。csv-store 模板非常适合这个需求,因为它通过 patom 利用了健壮的CSV文件数据库。

运行以下命令来搭建您的项目脚手架:

coni conimo create my-cms --template csv-store

脚手架脚本将瞬间生成一个全栈目录结构:

  • backend/: 您的后端HTTP/WebSocket服务器。
  • frontend/: 您的WASM编译前端代码。
  • coni.edn: 项目配置,会自动注入当前的编译器路径,以确保原生WASM构建无缝工作。

2. 运行开发服务器

创建项目后,启动开发环境就像运行 conimo dev 命令一样简单。

cd my-cms
coni conimo dev

在底层,Conimo开发服务器:

  1. 为您的 frontend/ 代码生成一个后台WASM编译进程。
  2. 等待直到 main.wasm 和必要的JS桥接完全编译完毕。
  3. 自动启动您的 backend/main.coni 服务器。

您现在拥有了一个实时的全栈环境,在这里您的后端服务器和WASM前端无缝连接。

3. 编写CMS

../conimo-todo.png

有了 csv-store 模板,构建CMS的速度快得令人难以置信。后端已经连接好以使用 patom——Coni的持久化原子状态管理系统。

下面是您如何定义一个最小的CMS后端来管理“帖子 (Posts)”:

;; backend/main.coni
(require "libs/http/src/server.coni" :as http)
(require "libs/patom/src/core.coni" :as patom)

;; 初始化一个由CSV支持的持久化原子(atom)
(def *db* (patom/create-store "cms_data.csv" []))

(defn handle-get-posts [req]
  (http/json-response @*db*))

(defn handle-create-post [req]
  (let [body (http/parse-json (:body req))
        new-post {:id (rand-int 10000)
                  :title (:title body)
                  :content (:content body)}]
    ;; 原子地交换状态并持久化到CSV
    (patom/swap! *db* conj new-post)
    (http/json-response new-post)))

(defn start-server []
  (let [mux (http/serve-mux)]
    (http/handle mux "GET /api/posts" handle-get-posts)
    (http/handle mux "POST /api/posts" handle-create-post)
    
    (println "CMS API running on port 8080")
    (http/listen-and-serve ":8080" mux)))

(start-server)

只需短短几行代码,您就拥有了一个由持久化CSV存储支持且功能齐全的JSON API。

4. 前端

在前端,您可以使用Coni的 reframe_wasm 库来原生在浏览器中获取和渲染这些帖子:

;; frontend/main.coni
(require "libs/reframe/src/core.coni" :as rf)
(require "libs/http/src/client.coni" :as client)

(rf/reg-event-fx :fetch-posts
  (fn [_ _]
    (let [res (client/get "/api/posts")]
      {:dispatch [:set-posts (:body res)]})))

(rf/reg-event-db :set-posts
  (fn [db [_ posts]]
    (assoc db :posts posts)))

(rf/reg-sub :posts
  (fn [db _]
    (:posts db [])))

(defn cms-view []
  (let [posts @(rf/subscribe [:posts])]
    [:div.container
      [:h1 "My Conimo CMS"]
      [:button {:on-click #(rf/dispatch [:fetch-posts])} "Load Posts"]
      [:ul
        (for [p posts]
          [:li [:h3 (:title p)] [:p (:content p)]])]]))

(rf/mount cms-view (js/document.getElementById "app"))

总结

通过将CLI脚本直接嵌入到 bin 目录中,启动Conimo项目变得比以往任何时候都更加顺畅。create 脚本为您提供了完美的样板代码,dev 提供了出色的本地工作流,而 patom 和Coni WASM的结合使您能够在几分钟内构建强大、持久的应用程序(如CMS)。

祝您编码愉快!