反馈 为什么 ruby-china 的 erb 源码, 代码缩进乱七八糟的?

zw963 · 2012年05月17日 · 最后由 sharp 回复于 2012年05月27日 · 10628 次阅读

使用浏览器查看源码看了下编辑帖子请求的源码,结果那个缩进,堪称惨不忍睹...

社区天天都有人讨论编辑器,难道没有个像 Emacs 的 format-buffer 的功能,一个快捷键,自动重新排列下么?没有缩进,给阅读代码带来很大的困扰。

公开开源项目,编码风格,缩进风格,真是一个很大的问题,对于别人参与进来,甚至只是简单的阅读,学习,造成很大的不便。

我一直认为 vim 的自动格式化功能很弱!虽然大部分人鄙视用 Netbeans 的,但是 Netbeans 格式化功能是非常好用~

你是说生成完以后的 html 结果么?

模板缩进有什么好办法?这个问题,我一直很头疼。

rubymine 的自动格式化 erb 我觉得还可以接受

貌似楼主说的是浏览器 右键->查看源代码 的这个出来的代码的缩进吧

ERB 文件本身应该没有什么的,但是 ERB 生成的 HTML 确实要想写好就要注意,比如用 -%> 这样就不会新增行等等。有些可能就没有办法了。

想要生成的 HTML 源代码好看,用 haml 是可以的,只是又要学习一种方言了。

#1 楼 @zw963

ERB 本身应该是没什么问题的,我想主席说的是生成的 HTML 源代码吧?

生成的 HTML 的确是缩进有问题,不过一般在浏览器里看源代码都是用 Developer Tool 来看,这些工具都是自动格式化的(Firebug, Inspector),只要浏览器支持我想不会再有能看懂 HTML 源代码的人直接用查看源代码来看页面的源码。

我不清楚 ERB 有没有选项能为生成的 HTML 格式化,Slim 默认是全部挤在一起,没有任何缩进,也可以设置为 pretty print,这样会生成很美观的 HTML 源码,不过这样在处理速度上面就会有一些下降。

#3 楼 @huacnlee 没错,的确是在浏览器右键,直接查看的。我还没看过咱社区的 erb 源码。

#7 楼 @ntyangxd 如果问题真是你说的 each 或这 for -%>造成的,我认为定制编辑器就可以解决的。(我也的确是这么干的)

#8 楼 @willmouse Chrome 有你说的工具,只是不太习惯使用。另外,我看代码的初衷只是验证自己的一个小小想法,并不是要分析什么代码结构,我想总是还会遇到直接查看源码的情况吧。

我很纳闷,为什么 Agile 书里的示例,生成的 HTML 缩进非常整齐?我觉得可能还是跟有些不好的习惯有关 (我现在还不清楚), 又或者跟太多的 partial 混在一起有关?发这个帖子之后,我特地的查看个 github 生成的 HTML 源码,相当整齐,虽然也存在多余的空行的问题,但至少,对称的元素起始标签和闭合标签,缩进是相同的。

但是咱 Ruby-china 的源码,没有开发工具,完全读不下去。我尝试着复制 HTML 源码到 Emacs 的一 buffer 里面,并自动格式化了一下,稍微好看点了,不过最让我吃惊的是:标签并非完全对称,最后一个</html>竟然和最初的<html>缩进竟然不匹配!这幸好是 HTML , 如果是 XML , 出现了这种问题,能解析正确才怪!

我查看了下代码,发现问题出在:

<meta charset='utf-8' >    # => 这里的标签没有闭合, 每个页面都如此! 模板问题.

也许你们觉得这不是问题,不过在我看来,这不就是从 HTML 过渡到 XHTML 的意义所在吗? 我觉得上面的错误就是生成的代码很凌乱的原因之一。因为从那一行之后的所有行的缩进,和之前都无法匹配。

#9 楼 @zw963 一般就算你少了个闭合标签,大部分情况下还是可以解析成功,因为浏览器很宽容。另外 XHTML 确实是比较严格的,但是它忘了人都懒惰、会犯错,这也是为什么会从 XHTML 2.0 转向 HTML5。

这?我还曾专门做过把 render 出的 html 里空格换行都干掉的事呢。

#9 楼 @zw963

