阿里、蚂蚁、晟腾、中科加禾精彩分享 AI 基础设施洞见,现购票可享受 9 折优惠 |AICon 了解详情
写点什么

用 Sinatra 编写博客应用

  • 2011-01-21
  • 本文字数:4537 字

    阅读完需:约 15 分钟

Sinatra 是 Blake Mizerany 在 2007 年 9 月开发的 Ruby 语言的 Web 框架。它最突出的特点就是轻量、快速。更难能可贵的是,Sinatra 的源代码只有一千多行。

在第一次接触到 Sinatra 的时候,我便被它深深地吸引住了。随后,我在 09 年 3 月的 Shanghai on Rails 活动向大家介绍了这个框架。10 年 8 月份我有幸可以在 RubyKaigi 这样的全球级 Ruby 社区会议上作为演讲者和听众交流 Sinatra。本文则是对 10 年 10 月份在上海 Linux 用户组介绍 Sinatra 的讲座的一些整理和总结。希望读者能够通过本例子能体会到 Sinatra 的精妙之处。

最新版本: 1.1

截止到本文成文为止,Sinatra 最新的版本是 10 年 10 月 24 日发布的 1.1 版本。很幸运的是,我对于 README 的翻译正好在发布的前一天被合并进入了主分支。于是在 1.1 的正式版本中,中文的读者可以直接阅读到中文的 README,从而更好的了解 Sinatra 的用法。官网上也有此文档的链接, http://www.sinatrarb.com/intro-zh.html 。本文的代码全部以 1.1 版本为准。

Sinatra 的基本结构

让我们从 Sinatra 最常见的 Hello world 程序开始:

复制代码
get '/' { "Hello, world!" }

这段简单的 Hello world 程序包含了 Sinatra 程序的三个基本组成部分:

  • 路由(route):

    ‘/’ 就是路由。路由可以是单一的路径,或者带有参数的路径(比如 /:name),甚至是正则表达式。对于 Sinatra 不知道的路由,Sinatra 会返回 404 错误(作为 App 运行的时候),或者传递给下面的中间件(作为中间件运行的时候)。

  • 方法(method):

    get是方法。在 Sinatra 中,HTTP 的四个方法GET/POST/PUT/DELETE都有相应的方法get/post/put/delete

  • 处理器(handler):

    处理器就是最后的代码块,处理器的返回值就是 Sinatra 返回给客户端(主要是浏览器)的内容。返回值主要以字符串为主,也可以是包含状态码,消息头,消息体的数组。

渲染模版

Sinatra 支持的模版类型也在逐渐增加中。Haml 是笔者常用的格式,因为它使用了 CSS 选择符构造 HTML 标签,从而节省编写时间。另一种常见的格式是 Ruby 自带的 ERB,本例子将使用 Haml 作为博客的模版。

渲染模版在 Sinatra 中是很容易的事:

复制代码
get '/' do
haml :index
end

在这里haml :index,就表示使用 Haml 渲染'views/index.haml'这个模版。

传递参数也是很容易的事,可以使用实例变量:

复制代码
# in app.rb
get '/' do
@now = Time.now
haml :index
end
# in views/index.haml
Hello, now is #{@now}

或者用 locals 传递参数(如例子中的哈希):

复制代码
# in app.rb
get '/' do
now = Time.now
haml :index, :locals => { :now => now }
end
# in views/index.haml
Hello, now is #{now}

熟悉了路由和模版,就可以开始构建 Web 应用程序了,Sinatra 也提供了一些简单的辅助方法,比如过滤器、helpersconfigurehaltpass等等,这些就不再这里一一叙述了,更多的内容请仔细参考官方文档。

开始博客应用

文件格式

本博客应用将使用 dorothy 格式的文件存储,不会使用数据库。

例子如下:

复制代码
# 文件名: 2010-10-10-a-lucky-day.txt
title: "A Lucky Day"
date: 2010-10-10
author: " 吴江 "
# 今天是我的幸运日
早上在地铁门将要关上的那一刻,我冲进了车厢,于是约会没有迟到...
中午提前了一点去港丽,居然只排了 42 分钟...
晚上又赶上了末班车...
到家数了数,钱包里面正好有 42 块钱...

