天津福康,电子烟,磁疗,远红外线产品。
09

sns ui 设计要看的两篇文章

分类:tech | 给我留言 |

声明:本文转载自http://www.5gme.com/space-84-do-blog-id-8867.html

浅析facebook的信息架构

facebook的信息架构设计,是目前为止互联网上我见过的最合理的信息架构。

每次培训,我基本都需要拿20分钟左右的时间来解析它,包括老的、新的、被抄袭的。 一直打算把这个解析过程写下来,但讲的时候可以图音并茂,写的时候确实表达起来很难。
今日权且一试,希望能把培训师讲到的内容表达出30%。(只写现在界面上表现出来的东西,不分析栏目划分已经扩展性问题了)

先看facebook老版界面的信息架构:

 

大架构的发展和变迁过程: 

1、最开始,facebook的整个信息架构主要分成三个部分:“系统核心导航区”(如上图,蓝色部分。包括LOGO和两个全部导航)、“应用导航区”(如上图,黄色部分。包括一个全局应用(搜索)和所有的应用列表)、“内容显示区”(如上图,橙色部分。主要分成局部导航、主内容、辅助内容三个大部分,有N多主要内容)。

由于“系统核心导航区”、“应用导航区”的常态存在和内容繁多,在用户使用时经常会干扰用户对主要内容的关注。所以,facebook在视觉设计上,特意通过错位特别突出了“内容显示区”(如上图,橙色部分。我看到有些设计师说“facebook的视觉很烂,把那个位置扭曲了很傻”,其实他们根本没有看出设计者的意图,很傻!)

2、后来,facebook添加了“协作翻译”,这是一个全局功能。按照一般的设计思路,这个“翻译”的位置选择可以:放在“全部导航3(设置)”的位置,或作为“全部导航2(应用)”的一个常态项目。
但facebook没有这么做,为了更好的表现其牛逼的UGC魅力,facebook的设计师大大加重了“翻译”在导航上的比重。“不伦不类”的把这个应用,突出在了“内容显示区”的右上角,同时在“全部导航3(设置)”里加了一个语言切换的导航(后来大概是发现“语言切换”的使用频率很少,现在给调换到了底部版权信息的右侧)。

3、再后来,facebook推出了IM功能。对于facebook来说这是一个常态应用,在信息架构上必须常态存在。于是他们把“即时通讯”结合了“信息通知”一起作成了“状态栏”的模式。  (我猜想,这个时候facebook的设计师们已经有了“操作系统”的设想)

这是一个很艺术性的设计,处理的非常好。而且IM本身设计做的非常轻巧易用。 在此之前我曾经猜测,他们可能会把IM放到“系统核心导航区”的“收件箱”的位置,结果我错了,他们找到了更好的设计方式。

4、如今,由于“系统核心导航区”(如上图,蓝色部分)、“应用导航区”(如上图,黄色部分)是常态存在的内容,占据了界面很大比例的位置,再加上内容显示区(如上图,橙色部分)本身还需要一些“关联导航”“友好导航”已经“标题”的内容,导致每个页面真正展示“内容”的区域很少很少。
作为一个网站,这没有什么大问题。但作为一个“应用平台”,这无疑有很多的障碍,界面内容展现严重受限,用户的视觉总是浪费“常态导航”上。想一想如果你的操作系统界面,1/3空间长期被系统菜单占据,你会不会崩溃?

.

我对老版设计的,几个主要评价:

1、逻辑清晰,层次分明严谨。扩展性好。但在内容呈现上,缺乏创新。

2、facebook整个网站的核心是“我的”,这就是他顶部系统核心导航区(如第一张图,蓝色部分)。另外,顶部还有“全部导航3(设置)”。整个顶部是网站的核心,用户不可能被用户或者第三方改变,也是facebook的官方保留“区域”。

但,这里有个细节他们一直蹑手蹑脚没有真正放开,就是那个权宜之计的“home”。
事实上现在大部分用户返回首页都会点击logo,facebook在主导航上取消了“home”,但又不敢完全取消,于是在“全部导航3(设置)”那个区域前面加了一个“home”,而且还把这个链接和logo的链接作了区分,一直保持着对数据的检测(包括最新的信息架构设计也一样作了链接区分,在检测数据。有兴趣人可以看看logo的链接和home的链接地址不一样)