In HTML the <meta> tag has no end tag.

In XHTML the <meta> tag must be properly closed.

http://www.w3schools.com/tags/tag_meta.asp

浏览器右键的源码,是给浏览器看的,哈哈。google 主页的代码就很乱。

#9 楼 @zw963

应该只是 Ruby China 没有特意输出格式化过的 HTML,应该是 ERB 这块没配置

至于查看 HTML 源代码,我想做 Web 的人,天天经常会查看后端输出的 HTML,不过现在我是没见过有开发人员直接拿 HTML 源代码来看,都是借助浏览器提供的开发工具来看,因为功能实在是太强大了。

就跟 Rails 写测试会用 guard 等 watcher 来监视文件变化,从而达到自动测试的目的一样,guard 相对测试来说是个必不可少的工具,Firebug、Web Inspector 对分析页面源代码及样式表、性能测试都是必不可少的。

ERB 生成的 HTML 源码一定是可以良好格式化的,可能是部分 view 嵌套的东西比较多出了些问题吧。

没必要在意这个无关紧要的事情

#10 楼 @Juanito

XD, 严格不是错,相反是好事情,而且,XHTML 太严格,我想绝对不是从 XHTML 过渡到 HTML5 的原因吧?难道 HTML5 又要回归 HTML4 之前的自由主义,无约束的风格状态?

@zhangyuan

HTML5 要求同样是严格的。(看起来,咱社区使用 HTML5 DOCTYPE ? )

现在问题是:使用了那么多 META 标签,唯独有一个不闭合,代码解析能正确才怪。浏览器干了太多的这种费力不讨好的事情。

#15 楼 @huacnlee

这怎么成了无关紧要的事情,上下总共五六个 meta 标签,唯独一个少了个闭合标签,并由此,让每一个访问 Ruby-china 的浏览器都需要额外的来处理下这个 `非常规情况' , 只需要代码风格统一一点 (增加闭合标签), 浏览器会少做了很多费力不讨好的工作,格式化输出结果也应该比原来要好很多。

#16 楼 @zw963 嗯,严谨挺好的,但是大多数程序员不喜欢被束缚,程序员都很懒惰、崇尚自由。HTML5 是蛮宽松的,但也有一套规则在,更总结了 HTML4 一些常用的 id/class 名字创了许多具语义标签让我们使用。。。还有当初发展 XHTML2.0 那群帅哥 W3C 决定不向下相容 HTML 4, 几个不安的人跑出来搞了个 WHATWG,后来 W3C 终于意识到 XHTML 2.0 是死胡同,没路了,求爷爷告奶奶的与 WHATWG 合作,成立了 HTMLWG。HTML5 横空出世喔耶!

#17 楼 @zw963 你最初不是在谈缩进的问题么?

很注重输出格式的缩进的话可以试试 HAML,我始终记得看到它输出的 HTML 缩进整齐的那一刻(但那之后就没再用了)。

不过反正浏览器都能读取,而且真要优化应该是从 CSS selector 和 JavaScript 效能去着手,不是纠结 HTML 缩进...

#19 楼 @huacnlee 我觉得符合 XHTML 规范的单标签闭合这是应该需要加上的,我看了下 laiout 里有几个 meta 标签漏掉了结尾的 /

#11 楼 @huobazi 其实用 slim 做模板的话,默认渲染出来的 HTML 都在一行,没有空格、回车⋯⋯

而至于 meta 少了 / 这个确实是个问题。

但我说“无关紧要”所指的是 HTML 结果,这些缩进差些没有任何问题,我只用保证源代码里面是整齐的就好了,如果我为了排好它需要在代码里面格外小心翼翼,这是一件多余的事情。

#1 楼 @zw963 其实我很想说,你既然 #9 楼 说连 Ruby China 的 erb 文件都没看过,怎么可以这么快下这个结论呢?

我本地改了楼主指出的问题(标签闭合/编辑器排版),输出依然缩进不正确,估计 erb 就是这样。我没有提交,@huacnlee 应该是不喜欢「仅仅让 html 输出更好看」这样的 commit 的。

网上搜到些后置过滤器,或者在 rack 做动作的方法,不过我觉得不值得。在乎缩进的可以用 haml 这样自带格式化的模板,不过注意默认配置生产环境是去掉缩进的:

:ugly If set to true, Haml makes no attempt to properly indent or format the HTML output. This significantly improves rendering performance but makes viewing the source unpleasant. Defaults to true in Rails production mode, and false everywhere else.

http://haml.info/docs/yardoc/file.HAML_REFERENCE.html

再提个问题,render_body_tag 这个 helper 会干扰编辑器排版,而且也不符合惯例,一般包裹性的 tag helper 应该用 do end 包起来,不然会忘了闭合。(我就不说这个 helper 来自哪个我一开始就质疑的 gem 了)

上面是技术问题,下面是非技术问题。

一进来就感觉这个主题很不愉快,主题是说 erb 源码,内容是说 html 输出,然后楼主也没看过 erb 源码,还群嘲了编辑器众。

就像提问的智慧提到的,不要一上来就说「你写的软件有 Bug」,这样作者感到明显的敌意,本来该处理的问题也不想处理了。指出问题有价值,解决问题更重要。

我也是对代码乃至输出格式都很在乎的人,不过也不能要求别人完全和我一样,因为别人的注重点跟我不同,有我没有的东西。

还有 js,css 里面揉成了一行你为什么不说呢?那样更没法看。 我说这句话的意思还是想阐述上面回复的观点,HTML 结果本身就没有考虑过别人看,本来还想一起去了空格的,但想想是多余的运算,也就算了。

#23 楼 @huacnlee

是的,我的确没有看 erb 源码,不过既然能看到 HTML 输出,我一样知道问题在那里。

我刚开始是说缩进问题,没错,你说你只要保证源代码里整齐就好了,但是就算我不看 erb 源码,我也可以下结论,你的布局模板肯定缩进有问题。就算你排的再整齐,也是你纯手工排列的,绝对不是类似于 Emacs这样, 根据语法解析自动缩进 , 后者和浏览器以及 erb 文件的解析方式是一致的。

换个说法:因为 `布局模板' 一个很小的错误,即使看起来源码是对齐的 (你用手工对齐), 但是对于浏览器来说,始终是不对齐的。(如果是严格的标记语言,应该会把缺少闭合标签的那个 meta 和下面紧跟着的另一个 meta 元素的闭合标签算作一个元素).