该文件的结构是:以第一个连续换行符("\n\n")为界线,前一半是 YAML 格式的配置信息,后一半则是 markdown 格式的文本。 YAML 格式是一种表示数据的标记语言。这里只使用到它的键值对结构。 markdown 则是很方便的用纯文本编写 HTML 的格式。比如"# header1"会生成"<h1>header1</h1>""*emphasis*"会生成"<em>emphasis</em>"等等。

安装环境

本博客应用使用 Ruby 1.8.7 版本。安装好后,首先安装 Bundler(gem install bundler),然后编写 Gemfile(见下),运行bundle install即可一次性安装好所需的 gems。

复制代码
# Gemfile
source "http://rubygems.org"
gem 'haml' # Haml 模版
gem 'rdiscount' # 渲染 Markdown
gem 'sinatra' # Sinatra
gem 'thin' # 应用服务器
gem 'shotgun' # 重启服务器
group :test do
gem 'rspec' # 单元测试
gem 'nokogiri' # 解析 HTML 输出
end

测试驱动开发

使用测试驱动开发并非为了赶时髦,只是为了能够帮助我们写出更好的代码。

在本例子中,我们的测试需要能够达到以下目标:

  1. 访问"/"的时候能够正确返回文章列表(虽然只有一篇文章)
  2. 访问"/:year/:month/:date/:title"的时候能够正确地展示文章内容

正式编写

在本例子中,将只接受两个路由请求,'/''/:year/:month/:date/:title'

首先编写如下的测试:

复制代码
# in app_spec.rb
describe 'blog' do
before do
@req = MockRequest.new(Sinatra::Application)
end
it "should show index correctly" do
resp = @req.get '/'
resp.status.should == 200
end
end

运行rspec app_spec.rb可以看到失败结果。先编写简单的代码让测试通过。

复制代码
# in app.rb
get '/' do
""
end

然后继续增加测试,我们想让返回的页面中有链接到/2010/10/10/a-lucky-day这个日志的链接

复制代码
# in app_spec.rb
...
it "should show index correctly" do
resp = @req.get '/'
resp.status.should == 200
doc = Nokogiri.new(resp)
(doc/'a[href="/2010/10/10/a-lucky-day"]').text.should == "A Lucky Day"
end

为了通过这个测试则要写一些长一点的代码,为了省略篇幅,Article类的代码在这里忽略:

复制代码
# in app.rb
get '/' do
@articles = []
Dir.glob("articles/*.txt").each do |article_file|
@articles << Article.new(article_file)
end
haml :index
end

在上文的代码中,首先读取了 articles 目录下的所有 txt 后缀的文件,就是全部的日志。 并把这些日志装到@articles这个数组类型的实例变量。

在视图中,则简单的把日期和日志名称罗列出来。

复制代码
# in views/index.haml
...
- @articles.each do |article|
%header
%h2
= article.date.strftime("%Y 年 %m 月 %d 日 ")
%a{ :href => article.path }= article.title

接下来使用同样的方式来编写显示日志具体内容的代码:

复制代码
it "should show article correctly" do
resp = @req.get '/2010/10/10/a-lucky-day'
resp.status.should == 200
doc = Nokogiri(resp.body)
(doc/'title').text.should == "A Lucky Day"
(doc/'article h1').text.should == " 今天是我的幸运日 "
resp.body.should match " 钱包里面正好有 42 块钱 "
end

实现所用的代码相对会少一些:

复制代码
# in app.rb
get '/:year/:month/:day/:title' do |year, month, day, title|
article_file = "articles/#{year}-#{month}-#{day}-#{title}.txt"
@article = Article.new(article_file)
haml :show
end
# in views/show.haml
!!!
%html
%head
%title= @article.title
%body
%header
%h1
= @article.title
%article= @article.body

测试通过以后,也可以使用shotgun app.rb -s thin开启服务器, 访问 http://localhost:9393 就可以看到在浏览器中的效果。

部署

Heroku 是目前为止最好用的 Ruby 应用部署服务之一。在 Heroku 的帮助下,我们可以快速地把这个应用发布给全世界使用。

首先编写config.ru

复制代码
# in config.ru
run Sinatra::Application

然后运行如下代码:

复制代码
# git 初始化
git init .
git commit -a -m "Initial Commit"
# heroku 部署
heroku create
git push heroku master

当看到"Launching … done"的字样的时候,就说明我们的程序部署成功了,赶快点击下面的链接看看结果吧!

评论