3、facebook的主要导航其实是“应用导航区”。这里影响了主要内容区的显示。
“系统核心导航区”和“应用导航区”包围着内容显示区的做法,结构和逻辑都很清晰,而且容易理解。

4、主要内容区有一个设计一直存在争议:
比如,在“图片”的页面,facebook加了两个链接“我的图片”“有我的图片”,这两个链接被处理成了“友好导航”,用户点击后到了新的界面,新的界面无法返回当前“图片”的应用。
但,就国内用户(我不是很相信在这个地方存在国内外用户使用习惯的偏差)的使用习惯来看,这两个链接应该被当作“关联导航”甚至“局部导航”处理。这也是UCH在抄袭facebook时做过的为数不多的“好改动”之一。
.
.

再看看facebook现在新的信息架构设计:

如上所说,老版的信息架构显示了facebook的主要内容展示区域。使每个界面都背负了严重的“导航任务”。
于是facebook开始尝试改变。刚开始,他们试图拉宽整个内容显示区的空间,把应用导航区和常态提示信息放到系统核心导航区下面,做成windows“开始菜单”的模式。(这个版本有些人看到过,UCH现在准备出的新版抄袭了这个设计。在这里不做详细评价)

(也许他们觉得这样还是太啰嗦,内容显示区还是不够大),现在他们把应用导航区合并到了系统核心导航区里。 不仅是内容布局上作了改变,连栏目的规划都有了新的变化。(这个版本可以在“http://www.new.facebook.com”看到)

 

 

主要变化:

1、将所有全部导航和引用压缩到顶部的一个区域,甚至不惜大举压缩LOGO尺寸,让这个区域尽可能的小。(如图,蓝色区域)
当然,这样的大变化也伴随着其栏目划分的重新规划。

2、将广告从左边拿到右边。尽可能的放大并在主要的视觉“焦点区”突出具体的页面内容。

3、保持IM和通知的常态显示,并将“翻译”合并到一起。

.

我对新版设计的,几个主要评价:

1、新的信息架构设计其实面临着很大的调整。要从一个传统网站到一个应用平台作专门,确实很难很难。对于一般的界面设计师来说,这个任务很难完成。但facebook的设计师做到了,而且从时间上来看他们很有前瞻性,呈现层的设计甚至走到了策略之前。
2、新的设计改的大胆,页面就应该表现出“系统”的感觉。 每一个应用就像一个软件。“应用”列表就应该合并起来,“应用”和“应用”之间的切换根本不需要那么快捷。

3、顶部蓝色的主导航区应该再加宽(只要不是100%宽度就行)、压低,完全做成状态栏的样式。

3、把应用夹杂到“我的”一些选项中间不合理。特别是放在好友和收件箱中间。
如果是我设计,我会把LOGO变成“开始菜单”,把应用放进去。

.
.

最后,看看一些抄袭者的作品:(是谁我就不说了)

(作品1)

点评:
这个设计单看一个页面就有问题,属于层次混乱。 单个页面的逻辑不顺畅。
用户经常不知道自己在哪里。
而且没有将关联导航和友好导航区分开,次序和逻辑都交代的十分混乱。 

.

(作品2)

 

点评:
这是某社区专家的网站结构图,单看他的页面没有任何问题,结构清晰,层次分明。
但,用户只要一使用,就晕乎。改动过的信息架构(其实只是把内容区的“关联导航(操作和设置)”的放到了“全局导航2(应用)的上面”)使用起来极其不流畅。(为什么不流畅,在这里不多解释)。

该网站从上线到现在一直充斥着一类投诉:靠,怎么加入群呀? 怎么设置群? ….

虽然是借用facebook的信息机构,但足见抄袭之失败。虽然只是一个“关联导航(操作和设置)”的变化而已。

.

.

.

此文为抛砖引玉,我想说的内容大概只表达了1/3不到。(这里只说了布局,并未说栏目、导航划分的原则、延续性、扩展性等问题)
.

结束,简单总结:

好的信息架构设计,可以清楚的表现产品定位,可以清楚的阐述内容层次和关系,可以在使用中保持流畅,并能够让用户迅速的熟悉。

所谓“清楚的表现产品定位”:用户一看网站的信息架构,就知道这个网站是干什么的,我是否应该留在这里,我在这里能干什么应该怎么开始去用。
所谓 “清楚的阐述内容层次和关系”:用户一看网站的信息架构,就清楚知道页面上有多少内容,内容和内容之间的关系是什么,什么类型的内容在什么位置。
所谓“可以在使用中保持流畅”:让用户在使用的过程中感觉不到“跳转”和“障碍”,感觉自己在一个平和世界里畅游,非常流畅,不跳动、不卡机。
所谓“能够让用户迅速的熟悉”:用户看到你的第一个界面时,也许需要找一下他需要的内容在那里,也许会觉得这个网站陌生、有距离。但当他很自然的看到第二个、第三个界面后,应该感觉“这个网站很熟悉”,需要任何内容时都不用去“找”,很自然的就能知道什么类型的内容在什么位置。
.

PS:
我敢断言,“呈现层的信息架构和导航”必将成为未来网站产品设计中的核心工作,未来一个网站的设计80%工作都在此。其学问之深并非一两本书能说清楚,更不是一两篇blog能表达明白的。
欢迎有兴趣者深入交流。

里克:最近的项目和未来的一个项目都是sns为基础的应用,可见现在有点规模的站点sns是必备的。看了下面这个文章的确思路清晰不少。

个人观点:UI的设计是一个简-繁-简的前进路线,目前我给客户设计的站点,可以用下面的图概括

主要的想法是:同类的功能操作,放在一起,用tab实现并列,tab的current颜色,实现用户的当前定位。

这仅是个人的想法,需要一定时间来改进。毕竟uchome将在几个月后带来审美疲劳,个性风格必将在sns普及的大环境下有更多的需求。(外包的好时机哦。)所以抓紧理论的研究,能给给客户一个满意的方案。里克个人见解,欢迎朋友们讨论。

这篇文章同样值得看一下:

http://hi.baidu.com/%C2%ED%C1%BCs/blog/item/7bc98638ab83daf4b311c739.html

08

Fckeditor on Rails的问题和临时解决办法

分类:tech | 给我留言 |

在目前的项目中使用了Fckeditor On Rails插件,没想到碰到很不少问题,网上google一下,发现大家都有这样的问题,有的是这个plugin的问题,有的是fck的问题。为了方便日后对系统的管理,在此笔记一下目前碰到的诸多问题和临时的解决办法。

问题:

1、无法编辑内容,编辑时出现js问题

2、上传图片时无法准确放入指定Image文件夹路径中

3、上传文件时无法得到params[:Type]变量

4、无法使用 fckeditor 的文件上传配置

5、上传中文rar文件时,出现110错误提示

解决:

1、插件似乎没有考虑修改的问题,之前我的asp做的EZAdmin中,简单的传递内容即可,现在看来插件里并没有去处理传进来的value属性,所以在fckeditor.rb中增加了这个方法,使之能够编辑内容。

2、图片可以传递入Image文件夹内,但是结果中没有后面的文件名,具体原因似乎是版本的事情,这个暂时不去对比了,改了fckeditor_controller.rb中的返回值内容,也就是使 OnUploadCompleted的第二个参数带上了文件名,暂时得以解决。

3、问题同2类似,这时无法得到params[:Type]参数,看了下fck_image.js里,对图片上传设置了type属性为image,但是文件上传,或者叫Link上传时,没有设置这个属性。所以在fckeditor_controller.rb中,当该属性为空时,设置为File。这个修改非常危险,但是目前没有更好的方法。

4、在文件上传时,作者自定义了MIME_TYPE数组,来做校验。这个有点。。。。所以暂时将几个类型加上,解决doc,zip,rar等文件上传先。

application/msword

application/x-zip-compressed

application/octet-stream (rar的)

5、当上面都解决完,发现对中文名文件无法上传,哭吧。。。。。。

下面是我修改完的Fckeditor on Rails plugin,希望朋友们多指正问题。谢谢。

说明:plugin版本:0.5.1,Rails版本:2.1.2,两个部分的,不用安装了。

fckeditor051-for-rails212

javascripts

后记:

记得每次修改完插件内容后要重启一下服务

04

貌似php父路径问题引发的问题

问题出现了:

转移了discuz!6.1论坛到新的服务器,因为使用的火狐插件来播放flash,所以打开时发现提示:“failed to open include/common.inc.php”的提示。

分析:

之前,论坛在windows环境下,搭建的php,转来后,虽然还是windows,但是改成了apache做前端。因为php的设置肯定不会转过来,所以应该在配置或权限上出的问题。

检查:

权限上,用论坛自带的检查看了下没有问题,所以可能是apache配置或php的配置问题。

查了下百度和google,大家都在认为貌似是父路径的问题。看了下open_basedir的描述,貌似是问题的关键,可是里面提到了safe_mode设置,对比了下windows的php环境和apache的php环境配置,发现windows下的safe_mode=Off,而新的apache环境是On。

解决:

改成Off后,正常访问了。

后话:

很久没有动apache的配置了,希望这次能是一个好的开始。另:今天,已经搬进新房子了,虽然是租的,但是更多的人感觉我自己开了个工作室。貌似是吧,我可以专心工作,写博客,学习了。李猪猪小朋友不会再跑来抢电脑或者:“闪开,就坐一会”啦~!

希望未来两个月可以把工作重新走上正规。加油,加油~~!!湘北必胜~~!!

11

使用attachment_fu实现多图上传

分类:tech | 给我留言 |

请参考这篇文章

十二 30

Rails Rdoc笔记:respond_to

首先祝所有的朋友09年工作学习顺利。祝李猪猪小朋友即将到来的幼儿园生活开心。

刚才看了下respond_to这个方法,想写上一些东西。

最新做的项目,要求松耦合。因为之前2个月一直在做康盛的uchome的项目设计,对这种设计方式有点自己的想法。所以在初级设计这个代号kx2009的Rails项目时,走了些弯路。刚才看到redpond_to的文字,感觉又回到了一个正确使用Rails的方向,就是更加的REST,要web service。

REST的概念在我心里是来做资源管理的,这个资源管理要简单,所以我并不喜欢/users/1/posts/22这种资源嵌套,我更喜欢是/users/1,而他的posts就是/posts/index,/posts/22,足够。

多态。这次用到了很多多态的方法,使得设计上每个部分都很松耦合,能够复用,比如那个photos,就可以给活动,圈子,论坛去承担不同Model的图片上传,显示,管理功能。积分和信誉积分采用了同样的设计,下面的Account就是多态。(不过自动累加上一个Model的total字段稍微麻烦了点,magic有类似counter_cache的功能吗?对belongs_to那方的total字段进行自动加减?)

好了,看看Rdoc的描述。大意是:Rails是一个很好的web-service框架。

Without web-service support, an action which collects the data for displaying a list of people might look something like this:

  def index
    @people = Person.find(:all)
  end

Here‘s the same action, with web-service support baked in:

  def index
    @people = Person.find(:all)

    respond_to do |format|
      format.html
      format.xml { render :x ml => @people.to_xml }
    end
  end

What that says is, “if the client wants HTML in response to this action, just respond as we would have before, but if the client wants XML, return them the list of people in XML format.” (Rails determines the desired response format from the HTTP Accept header submitted by the client.)

Supposing you have an action that adds a new person, optionally creating their company (by name) if it does not already exist, without web-services, it might look like this:

  def create
    @company = Company.find_or_create_by_name(params[:company][:name])
    @person  = @company.people.create(params[:person])

    redirect_to(person_list_url)
  end

Here‘s the same action, with web-service support baked in:

  def create
    company  = params[:person].delete(:company)
    @company = Company.find_or_create_by_name(company[:name])
    @person  = @company.people.create(params[:person])

    respond_to do |format|
      format.html { redirect_to(person_list_url) }
      format.js
      format.xml  { render :x ml => @person.to_xml(:include => @company) }
    end
  end

If the client wants HTML, we just redirect them back to the person list. If they want Javascript (format.js), then it is an RJS request and we render the RJS template associated with this action. Lastly, if the client wants XML, we render the created person as XML, but with a twist: we also include the person‘s company in the rendered XML, so you get something like this:

  <person>
    <id>...</id>
    ...
    <company>
      <id>...</id>
      <name>...</name>
      ...
    </company>
  </person>

Note, however, the extra bit at the top of that action:

  company  = params[:person].delete(:company)
  @company = Company.find_or_create_by_name(company[:name])

This is because the incoming XML document (if a web-service request is in process) can only contain a single root-node. So, we have to rearrange things so that the request looks like this (url-encoded):

  person[name]=...&person[company][name]=...&...

And, like this (xml-encoded):

  <person>
    <name>...</name>
    <company>
      <name>...</name>
    </company>
  </person>

In other words, we make the request so that it operates on a single entity‘s person. Then, in the action, we extract the company data from the request, find or create the company, and then create the new person with the remaining data.

Note that you can define your own XML parameter parser which would allow you to describe multiple entities in a single request (i.e., by wrapping them all in a single root node), but if you just go with the flow and accept Rails’ defaults, life will be much easier.

If you need to use a MIME type which isn‘t supported by default, you can register your own handlers in environment.rb as follows.

  Mime::Type.register "image/jpg", :jpg
十二 18

开发笔记:rails分页和acts_as_taggable插件的应用[重发]

分类:tech | 给我留言 |

最近一个月在忙于开发项目,所以没有更新博客。不过开发中还是学到不少东西。

对于一个程序员,阅读是相当有帮助的,读别人的博客,读源码,读经验文章 ,即便读别人的开发代码,都是有帮助的。

本次开发的初始,就是在读别人的开发代码,然后一点点找到思路,继续在原有基础上加强功能。由于上一个版本的代码写的相当有水准,所以对自己的开发也提高不少。

本次开发的项目是一个在线视频教学系统。开发中用到了曾经写过的分页代码和一个rails插件:acts_as_taggable。

下面对这两个部分进行总结。

一、分页

下面的程序在3个项目上使用过。
models/page.rb

class Page
  attr_accessor :pages #分页连接列表,[]类型
  attr_accessor :cur #当前页
end

helpers/application_helper.rb

  def howtopage_links(pagecls=nil) #在页面输出分页连接,pagecls:分页实例
    if pagecls
      return pagecls.pages.collect {|t|
      [if t.to_s == pagecls.cur
        ""+(t.to_s)+""
      else
        ""+(t.to_s)+""
      end]
      }
    end
  end

controllers/application.rb

  def howtopage(totalcount=0, per_page=6)
    cur_page = params[:page] || 1 #直接从页面取得page变量
    x = (cur_page.to_i - 1) * per_page
    pagecount = totalcount / per_page
    if totalcount % per_page != 0
      pagecount += 1
    end
    page = Page.new
    page.pages = (1..pagecount).collect
    page.cur = params[:page] || "1"
    return page, x #page为一个包装的分页类,x为find方法的偏移量
  end

在一个notebook_controller.rb中

@notes_count = Notebook.count(:conditions=>['user_id = ?', params['user_id']])
per_page = 6 #每页记录数
@page, x = howtopage(@notes_count, per_page)
@notes = Notebook.find(:all, :conditions=>['user_id = ?', params['user_id']],
 :o rder=>"id desc", :o ffset=>x, :limit=>per_page)

在对应的页面中

< %=howtopage_links(@page)%>

这段方法有很多可以改进的地方,但是能用就好。
不过这个分页绝对算是ruby和rails入门的练习,如果想使用更专业的分页,还是推荐will_paginate插件。可以通过下面的方法安装:
script/plugin install svn://errtheblog.com/svn/plugins/will_paginate
介绍页面:http://errtheblog.com/posts/56-im-paginating-again

08年12月19日补充:

这篇博客是去年12月2日写的,一年的时间足够改变世界了。现在这个插件的地址在:http://github.com/mislav/will_paginate/tree/master

二、acts_as_taggable

虽然标题写的是acts_as_taggable,但是首先要说明,我用的是acts_as_taggable_on_steroids,可以通过下面的方法进行安装:
ruby script/plugin install

http://svn.viney.net.nz/things/rails/plugins/acts_as_taggable_on_steroids

注意不同之处:
acts_as_taggable per user tagging篇提到:also an acts_as_taggable的gem安装和plugin安装结果是不一样的. acts_as_taggable的plugin仅适用与Rails 1.1.
里克:其实上面写这句话的人是针对不同版本的,仅供参考。

所以,选择哪个tag插件,需要注意下。不同的插件使用的方法是不一样的。DDH的acts_as_taggable文档是关于那个插件的,它可以通过
svn co http://dev.rubyonrails.com/svn/rails/plugins/legacy/acts_as_taggable/ acts_as_taggable
获得。目前看也仅能从这里获得。

非常详细的适用方法请看Plugins – Acts As Taggable On Steroids

其他Rails插件

本部分被转移到 MephistoBlog使用的插件和第三方代码介绍

参考资料:
RDoc
Acts As Taggable Plugin
ActsAsTaggablePluginHowto
Plugins – Acts As Taggable On Steroids
为每个用户曾加tag功能[acts_as_taggable per user tagging]
ASCII
Ruby Lib中文站

十二 07

Rails中基于属性的动态查询

分类:tech | 给我留言 |

这是个很简单的Rails2.1.2的 find 的应用,来自Rdoc ActiveRecord::Base

一、find :first 和find :all

使用 Model.find_by_user_name ,来简写 Model.find(:first, :conditions=>["user_name=?",user_name])

使用 Model.find_all_by_user_name ,来简写 Model.find(:all, :conditions=>["user_name=?",user_name])

这里也可以使用and,比如典型的用户名和密码查询:Person.find_by_user_name_and_password(user_name, password)

find也支持带参数的查询,比如Payment.find_all_by_amount(50, :o rder => “created_on”)

二、find_or_create_by_和find_or_initialize_

find_or_create_by_:当查询的内容不存在时,创建并保存该记录

find_or_initialize_:更上面的相似,只是创建不保存该记录,需要自己再次save

这里也支持参数和代码块,如

User.find_or_create_by_name(‘Bob’, :age => 40) { |u| u.admin = true }

三、find_by_的时候,支持多属性,如

Tag.find_or_create_by_name(:name => “rails”, :creator => current_user)

以上文字来自Rails2.1.2的Rdoc文档ActiveRecord::Base

十二 02

TextMate的HTML快捷键

分类:TextMate | 给我留言 |
  • 选中文字后按 appli + I 是 em
  • 选中文字后按 appli + B 是 strong
  • 选中一行文字后按 shift +ctrl +W 是用一对标签包裹它
  • 选中一行文字后按 ctrl + apple+H 是用 h* 标签包裹它
  • 选中文字后按 ctrl + apple+B 是用块标签包裹它
  • 选中多行文字后按 shift +ctrl + apple+W 是用一组标签包裹各行
  • 选中多行文字后按 ctrl + apple+L 是用列表标签包裹各行
  • 插入一对标签 ctrl + <
  • 插入一个结尾标签 Option + apple + .
  • apple + & 进行URL编码
  • ctrl + H 帮助文件
  • shift + ctrl + V 校验W3C规范
  • option + ESC 自动补完html标签和属性
十一 30

随便写写

分类:others | 给我留言 |

刚才看了gmail里发来的一篇文章,引用一句话

应用开发者都应该思考到底哪种选择才是最符合其需要的

08年11月即将过去了

十一 29

重读AWDWR笔记

分类:tech | 给我留言 |

加载路径
标准的环境配置回自动将下列目录纳入应用程序的加载路径。

  • test/mocks/environment 由于该目录位于加载路径的第一位,在这里定义的类回自动覆盖真正的实现类,这样你就可以在测试阶段使用这些替代品。
  • app/controllers 目录及其子目录。
  • app/models 和 components 目录下所有以下划线或者小写字母开头的目录。
  • app, app/models, app/controllers, app/helps, app/services, app/apis, components, config, lib 以及 vendor 目录
  • 检查 vendor/rails 目录,如果存在就从这里加载 Rails 库。

命名约定

  • 变量名全部小写,单词之间以下划线分割。
  • 类和模块的名称没有下划线,短语中每个单词的首字母大写。
  • 表应该像变量一样,采用小写字母,并且是复数形式。
  • 文件名全部小写,以下划线分割。
  • controller 用名词,action 用动词。当你创建了一个 action 的名字是 动词_名词 这样的格式,那么有必要再创建一个新的controller了 。
  • 信息发布
  • 最新留言
  • 热评日志
我的2010,新的开始啦

稍后把团队的介绍放上,呵呵。
关于 里克
里克:本名李伟,全职SOHO开发,技术顾问
长春互联 技术总监
邮件:liwei@echangchun.net
QQ:5175486
MSN:liwei78@live.com
某高潜力SNS网站团队成员
对iphone和android的开发很感兴趣