说白了,就是你看着整齐,不代表浏览器看着整齐,你那个布局模板,放到 Emacs 的 html-mode 下自动格式化,肯定照样最下面的</html>会多一个缩进。

如果只是输出缩进的问题,实在无关紧要。

生成的 html 缩进有问题,这东西影响到开发者吗?影响到用户吗?

#27 楼 @zw963 你把 <%= render_body_tag %> 这行替换成 <body> 再排版看看

有没有 close tag 跟缩进整不整齐是两回事啊。况且你真要说浏览器看着整齐,tag 之间没有缩进没有空格没有回车那才叫整齐吧(parser-friendly)。

#25 楼 @Rei

我承认我偏题了,呵呵,因为我常常讨论偏题。代码格式化排列问题,我的确没看源码,我只是推测,如果标签能够正常匹配的话,应该只有空元素 或 多余的空白行,会出现缩进问题,块元素 至少是一个同一个模板内生成的块元素,缩进应该是严格匹配的。但事实上并不是这样。

说起编辑器,现在觉得,其实讨论的是另一个话题,就算跟 erb 输出缩进无关,不过跟 布局模板 中 漏掉了一个 闭合标签 多少还有点关系,对吧?毕竟,如果常常格式化代码 (甚至编辑器自动格式化代码), 这个问题早就该发现的。

那个 render_body_tag 好熟悉啊(望)没记错的话应该是为了输出 IE-specific class 加上 controller / action-class 的...在某些情况下这些 class 很好用,不过既然是 Ruby China 应该可以不要 IE class 吧。我也同意 #25 楼 应该要有 do ... end

#33 楼 @chitsaou 那个是 xdite 写的。

#30 楼 @Rei #34 楼 @huacnlee

好啦,你们知道,我其是不是那个意思的。什么群嘲之类的。只是发帖有些随意。下回我注意就是了。

我还发现一个小问题:

<fieldset>

这个标签也没有闭合。