Disqus 是目前我知道的最好用的评论管理系统。更要命的是,它能够很简单的把一个评论系统加到我们的博客中:

复制代码
<section class="comments">
<script type="text/javascript" src="http://disqus.com/forums/#{username}/embed.js">
</section>

只要把上面这段 html 代码加入到我们的系统中,一个完善的评论系统就出现在用户的眼前。本地调试的时候则要额外加上一句:

复制代码
<script type="text/javascript">var disqus_developer = 1;</script>

借助了 Disqus,我们的评论系统就不会逊色于任何的博客应用。

思考

如果读者能够在整个过程中感受到快乐或者惊奇,那么我编写本文章的目的就算达到了。 详细的代码请参考本文的项目地址: https://github.com/nouse/text-blog

以下则为笔者在制作这个应用过程之中的一些思考。

5 年前,Rails 的创造者 David Heinemeier Hansson 向全世界介绍了 15 分钟编写 blog 应用(优酷视频链接)。在5 年后,我们又用Sinatra 重复造轮子,如果读者对比两者的差别, 就能深刻感觉到这5 年里Ruby 世界的一些变化。

基本工具(RVM 和Bundler)

这5 年间,Ruby 基本工具有了很大的发展。这其中最大的亮点就是 RVM(Ruby Version Manager)。 除了如它的名字所述,可以帮助开发人员安装不同版本的 Ruby 以外。它的 gemset 功能也非常 好用。不同的 gemset 之间是一个个独立的环境,从而避免同一个 gem 的不同版本之间的干扰。

如果在项目目录下添加.rvmrc(rvm use version@gemset),就可以让项目处于一个独立的环境之中。 再编写好 Gemfile,将项目中需要的 Ruby 库全部交给 Bundler 管理, 就不会出现部署的时候缺乏相应的库导致失败的情况了。

方便的部署

Git 的普及和 Heroku 的崛起,大大简化了部署的过程。如果 5 年前有 Heroku 的话, DHH 的博客应用可以有更大的反响。“编写完成”–>“git push”–>“上线!”。 一个博客应用就一瞬间仿佛活了一样,从一个本地的演示项目变成了一个真正的线上应用。

Disqus 等第三方应用的兴起

5 年前,Web 2.0 刚刚兴起,只要编写一个使用 Ajax 增强交互功能的应用, 就可以吸引用户的眼球。但是随着 Web 2.0 的概念深入人心,做一个 blog 显然不再能吸引用户的眼球了。

如果 Disqus 这样的第三方应用能够逐渐增多,那么我们就能够把更多的时间放在我们真正想实现的功能上。 就像这里,我们只要把博客的内容展示做好就够了,其他的则交给成熟的服务来处理。 Rails 的成功就在于简化了开发 Web 2.0 应用的时间。借用一下 jQuery 的口号“write less, do more”, “写的更少,做的更多”是软件开发永远的主题。

Sinatra 和 Rails 的关系

DHH 在推出 Rails 的时候,让深陷于 Java 世界的开发人员看到了希望,Rails 也借助 Web 2.0 的热潮迅速走红。 其实,笔者所做的演示的功能模仿的是一个 Rack 应用程序, toto 。 所以读者们也不必迷信,用 Sinatra 经过 15 分钟能做出更好的博客应用,就说明 Sinatra 会取代 Rails。

当前最流行的方式是融合,比如 gemcutter.org,也就是现在的 rubygems.org。 他们整个站点使用的是 Rails 3,而客户下载 gem 的请求则是被 Sinatra 处理。 这样就可以保证网站在升级的时候不会影响下载 gem 的请求,而且 Sinatra 处理请求的速度也优于 Rails 3, 用来处理每天超过访问网站数倍的下载请求也十分合适。

不管怎样,只有更多的了解一个框架的优缺点,才能在真正使用的时候做出正确的选择。而 Sinatra 的源代码只有一千行,要了解它并做出选择,相信不是件难事。


关于作者:吴江,Ruby 和 Javascript 程序员。从 09 年开始,在国内社区中积极宣传和推广 Sinatra。10 年 8 月底,以演讲者的身份参加了在日本举行的 RubKaigi。现在上海一家 Ruby 行业的咨询公司工作。

2011-01-21 00:0010276

评论

发布
暂无评论
发现更多内容

Web网页端IM产品RainbowChat-Web的v6.0版已发布

JackJiang

网络编程 即时通讯 IM

软件测试/人工智能丨成员运算符

测试人

人工智能 软件测试

Nacos 配置中心源码 | 京东物流技术团队

京东科技开发者

源码 nacos 源码剖析 配置中心

docker通过dockerfile安装sftp教程。

百度搜索:蓝易云

Linux 运维 Dockerfile 云服务器 sftp

如何将在线教育小程序一键生成App

Geek_2305a8

CloudQuery x 达梦,国产数据库正当时

BinTools图尔兹

数据库 数据库管理 数据库安全 达梦 兼容适配

010 Editor 十六进制编辑器 注册激活版 mac/win

Rose

010 Editor下载 010 Editor破解版 010 Editor注册码 16进制编辑器

INTO领航:2023社交变革峰会揭示数字社交的未来格局

Geek_2d6073

Atlassian发布四个CVSS风险评分9.0或更高漏洞,影响多个产品

龙智—DevSecOps解决方案

Atlassian

SVN优缺点详解及版本控制系统选型建议

龙智—DevSecOps解决方案

svn 版本控制

Topaz Video AI for mac v4.0.7注册激活版 人工智能视频增强 支持M/Intel

Rose

mac软件下载 人工智能视频增强 Video Enhance AI 下载 Video Enhance AI 注册

基于FFmpeg实现一个数据流风格的视频处理工具 | 社区征文

为自己带盐

ffmpeg #技术人的2023总结

SVN管理工具Cornerstone for Mac入门教程 Cornerstone永久破解资源

Rose

零基础也能搞定文案生成应用,半小时包教包会!「大模型摇摇乐」硬核教程来啦!

飞桨PaddlePaddle

人工智能 代码 零基础 开发教程 文案生成

开源MES/免费MES/开源MES生产流程管理

万界星空科技

开源 开源代码 开源软件 免费开源 开源mes

Amazon CodeWhisperer 免费的 AI 代码生成助手!最新体验反馈~

亚马逊云科技 (Amazon Web Services)

人工智能 亚马逊云科技 云上探索实验室 Amazon CodeWhisperer

NFTScan | 12.04~12.10 NFT 市场热点汇总

NFT Research

NFT NFTScan nft工具

【数据安全】金融行业数据安全保障措施汇总

行云管家

金融 数据安全 运维安全 数据安全运维

SmartGit for Mac(老牌Git客户端)v23.1.1中文注册版 支持M/intel

Rose

SmartGit破解版 SmartGit许可证 Git 客户端 SmartGit for Mac SmartGit 中文

万界星空科技低代码平台:搭建MES系统的优势

万界星空科技

低代码 数字化 MES系统 低代码开发 mes

MongoDB和阿里云携手驱动WeLab 引领超千万用户迈向智能金融未来

Geek_2d6073

Wireshark中的http协议包分析

小齐写代码

oracle dblink mysql查询text无法显示问题

百度搜索:蓝易云

MySQL oracle Linux text DBLINK

大模型发展的前景与挑战 主赛道:技术人的 2023 总结

不叫猫先生

大模型 ChatGPT #技术人的2023总结

VisualDiffer for Mac(文件夹和文件比较工具) 1.8.9中文激活密钥版

mac

苹果mac Windows软件 VisualDiffer 文件快速比较工具

mac强大的音频处理工具Ableton Live 12 中文版最新

胖墩儿不胖y

Mac软件 mac音频编辑器

视频后期特效合成软件:Blackmagic Fusion Studio18 激活最新

mac大玩家j

Mac软件 特效合成工具 Mac软件特效

LED透明屏市场前景展望

Dylan

全球经济下行 中美贸易 LED LED显示屏 led显示屏厂家

Sermant:无代理服务网格架构解析及无门槛玩转插件开发

华为云开发者联盟

云原生 后端 华为云 华为云开发者联盟 DTSE Tech Talk

Fusion Studio 18 v18.6.4完美兼容破解版 附Fusion Studio激活补丁

Rose

mac视频后期特效处理 Fusion Studio 18下载 Fusion Studio激活秘钥 Blackmagic Fusion Studio

Q-learning 入门:以 Frozen Lake 游戏环境为例

Baihai IDP

人工智能 程序员 AI 强化学习 白海科技

用Sinatra编写博客应用_Ruby_吴江_InfoQ精选文章