手撸了一个简单 web 框架,拿来做博客

2016-02-24 11:14:19 +08:00
 bramblex

手撸了一个简单 web 框架,拿来做博客

这两个半个月自己简单手撸了个 web 框架。用得是 PureScript 撸的, PureScript 跟 CoffeeScript 一样是一门 target 到 JavaScript 的语言,虽然 PureScript 从语言本身的设计角度来说比 CoffeeScript 不知道高到哪里去了……但那也架不住 CoffeeScript 简单方便易学大众有生态。

其实拿 PureScript 手撸这个 web 框架是用来炫技的, PureScript 的强类型纯函数式的特性我觉得真的不太适合应用场景,把本身很简单的事情变复杂了。用 JavaScript / Ruby / Python / PHP 我实现这些东西顶多就两三天。

》》Github 传送门
》》LoveAria.Me 博客主站

下面讲讲我主要做的事情:

1.SQLite3 的 PureScript Binding ,以及一个简单的 ORM (还是半残状态,连 JOIN 我都没实现好,强类型面对这种场景只能日狗)。

虽然是自己手撸的……但是放心,注入不了的,本宝宝做了防注入的。

可以用下面哪种好看的方式做查询了,例如:

insert "article" [ "title" .= title
                , "category_id" .= category_id
                , "raw_content" .= content
                , "content" .= Markdown content ]

update "article" [ "title" .= title
                , "category_id" .= category_id
                , "raw_content" .= content
                , "content" .= Markdown content] ("id" .== id)

first "article" ("id" .== id .&& "user_id" .== user_id) (Asc "id")

findall "article" ("category_id" .<- [cid1, cid2, cid3]) (Desc "id")

2.一门 HTML 模板 DSL 。因为是 PureScript 的 DSL ,所以其实还是 PureScript 本身。只是语法看上去像一门单独的语言而已, 并且还是有些丑的。

list :: Array Category.RichArticle -> Template
list articles = do
  base
  title "Article"
  extend "body" $ do

    ifLogined $ \_ ->
      t_a [a_href := "/article/create"] $ text "Create"

    article_list articles

article_list :: Array Category.RichArticle -> Template
article_list articles = do
  t_table [] do
    t_tr [] do
      t_th [] $ text "Id"
      t_th [] $ text "Title"
      t_th [] $ text "Category"
      t_th [] $ text "Create At"
      t_th [] $ text "Update At"

      forT articles $ \article -> do
        t_tr [] do
          t_td [] $ text $ show article.id
          t_td [] do
            t_a [a_href := "/article/show/" ++ show article.id]
              $ text article.title
          t_td []  do
            t_a [a_href := "/article/category/" ++ show article.category.id]
              $ text article.category.name
          t_td [] $ text article.create_at
          t_td [] $ text article.update_at

3.基础的框架是在 PureScript-Express 上面建立的。所以基本的 handler 处理还是沿用 Express 。

main :: forall e. ModelApp (console :: CONSOLE | e)
main = do
  liftEff $ log "Setting up"
  setProp "json spaces" 4.0

  useExternal $ MW.bodyParser {extended: false}
  static_path <- liftEff $ Config.static_path
  useExternalAt "/static" $ MW.static static_path

  useExternal $ cookieSession {secret: Config.security_key}
  useExternal $ MW.setCookiesMaxAge (3600 * 24 * 30)

  use CacheHandler.logger
  use CacheHandler.cacheMiddleware

  mount "/" HomeHandler.main

  mount "/user" UserHandler.main
  mount "/article" ArticleHandler.main
  mount "/category" CategoryHandler.main
  mount "/cache" CacheHandler.main

4.现在博客的功能基本完善。讲一下框架之上博客的功能:

  1. 文章的增删改,搜索功能还没做,感觉没什么必要做。在下一条讲
  2. 不限制层次的分类。对的,分类就是树状递归结构,不限制层数。你爱几层就几层,跟文件系统的目录类似。用这样的分类来整理文章,我觉得根本没必要搜索了吧。而且我这一辈子能写一千篇高质量的博客不?
  3. 页面缓存。因为 ORM 设计的问题和分类目录递归查询量很大,所以我干脆就直接给他们做了一个 10 分钟的页面缓存。登录成功的用户忽略缓存。成功发布或者修改 文章和分类 会简单全部刷新缓存。

5.关于前端

前端方面我准备使用 PureCSS 来做基本的 CSS 框架,然后做一个简洁好看的 UI 。 /w\ 没错,本宝宝就是那么纯( Pure ) 。 JavaScript 部分依旧还是用 PureScript 来做。当然 PureScript 写前端也有些蛋疼,不过我能折腾 /w\。