我觉得类似问题,肯定不只是这几个元素,如果把这些小问题 都揪出来的话,最终输出效果应该会有改观,erb 解析代码的方式,可没有浏览器那么智能对吧?(事先声明:我只是站在一个 rails 小白的角度考虑问题,所以可能和各位不太一样,哈哈)

#35 楼 @zw963 恩,翻了几个 erb 觉得有不少同类问题,可以专门开个 issues,整理排版同时检查标签闭合。

#37 楼 @Rei

可以考虑以下方案:

  • 搜集整理所有可能出错的标签,编写个 Ruby 脚本,直接针对所有的 erb gsub 一遍就完了,不过可能会考虑不周的问题。

  • 找个支持标签语法缩进的编辑器,针对所有的 erb 文件运行下自动缩进,凡是排不整齐的,都有类似问题。找出来,修改之,并单独测试,这样的话比较稳妥。

我有心自己去弄,不过 rails 水平 还太初级,怕引起其他不必要的错误,再过几个月时间经验丰富了,我也期望能给咱社区贡献代码。

看了一下你们的回复时间,好多都是在后半夜活动啊。注意身体啊 兄弟们! (此楼已歪)

我反而希望 erb 能够像 slim 那样,所有的 HTML 输出都在一行

#40 楼 @quakewang 那个写个 Helper 用正则去掉就好了 Django 里面就有一个叫 spaceless 的 Helper 用来清除空白

其实所有大公司的输出 HTML 都不是让人看的,而且说实话我还非常希望输出 HTML 结构能够乱到不能人为分析

使用 vim 一直懒得设置。纯人肉检测。随便 review 下代码。实在太难看 gg=G 简单解决

#42 楼 @5ive 既然浏览器能解析,自然就能有工具把“不能人为分析”的 HTML 处理成能够人为分析的排版,Chrome 里 Command+Option+i 就能看到了

我对楼主的议事方式表示叹服,标题说 erb 排版好乱,结果内容说浏览器里查看 HTML 源码,然后很自以为是地认为排版 erb 输出的 HTML 就是编辑器里 html format 一下这么简单。

然后,话题忽然一转,到了标签是否闭合。我猜 @huacnlee 都要崩溃了。

#45 楼 @dotnil

原本不打算回复,看你对我这么不满,还是解释下。

标题,内容不符的确是事实,不过,虽然主题混乱,不过归根结底,讨论的中心其实都是一个问题:代码风格是否规范,只不过在此表现出来的副作用是输出乱成一团糟,但是良好的代码风格,应该不仅仅是格式化输出好看这一个好处吧?

自以为是地认为排版 erb 输出的 HTML 就是编辑器里 html format 一下这么简单

你不要把别人的想的那么肤浅好不好?没有人是笨蛋,不过这个事情上,还就这么简单。就这么编辑器 format 一下,问题已经很确定了。而且我越来越肯定,你只要满足以下两点,缩进就不会有问题!

  • 所有的空元素自闭合,块元素一定要包含配对的闭合标签。
  • 具有多个参数或复杂哈希参数的 helper 方法,所有参数使用括号括起来 (不要学 Agile 中 Dave Thoms 的风格) , erb 输出可没有浏览器那么宽容,大度。

光说没用,你试试,看你那编辑器 format 一下能不能把缩进的问题修正。 是在 ERB 里面哦。

#46 楼 @zw963 还真是奇了怪了,是我把你想得 肤浅,还是你的提问与你的解决办法都相当的 无厘头。你倒是试试 format 一下 erb,输出的缩进是不是就正确了。

不知道是否可以通过 w3c 的认证

#47 楼 @huacnlee

呵呵,好吧,我知道你肯定有理由给我回复。 我暂时无法测试,除了 erb 中混了大量的逻辑之外,我承认也许还有其他潜在问题会影响输出缩进。 模板文件太多,我暂时也搞不清楚之间关系,也不确定模板中间是否有 (不应该有的) 耦合。我可以举个例子:

https://github.com/ruby-china/ruby-china/blob/master/app/views/common/_user_nav.html.erb

上面的代码来自 ruby-china, 我并不了解这个 erb 实现的具体功能,但是我诧异的是,这个 erb 代码中,凭空多出来两个混杂了大量逻辑代码的<%= end %>标签 , 在我看来,end 之应该是 条件 或 循环 或 do ... end 的结束标签才对,不是吗?现在凭空造出来两个 end 标签 (分别是:第 12 行到第 21 行,第 25 行到第 28 行), 我不确定这是一个 trick, 又或者和其他 erb 文件相呼应?又或者之前有方法隐式的生成起始标签?

无论那种情况,问题在于,这是 erb 文件,而不是 ruby 源码, erb 则会按照标签的闭合情况来来生成最终的 HTML 代码, 因此,缩进问题就产生了。

顺便提下,呵呵,这个 erb 文件中,还有一个<spanc>标签写错了。好在这是一个内联元素,如果是一个块元素,包含其他元素,这肯定又是代码缩进的罪魁祸首了。

我觉得这个问题到此为止吧。等我将来有空,详细分析 erb 代码,并测试后,我会单独开个帖子重新讨论这个问题。

#50 楼 @zw963 我怀疑大大们都已经不想看这个帖子了,我给你大致解释一下为什么输出的源码不是对齐的吧。不知道楼主有没有尝试过 Rails 开发?或是真的写过 Ruby 么?

首先要说的是,我们一直强调的代码整洁是指开发者直接面对的代码,就是你在 github 上看到的文件。 你在浏览器里查看的源代码是用自动化工具自动根据 erb 文件生成出来的 HTML 文件。 这个文件就是给浏览器看的,人看得爽不爽无关紧要,所以闭合可以算是个问题,代码对齐绝对不是问题。

先说一下代码闭合的问题,就像 #12 楼 说得那样,这个在 HTML 的官方约定中也明确说明了标准的处理方式是什么。 如果一个浏览器不能正确处理,说明它不支持标准的 HTML 语言(比如严格依赖 XHTML 标准来处理 HTML 就是个愚蠢的决定),这是浏览器的问题,不是开发者的问题。 而且只有在 XHTML 中才有严格的闭合要求,Ruby China 在文件头声明的就是<!DOCTYPE html>。这一点问题都没有。

然后我来说明一下为什么说渲染出来的 HTML 文件没有代码对齐不是 Ruby China 开发者的错。 要说明的是,这是一个很麻烦的工作。 Rails 在渲染 HTML 的时候,一个页面会嵌入其他的函数或是模版,他们都会生成他们功能所对应的 HTML。 而他们自己是不知道自己的父函数已经缩进了多少列,即使有办法获得也是相当麻烦,甚至是需要直接 Hack 的。 如果真的需要渲染出人类可以欣赏的 HTML,最好的办法就是在整个页面渲染完毕后,再利用另一套工具规整全文的 HTML。 这种优化在开发环境中可能还有些意义,但是在生产环境中是全然没有任何意义,因为人不会去看,浏览器不在乎,而且降低了程序的运行效率,用户不爽。

至于你提到的 end 标签问题,实际代码是这个样子的:

<%= render_list :class => "nav pull-right", :id => "userbar" do |li|
  li << link_to( t("common.register"),new_user_registration_path)
  li << link_to( t("common.login"), new_user_session_path )
end %>

我没有这样不断行地写过,不过这样些没有问题。这并非是凭空出来的标签。 这实际上是一句话,28 行的end闭合的是 25 行的do,尖括号中间的这四行都是转义的 Ruby 代码。 它渲染了一个 list 给这个元素添加两个子节点 li。为什么会被理解为 trick?

至于你所说得spanc,这的确算是个 bug。 遇到这种情况你可以 fork 一个版本修改并发起一个 pull request,或是简单的提交一个 issue,这样也算为 Ruby China 做贡献了。

//顺便跟 @huacnlee 说下,第二行的逗号后面应该有一个空格,这个其实不算洁癖吧。

#52 楼 @ranmocy

哇,你解释的真详细,太谢谢了。让我终于明白了那个 do end 是干嘛的了。我熟悉 Ruby, 没写过 Rails, 所以还真是头一次见到这个写法,主要原因是见<% end %>见多了,end %>给了我错误的印象。

不过有两点你的理解有错误。

  1. Rails 在渲染 HTML 的时候,一个页面会嵌入其他的函数或是模版,他们都会生成他们功能所对应的 HTML 而他们自己是不知道自己的父函数已经缩进了多少列 你这句话没错,不过这丝毫不影响缩进的正确。你再想想是不是?你可以自己写一个非常小的 erb 文件,互相调用测试一下。

  2. 如果 do end 正如你所说的那样解释和的话,那么一定可以替换为更加清晰易读的代码。你这话更加印证了之前的论点。

既然知道那个 end 的用途了,那么代码也就好改动了,下面是我修改后的代码, @huacnlee 你看看,这是不是就是你说的 format 一下能不能把缩进的问题修正, 你不妨拿你的编辑器试试,看看自动缩进是不是很整齐?

下面是我修改后的代码: https://gist.github.com/2769467

代码一目了然,而之前的代码,甚至 do 语句和 end 语句都无法对齐,而因此引申到其他 html 元素也跟着乱乱的,很难保证像我这样的 rails 新人会看的糊里糊涂。对不?而且作为一个公开开源项目,如果代码风格太个人化,肯定不利于协作,对吧。

@huacnlee @Rei

不妨再给两位大大提点意见:

这个帖子,虽然扯的有点远了,而且主题不清,呵呵。不过,所有这些讨论都是来自于HTML代码 非常乱这一个初衷,不管它们和 缩进 之间的关系大不大,甚至没有关系,我也是希望,有良好的代码缩进排版 (这毕竟是给人看的) 以及代码风格。这样才会有更多的人参与。我想谁也不愿意,在贡献代码之前,先费劲儿了解别人那些 (尤其是不好的) 编码风格,这还只是个几个人维护的小项目。将来项目做大,如果这个问题不解决,绝对不仅仅是 输出HTML缩进不整齐 这种 无关紧要的事情, 绝对要出大问题!

我觉得你们也看到了,我只是 让编辑器自动format了一下代码 , 就发现这么多小毛病 (如果不是这样,还真的很难发现), 这至少说明一点,只要你采用良好的代码风格,尽量满足规定格式文件的严格语法要求,编辑器就会帮你指出大部分容易忽略的小问题.(至少对于 html 是这样的).

匿名 #55 2012年05月22日

吃饱饭没事做,很多网站的源码还是经过压缩的呢 BTW:你可以用 firebug 看,层次感很强

#54 楼 @zw963 Rails 风格指导这个 Ruby 社区首推的 Rails 代码编写风格里面还真没说的这些编码风格问题 另外, 将来项目做大,......这个观点,请参照 Getting Real 这本书的相关章节,比如当问题成为问题的时候才去担心

#49 楼 @chucai w3c 的认证虚幻的,能在所有 A+ 浏览器里正常使用的网站才是好网站。HTML 再符合规范,真正的浏览器渲染有问题,就全都白搭。

#54 楼 @zw963 code wins argument. 这点我没啥好说的。容我再吐槽一句,你做的事情,可不是直接在原代码上 format 一下这么简单罢。

如果需要好看,Haml 可以方便解决。

#58 楼 @dotnil

真这么简单,反复的 C-c C-c, 然后修改代码,直到缩进正常,并且不报语法错误为止 (例如不匹配之类的), 只要具有很初级的编写 erb 经验,查错很便捷的。

如果你不按照规范来 (就像原来 Ruby-china 的代码), 会提示一些缩进匹配错误之类的一大堆信息,你如果不规范它,这些信息对你除错完全没用了,你根本不知道代码真问题还是仅仅是缩进问题。

#13 楼 @sevk google 主页需要速度,经过压缩处理了的,只有机器能高效解释,不需要考虑到有人去读代码。。。。

还是不太懂楼主意思,你是建议大家都在写 erb 都先格式化一下 erb 源码吗,还是格式化输出的 html 代码?

  1. 生成后的 html 那不是源码。
  2. meta 本身就不用闭合,html5 就推荐这么写,也不会如楼主所说的增加浏览器解析负担。
  3. GitHub 明明不是对齐的。

楼主的追求无意义。建议 @huacnlee 对生成的 html 做一下压缩,就不会有这样无意义的讨论了。

匿名 #64 2012年05月27日

说真的, “code wins argument”这句话倒是很牛逼哄哄,只不过用在这个场景显得不是很合适,哈哈

需要 登录 后方可回复, 如果你还没有账号请 注册新账号