啊~ 终于能够好好写东西并且实验奇怪小东西的地方啊啦~

》》Github 传送门
》》LoveAria.Me 博客主站

7194 次点击
所在节点    JavaScript
55 条回复
bramblex
2016-02-24 14:23:39 +08:00
@yuriko

写起来很爽啊,就是处理这种不知道具体类型的东西要蛋疼一些。不过其实也是可以很简单解决的。比如 Template Haskell ,或者自己造一个语言来生成 Haskell 代码。这些都是很简单的解决方案
minsheng
2016-02-24 14:25:42 +08:00
楼主你是 C 写多了还是 C 写多了还是 C 写多了下划线是什么鬼?????
edsgerlin
2016-02-24 14:30:49 +08:00
好像在知乎看到过 OP 安利 PureScript ……过几年 WebAssembly 普及,只要 GHC 有 LLVM 后端就能直接拿 Haskell 写啦。
minsheng
2016-02-24 14:30:51 +08:00
Lib.Utils 是什么鬼东西啊,我虽然不用 PureScript 但是这些东西拿出来专门实现一遍也太鬼畜了吧?

还有为什么 .js 和 .purs 放在同一个目录下,不是有 pulp 吗?
minsheng
2016-02-24 14:31:44 +08:00
@edsgerlin GHC 本来就有 LLVM 后端, GHCJS 也早就理论上可以用了,但是生成文件的体积惨不忍睹
bramblex
2016-02-24 14:34:03 +08:00
@minsheng

是这样的,我自己曾经的语言风格是:
类——首字母大写驼峰,
函数 /方法——首字母小写驼峰
变量——首字母小写下划线

放在这里面好像不对劲……
minsheng
2016-02-24 14:35:11 +08:00
然后楼主打算 type Sql = String 吗?你这是写 Python/NodeJS 呢……
bramblex
2016-02-24 14:35:37 +08:00
@edsgerlin

那就等普及吧~
不过即便普及,我觉得 JavaScript 还能作为 target 语言活着。毕竟,你见过范式那么全的大杂烩吗? /w\
minsheng
2016-02-24 14:36:07 +08:00
哦,楼上我好像看错了,无视我对 Sql 的吐槽,我来研究一下 Model
bramblex
2016-02-24 14:37:14 +08:00
@minsheng

purescript pures/ js 放在同一目录有问题?我不知道, purescript 的作者就是这样写的。我跟着他做的
minsheng
2016-02-24 14:37:32 +08:00
@bramblex 入乡随俗,变量名请统一使用希腊字母,

cata phi = In . fmap (cata phi) . out

其它的统一驼峰法咯(逃
bramblex
2016-02-24 14:38:25 +08:00
@minsheng

炫技 / 练手 。至于有没有?

当然是没什么卵用啊 !
minsheng
2016-02-24 14:38:35 +08:00
@bramblex 我又傻逼了,我看成了你生成的 JS ……我就想怎么会犯这么低级的错误。 PureScript 的包我一点都不熟悉还是不看了,我们聊聊为什么不用 Haskell 吧?
bramblex
2016-02-24 14:42:26 +08:00
@minsheng

/w\ 还真可以……

```Haskell
搞 = id
比利 = id
(♂) = id

搞 ♂ 比利
```
minsheng
2016-02-24 14:44:03 +08:00
@bramblex 来点严肃的吐槽,既然是炫技,你 SQL 还要手工定义 Schema 是不是太麻烦了?我记得最近 PureScript 似乎是支持 Generics 了——虽然 Template PureScript 还是坑,希望今年 GSoC 能加进去——搞个什么根据数据类型自动生成 SQL 操作代码岂不美哉?
bramblex
2016-02-24 14:44:08 +08:00
@minsheng 因为我的 vps 装不进 ghc 。并且我不想折腾交叉编译
bramblex
2016-02-24 14:44:42 +08:00
@minsheng 今年的 GSoc 还真有 Template PureScript 项目……
learnshare
2016-02-24 14:45:54 +08:00
@bramblex 因为只见过 Python
bramblex
2016-02-24 14:46:38 +08:00
@minsheng

我想想怎么实现
minsheng
2016-02-24 14:49:48 +08:00
@bramblex 好像用不上, PureScript 的 record syntax 比较神奇我不是很熟悉,但看你用得好开心啊。

GHC 装不进 VPS 是嘛,这个确实是比较严肃的问题,我前段时间真是日了狗了 pandoc 编译 VPS 上死活不成功,结果查了一下 aeson 出了问题,那个版本需要 7GB RAM 才能编译,但是我所有的 Mac 都有这么多内存一点问题都没有……

对啊对啊,你要不要试试, 5500 刀呢。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/258673

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX