798.space漫游指南

目录:

银河系的历史又翻开了新的一页

798.SPACE - 打造你自己的垂直社区。

引子

乔布斯说 : “活着就是为了改变世界”。

然后,他死了。

https://dn-798.qbox.me/jobsisdead.jpg?imageView2/2/w/1392

某年某月末日,看了一篇关于中国共产党从无到有,从小到大的故事。

不由得心潮澎湃。

这真是人类史上最宏大的史诗级创业故事。

一小撮与众不同的热血青年,除了共同信仰一无所有。

他们用自己的双手和生命,点燃神洲大陆的星星之火,缔造了一个史无前例的红色帝国。

虽然有波折,有挫败,有狰狞岁月,有九曲回肠。

但是毋庸质疑,最终,他们还是成功了。

时至今日,最初十几个人的小团队,已发展成为地球上最大全产业链集团。

这真是一个传奇,属于他们那代人的传奇。

忆古思今,我们这一代人,又将会缔造怎样“史诗级创业故事”呢。

而我,又能在其中做些什么呢?

左思右想,辗转反侧,我最终觉得,只有整合全人类的力量,拉开星际移民时代的大序幕。

https://dn-798.qbox.me/32146_sci_fi_spaceship.jpg?imageView2/2/w/1392

唯有这样创业故事,才能媲美他们史诗级的传奇。

但,面对这样伟大的事业,我又能干什么呢?

毕竟,我只是一个写网站小程序员,就像黑客帝国里的那个码农Nero。

左思右想,辗转反侧,我最终觉得,还是写先个网站吧,毕竟整合全人类的力量首先需要一个网站。

于是,便有了后面的故事。

“我多么希望世界上有个小岛,居住的全是智慧又善良的人们”。

—爱因斯坦

https://dn-798.qbox.me/dubaislands.JPG?imageView2/2/w/1392

访问 798.SPACE 你可以很轻松的创建自己的垂直社区。

创建项目的初衷是实现一个开源的垂直社区技术解决方案。
网站基于一个纯前端的开发框架,是开始这个计划的第一环。
这个垂直社区解决方案,还将包含手机端,IPAD端等等部分。
长期以来,我都在思索一个问题。
如何更好更有效地去组织互联网上的那些有着共同的兴趣爱好,却素不相识的人们。
让他们能够相互发现,彼此结识,碰撞出火花,再让这星星之火成燎原之势。
经过尝试、摸索、彷徨,我最终得到 - 小而美的垂直社区,这就是我想要的。
一个很小的社区,不需要太多人。大家来自五湖四海,因为一个共同的目标。
这里有成员们共同关心的话题,大家在此发现新鲜而有趣的事情。
经常有人给出一些独到的见解,有人赞同,有人反对。
但是,无论是支持者还是反对者,参与者都能理性的,有根有据的展开讨论。
君子和而不同。
没有谩骂,没有人身攻击。气氛激烈而不失友好。
成员定期投票选举出委员会来管理社区,不守规则的家伙将被禁言甚至驱逐出境。
而想加入的新人,需要完善自己的个人信息,学习社区的守则。
只有让成员们知道who you are, where you from后,才能申请发言权限。
这些个人信息只会针对那些同样通过认证的成员开放,至于那些匆匆路过的家伙,只能看到你想公开的基本概要。
成员都很珍惜在这里发言的权利。因为这里的言行,形成了在圈子里面的声誉。
社区里面藏龙卧虎,年轻人希望遇到自己的伯乐,功成名就的希望发现下一个比尔盖茨,乔布斯。
大家都有所期待。
大家都深信,在这里,会诞生很多传奇故事。
https://dn-798.qbox.me/easter-island.jpg?imageView2/2/w/1392
每个认证成员每天登录会收获少量虚拟币。
举报广告或无关言论的,在管理员确认后,也会获赠虚拟币。
虚拟币可以用来感谢文章作者。
向陌生人发送私信也需要消耗虚拟币,这样可以有效避免各种垃圾广告。
社区鼓励分享,鼓励贡献有价值的内容。
每天,每周,每个月,每个季度,每年,都会评选出那些被成员们收藏,转发,感谢最多的帖子。
而这些帖子的作者,将会被奖励社区的分红权。
除此之外,委员会的管理员们也将获得分红,作为对其辛勤劳动的感谢。
说到分红,有支出必然有收入。
圈子里的知名公司可以赞助社区,投放他们的品牌广告。
初创公司,也可以支付一些费用,来这里招兵买马。
广告通过委员会审核后会展示,竞价排名,按点击付费(支付充值购买的虚拟币)。
收入,一部分,用来发放分红。
一部分,作为社区的开发基金,用来支付给社区研发功能的程序员与设计师。
一部分,会存入社区的小金库。用来发展和组织各种线下活动。
这些收入,可以让社区形成一个良性的循环。
我们相信,在现代社会,合理运用商业与金钱的力量,能帮助一颗脆弱种子在严酷环境中存活下来,迅速地生根发芽,成长为参天大树。
让参与建设的人都有利可图,是实现梦想的最佳方式。
https://dn-798.qbox.me/stock-market.jpg?imageView2/2/w/1392
当然,还有很多更加遥远,也更加让人兴奋的遐想。
比如,成员可以在锁定期后,按一定比例减持分红权。分红权可以直接被交易,甚至被用来当作支付方式,用来交易买卖。
比如,社区在通过按照分红权投票的表决后,以民主决议的方式来增发部分分红权来融资完成一些自己的使命 – 例如,给地震的灾民捐款。
甚至,我们可以整合很多这样社区的分红权买卖交易,形成一个新兴的交易市场。
进一步,基于这个交易市场,大家可以成立自己的投资基金,可以自行去发行ETF,期权。
等等等等。
有了这样的平台,每一群志同道合的人,都能凝聚在一起,去做他们想做的事情。
也许最终有一天,有一群人,从这里相识,从这里启航。
他们聚结成一股力量,发射自己的飞船,去月球,去火星,开疆僻壤,去书写银河系历史新的篇章。
而我们今天在这里所书写的一切,则是那个银河新纪元的前传。
https://dn-798.qbox.me/291819-earth.jpg?imageView2/2/w/1392
脚踏实地,仰望星空。
谁也不知道,我们未来会走到哪儿。
谁也不知道,山顶洞的猴子,会发展出怎样的璀璨文明。
我们心怀梦想,且行且歌。
我们是编码咒语的魔法师,我们缔造空间,我们定制规则,我们创建宇宙。
现在,一切刚刚开始,未来充满着无限可能。
我们希望可以通过一系列开源项目来完善、来丰满以上的构想。
当然,毋庸置疑,这是一个非常庞大的工程。
世界上没有一蹴而就的事情。
所有的美好设想,都要通过辛勤劳动的双手来实现。
我们期待,遇见同样信仰互联网、同样不甘于每日碌碌的生活、同样相信自己是被上苍选中成就一番事业的您的加入。
联起手来,缔造属于我们的罗马。

千里之行,始于足下

https://dn-798.qbox.me/7024573-space-stars-road.jpg?imageView2/2/w/1392

798.SPACE 名字的起源

798,北京著名艺术区。

前身是当年集全东德的电子工业力量,包括技术、专家、设备生产线铸成的宏大工厂。

这是一个带有很强乌托邦情怀的盛大工程,属于那个懵懵懂懂的时代。

后来,工厂没落了,柏林墙倒了,东德也成为了历史教科书上的名词。

一群流浪艺术家驻扎了过来,把废弃的厂房改造成为了中国最著名艺术区。

https://dn-798.qbox.me/798_Art_District_Beijing-10.jpg?imageView2/2/w/1392

有一天,我注册到了 798.SPACE ( 中文含义: 798.空间 或 798.太空 )这个域名,我很喜欢这个名字。

科技与艺术,理想的老去,废土的重生,自由的创作与自我的表达,等等等等。

总而言之,我觉得它寓含了很多东西。

就是它了,798.SPACE 。

地球是人类的摇篮,但是人类绝不会永远躺在这个摇篮里

—前苏联科学家,康斯坦丁·齐奥尔科夫斯基

关于作者

生活不是贴在墙上的日程表。生活是充满激情、荆棘、光荣与梦想的伟大冒险。

程序是一种艺术创作,仿佛上帝在编码DNA,哺育着一个有着灵魂的数字生命。

—Noman

洛曼,喜欢科幻,每日YY。典型宅男。

与笔记本相依为命,不喜欢与人类接触。

是的,这是一只靠想象和自我催眠而维持存在的奇特地球生物。

https://dn-798.qbox.me/tumblr_static_lincoln_wallpapers_187.jpg?imageView2/2/w/1392

欢迎关注我的 新浪微博

‘洛曼’ 昵称的由来

雷军在小米创业初期,很低调,他说:“人若无名,便可专心练剑” 。

一旦大家知道是雷军在做,期望值就会高,他希望用户认为“就是张三、王五做的,甚至没有名字做的。”

心有戚戚。红尘多纷扰。

太多机会、太多诱惑,常让人忘记出发的初心。

隐姓埋名,专心做事。

不与人争论,不多加解释。

于是,启用 Noman(诺曼)作为化名。

但,诺曼太西化了,便改写为 “洛曼”。

加盟指南

想加入开发,请邮件 noman@798.space ,写明您的姓名,城市,擅长技能,微信或QQ 。我们会进一步联系您。

更多资源请参见文档首页的 相关链接

项目规划

2015-4-13

想法很性感,现实很骨感。
现实世界,你必须珍惜手头的每一钉点儿资源,定下一个又一个清晰而明确而且切实可行地目标,一砖一瓦的去砌起万里长城。
积跬步,然后,至千里。
所以,我们一期工程的目标很简单 - RSS阅读器 + hao123 。
我们一期工程主要着眼于搭建一个类似 weebly.com 的建站工具,当然不需要像它那么复杂。

我们需要实现的几个基本功能如下:

  1. 基本的用户注册登录
  2. 实现类似google reader的RSS订阅阅读功能
  3. 垂直社区可以默认订阅一批社区中的优秀博客,作为这个社区的资讯聚合和上网导航
  4. 桥接入微信公众号的订阅
  5. 手机浏览器的适配
  6. 完善程序的开发文档,以便于新人加入
具体拆分后的细节,包括后续工期的规划,我们整理在 开发协作工具 风车 上。
请参考 加盟指南 ,申请加入后了解详情。

配置开发环境

基础知识

如果你连SSH登录Linux都不会,不妨看一看以下教程

向服务器上传文件

运行docker镜像

配置开发环境是一个既繁琐又无趣的事情。

人生漫漫,有很多山峰等值我们去征服。但毫无疑问,配置开发环境不是其中之一。

我们希望尽可能去简化这一部分工作,所以我们用Docker对开发环境进行了打包。
执行几个小命令,就可以获得“开箱即用”(Batteries Included)的环境。
Docker是一种虚拟机中的虚拟机,它可以运行在云服务器的虚拟机中,并且本身没有性能损耗。
Docker的强大之处不是我们今天的主题。
大家请参考 Docker中文指南 自行安装Docker。

我们以基于Centos7.0为例讲讲一下部署步骤。

大家可以在 QingCloud 上开启一个全新的Centos7.0系统运行该脚本。

以下各步骤都以root身份运行。

如果不是root用户,可以先sudo su切换到root用户

sudo su

我们先更新升级系统 , 安装 docker 和 hg

yum update -y
yum install epel-release -y
yum install docker mercurial nginx tmux -y

然后启动 docker ,并添加到开机启动

service docker start
service nginx start
systemctl enable docker
systemctl enable nginx

因为众所周知的原因,国内的docker被墙了,我们需要启用一下加速服务

访问 DaoCloud的docker加速服务器 (登录后点此链接),按照网页底部的 操作手册->Centos 篇配置一下docker加速服务器。

接下来,我们pull最新798的镜像。

这个需要的时间比较漫长,我们通过nohup让其在后台一直运行,这段时间,我们可以断开ssh去睡觉了。

nohup docker pull 798space/798 &

我们可以通过tail来观察pull的进度( Ctrl+退出观察)

tail -f nohup.out

如果出现以下文字就是更新完毕:

Status: Downloaded newer image for 798/798:latest

我们可以通过 docker images 浏览看到 798 镜像。

如果出现问题可以重新pull一下,多尝试几次也许就好了。

接下来我们用hg clone下我们开发环境的home目录 ,并且启动docker

mkdir -p /home/
cd /home/
hg clone https://bitbucket.org/798space/docker_home 798
rm -rf /home/798/.hg
cd /home/798/
hg clone https://bitbucket.org/798space/798

最后启动docker

docker run -d -i -p 4242:4242 \
-p 10922:22 -p 10900:10900 -p 10901:10901 \
-p 10902:10902 -v /home:/home --name 798 \
798space/798 /etc/init.d/ssh start -D

注意,你需要配置云主机的防火墙,暴露 10922 , 4242 端口以便于我们从远程ssh访问登录docker镜像和修改html后浏览器自动刷新。

启动后,我们可以通过

docker ps

看到我们正在运行的docker

关机后重启这个docker镜像的命令是

docker start 798

然后我们就可以ssh登录进入docker

ssh 798@127.0.0.1 -p10922

127.0.0.1 也可以改为你服务器远程访问的IP

docker的798用户默认的密码是 798devos

登录进入docker镜像后,我们先修改一下文件权限

sudo chown 798:798 /home/798 -R

然后我们需要生成一下nginx的配置文件

cd ~/798/cli/docker
cp config.example.py config.py

你可以编辑config.py

vi config.py

修改域名为你自己域名。如果你想启用真实的域名,请将裸域名和泛域名都指向这台服务器

如果只是为了开发,可以保留原来的测试域名,然后在本机修改hosts文件指向此服务器。

如何配置hosts ?

windows用户用笔记本打开

C:\Windows\System32\drivers\etc\hosts

mac和linux用户请修改 /etc/hosts

在末尾添加3个域名 ,其中IP改为你自己服务器的IP,域名为你自己配置的域名,ministe.xxx通过798.space创建的垂直社区的域名,可以是任意域名

192.168.10.169 798.space
192.168.10.169 798-docs.798.space
192.168.10.169 minisite.xxx

生成配置文件

运行脚本生成配置文件

python ~/798/cli/docker/make_config.py

注意,因为我们的vim默认配置了折叠插件,命令模式下zn可以打开折叠

然后我们 ** 回到docker的母机 ** ,修改nginx的配置文件

vi /etc/nginx/nginx.conf

删除配置文件最后整个 server 那一大段(因为default server冲突)

然后软链nginx的配置文件,重启nginx服务器

cd /etc/nginx/conf.d
ln -s /home/798/798/build/nginx.conf 798.conf
service nginx restart

OK,大功告成。

我们回到docker服务器中,启动开发环境

cd ~/798
./cli/dev

你应该可以看到网页了,COOL !

如何发布到线上?

还是先编辑 /cli/docker/config.py

修改HOST域名为线上服务器的域名,修改STATIC_HOST为静态文件服务器的域名。

其中STATIC_HOST静态文件最好是与主站完全不同的根域名,这可以避免http请求头中总是包含cookie的开销。

我们建议使用 七牛云存储 的 空间设置 -> 镜像存储,直接镜像主域名,做它的CDN的反向代理,以加速访问。

同时还建议在启用其 空间设置 -> 域名设置 中的 HTTPS, 然后就把这个支持https的qbox.me的域名作为STATIC_HOSTd的域名即可。

完成以上步骤后,运行 make_config.py 生成配置文件。重启母机的nginx。

然后运行 ./cli/publish 更新发布的html即可。

798.space 目录导读

我们先来看一下项目的目录结构, 常用的目录和文件如下

首先是最重要的启动开发环境脚本,我们在这个脚本中启动了FIS,PLIM,CoffeeScript,Scss的自动编译进程

cli
dev

然后是rpc目录 。

rpc
root.json.py

写静态页面时,可以先与后端约定好交互数据数据结构。

在后端接口完成之前,在此按约定好的结构定义一些假的json数据,以实现并行开发 。

rpc 目前中是存放的是python脚本,以 .json.py 结尾,文件内容类似

class FAKE:
    index = [
        "昵称",
        32, #未读消息数
        ...
    ]

启动开发环境后,当你修改.json.py文件是,会自动编译生成对应的json数据的静态文件到build目录下(生成的文件于.json.py的文件名,以及FAKE中的函数名相对应)。

同时build目录也是FIS发布项目时候生成静态文件的部署目录。

我们可以通过访问诸如 http://你的域名/rpc/root.index 来看到生成的内容。

这样我们就可以在javascript中很方便使用 /rpc/root.index 这个地址来获取数据(这与后端真正实现接口后的数据获取路径是一致的,区别只是域名不同)。

  • build
    • rpc
      • root.index 由root.json.py生成

leancloud云代码,该目录内容相当于用js写的后端代码

  • leancloud

    • cloud 后台由coffee编译的js代码
    • coffee 后台coffee代码
    • config 配置文件目录
    • public
    • deploy 将本地源码推送到 LeanCloud 云代码平台运行 ./deploy

其它目录

  • pure

    • fis-conf.js fis配置文件
    • css css通常由scss生成,一般不会直接修改
    • html html通常由plim生成,一般不会直接修改
    • modules 由coffee生成的js文件存放目录,一般不会直接修改
    • lib 库文件存放目录,库文件例如semantic等,包含css和js
  • plim plim文件存放目录

  • coffee coffee文件存放目录

  • scss scss文件存放目录

  • docs 文档

  • config.rb compass配置文件

  • replace_line.py 用于替换文件中字符串的脚本,FROM_STRING是原来的字符串,TO_STRING是替换后的字符串,修改完之后F12运行一下完成文件中的替换

coffee目录中的plim

在我们写网站的时候,经常会有写弹出框的需求.这时通常我们会在coffee文件中引入plim文件,为了解决查找麻烦的问题,我们将会用到的plim文件写在coffee的目录下,这样当引用plim文件时将会更加方便。

我们用到了下列技术

FIS

798.space 使用基于 FIS 的 PURE 作为我们纯前端开发框架的基础框架。

我们运行 ./cli/dev 脚本启动开发环境的时候,就启动了pure (PURE是FIS的一个定制版)。

FIS是专为解决前端开发中自动化工具、性能优化、模块化框架、开发规范、代码部署、开发流程等问题的工具框架。

它提供了很多实用的特性来提供我们的开发效率。比如,修改保存之后html或脚本文件之后,浏览器会自动刷新网页。

详情参阅 * FIS前端工具框架

我们特别强调几点。

FIS可以通过pack来进行资源文件的合并,比如我们需要将DEMO中的公共库文件打包在一起,可以修改fis-conf.js配置,加入pack配置:

fis.config.set('pack', {
    'pkg/lib.js': [
            '/lib/mod.js',
            '/modules/underscore/**.js',
            '/modules/backbone/**.js',
            '/modules/jquery/**.js',
            '/modules/vendor/**.js',
            '/modules/common/**.js'
    ]
});

FIS可以在javascript脚本中对于声明其关于javascript和css的依赖关系,输出时,会自动在生产的HTML静态文件中引用相关的样式和脚本。

也可以在javascript通过 __inline 引用html文件, 这对于编写单页面全动态的网站(类似Gmail这种)帮助巨大。

详情参见 三种语言能力

leancloud

LeanCloud 提供一站式后端云服务,从数据存储、实时聊天、消息推送到移动统计,涵盖应用开发的多方面后端需求。

以后再也不用租服务器,也不用写后端代码了。

js数据存储开发相关链接 :

leancloud云代码命令行工具

leancloud云代码命令行工具是用来管理、部署云代码项目的命令行工具,称之为avoscloud-code项目。通过它,你可以部署、发布、回滚云代码,并且可以对同一个云代码项目做多应用管理,还可以查看云代码日志,批量上传文件到LeanCloud平台上等

安装avoscloud命令行工具:

sudo cnpm install -g avoscloud-code

在你开发和本地测试云代码项目通过后,你可以直接将本地源码推送到 LeanCloud 云代码平台运行,只要执行 deploy 命令:

./deploy

PLIM模板

plim 是 MAKO模板 的一种简便写法。

所以,你需要先了解什么是Mako。

请先仔细阅读相关文档

用plim模板写html有一些好处。

  • 比写html更加简单,代码量更加少
  • 再也不用担心html标签的闭合问题
  • 简单的缩进表示嵌套让代码看起来更整洁

通常的页面,我们通过继承简化代码结构,比如继承基模板(基模板是所有页面都要继承的模板)

-inherit /_base/page.plim

基模板将html分成head,body,script 三部分(mako中的block),三部可以分别被重载.

比如,继承基模板的head(head部分一般引用css文件):

-block head
    = parent.head()
    <!-- @require /css/index.css -->

如果是直接继承/_base/page.plim,parent.head可以省略,下同。

继承基模板的script(一般位于模板结尾,引用js文件):

-block script
    = parent.script()
    scrpit
        require('798')

其他部分将自动插入基模板的next.body()部分

SASS

Sass是一种CSS的开发工具,提供了许多便利的写法,大大节省了设计者的时间,使得CSS的开发,变得简单和可维护。

Sass的使用方法使你的css的扩展和维护工作变的更加容易

相关链接 :

通常情况下SCSS分成三个等级来引用:全局级,模块级,页面级

全局级和模块级的SCSS文件名用下划线开头,如_base.scss,_head.scss等

其中head部分,sidebar部分一般作为一个模块被引用。

当页面级的SCSS需要被其他SCSS引用时,请用@import

所有的SCSS导入文件都可以忽略后缀名.scss。

不被直接引用的css样式组件,我们以 _ 作为文件名的开头,如 _mixin.scss 。

这种文件在导入的时候可以不写下划线,可写成

@import "mixin"。

Compass

简单说,Compass是Sass的工具库(toolkit)。

Sass本身只是一个编译器,Compass在它的基础上,封装了一系列有用的模块和模板,补充Sass的功能。它们之间的关系,有点像Javascript和jQuery、Ruby和Rails、python和Django的关系。

我们使用compass来编译我们的scss脚本。

相关链接 :

Coffeescript

CoffeeScript,是一种更好的JavaScript。

使用Coffeescript可以避免书写JavaScript时候遇到的许多问题,同时也能简化我们的代码书写。

比如,忘记用var定义变量,导致局部变量成为全局变量,进而导致名字空间的污染。

比如,可以用 for ... in , 而不用 for(var i=0;i<arr.length;++i) 如此麻烦的写法。

我们在项目中禁止书写原生JavaScript,所有的脚本都请用Coffeescript编写。

如果你在网上找到一些JavaScript脚本,希望copy&paste加以使用,请先通过 js2.coffee 将其转换。

相关链接 :

Semantic UI

Semantic UI—完全语义化的前端界面开发框架

跟 Bootstrap 和 Foundation 比起来,还是有些不同的,在功能特性上、布局设计上、用户体验上均存在很多差异。

Semantic UI 比Bootstrap更语义化,使用了更容易理解的标签名称:导航的是nav,主要内容的是main,class名也很明确,而且不像Bootstrap需要套很多层。Bootstrap很通用,兼容性很好,甚至能兼容低版本的IE,Semantic-UI则更Geek,有不少CSS3的特性,比如Shape和Reveal就很有趣。从界面设计风格来说,Semantic比Bootstrap(2)更扁平化.

我们在基模板中引用Semantic UI,编写代码时,注意复用Semantic UI中已有的功能组件

相关链接 :

avalon

avalon是一个简单易用迷你的MVVM框架,为解决同一业务逻辑存在各种视图呈现而开发出来的。

MVVM将所有前端代码彻底分成两部分,视图的处理通过绑定实现, 业务逻辑则集中在一个个叫VM的对象中处理。我们只要操作VM的数据,它就自然而然地同步到视图。

相关链接 :

View

View是对avalon中avalon.define的改写

定义一个View可以写成:

View(id,o,view)

改写文件coffee/lib/avalon_ext.coffee

avalon.nextTick

avalon.nextTick类似于Node.js里的process.nextTick()

相关链接 :

开发环境导读

在正式开始开发之前,我们不妨回顾一下我们在docker开发环境中的Linux命令,以及一些我们自定义的小工具。

  • TAB 键自动补全
  • ls 列出目录
  • ls -al 使用格式化列出隐藏文件
  • pwd 显示当前目录
  • cd <dir> 切换到 dir 目录
  • cd 切换到 home 目录
  • cd .. 切换到父目录
  • mkdir <dir> 创建目录
  • touch <file> 创建文件
  • cat <file> 显示文件内容
  • less <file> 逐页显示文件内容
  • more <file>
  • head <file> 显示文件头 10 行
  • tail <file> 显示文件后 10 行
  • tail -f <file> 开始监控文件内容改动
  • xtail /var/log/nginx/* 批量监控nginx日志
  • ctrl+c 结束程序
  • ctrl+z 停止当前程序,可使用 fg 恢复
  • ctrl+w 删除当前行中文字
  • ctrl+u 删除整行文字
  • ctrl+a/e 将光标移动至行首/尾
  • ctrl+r 搜索最近使用的命令
  • bg 列出已停止或者后台程序
  • fg 将最近作业带到前台
  • locate <file> 查找某个文件所在位置
  • top 参看当前运行的进程

删除vim非正常关闭的临时文件 deltmp

当vim非正常关闭或文件被同时打开两次时的时候,会有临时文件

如何当一个文件上次打开时被非正常关掉.再打开时,按R恢复文件,然后:wq保存退出。

最后用deltmp命令删除临时文件

tree 以树形显示当前目录结构

  • tree 以树形结构显示当前目录下所有文件和目录
  • tree -d 仅显示目录
  • tree -L <num> 限制目录的最大深度

ag 搜索

  • ag <something> 在目录所有文件中寻找 something
  • ag <something> -py 在所有 Python 文件中搜索 something (CSS,JS同理)

autojump 一键直达目录

autojump

在命令行中切换目录是最常用的操作,不过很少有比一遍又一遍重复“cd ls cd ls cd ls ……”更令人沮丧的事情了。如果你不是百分百确定你想要进入的下一个目录的名字,那么你不得不使用ls来确认,然后使用cd来进入你想要进的那一个。所幸的是,现在大量的终端和shell语言提供了强大的自动补全功能来处理该问题。但是,你仍然需要一直疯狂地敲击TAB键来干这事。如果你和我一样懒惰,你一定会对autojump感到惊喜。

autojump是一个命令行工具,它允许你可以直接跳转到你喜爱的目录,而不用管你现在身在何处。

  • j <dir> 根据最近工作目录记录跳转到最合适的位置。

如果你不确认哪里是不是你要跳转的地方,敲击TAB键就会列出完整路径。

还是同样的例子,输入

autojump d

然后敲击tab键,将会返回/root/home/doc或者/root/home/ddl 。

如果你突然想要把当前目录变成你的最爱和使用最频繁的文件夹,你可以在该目录通过命令的参数 i 来手工增加它的权重

j -i [权重]

这将使得该目录更可能被选择跳转。相反的例子是在该目录使用参数 d 来减少权重

j -d [权重]

42qucc

42qucc 是在线的随手贴,可以随意地自定义网址来自己记录或与朋友分享文字。

保存

42qu.cc 提供在线分享文本文件的功能。在命令行中输入

42qucc < 某个文件名

即可获得诸如 http://42qu.cc/6nhxuqpg 格式的网址,打开该链接即可看到分享的内容。

我们也可以自定义生成的网址

42qucc xxx < 某个文件名

读取

将链接中的内容保存在文件中

42qucc http://42qu.cc/6nhxuqpg > 文件名

Linux的回收站 - trash-cli

凡事只要有可能出错,那就一定会出错。

—墨菲定律

啊,删错文件了!!!

好吧,这已然是第N+1次了。

“此情可待成追忆,只是当时已枉然”。

我一直认为Linux最不人性化的设计就是没有回收站。

长期以来,rm命令就像一颗隐形的地雷,不知道什么时候就被踩到,壮烈牺牲。

“出师未捷身先死,长使英雄泪满襟”。

幸好,我们还有trash-cli,Linux的回收站。

与其等不小心误删除后去追悔莫已,去苦心钻研如何恢复文件,不如一开始就防患于未然。

故,兵书曰,善战者无赫赫之功

想使用trash-cli,首先安装

sudo pip install trash-cli

然后修改全局的bashrc

alias rm="trash-put"
trash-empty 99

这样删除文件就会进入回收站而不被直接删除了。同时清空删除超过99天的文件。

通常全局bashrc的路径是

/etc/profile

此外,我们可以在root用户的crontab中配置

trash-empty 99

每天晚上3点执行,自动清空删除超过99天的文件

trash-cli 的命令如下

  • trash-empty 清空回收站
  • trash-list 查看被删除的文件
  • restore-trash 恢复被删除的文件
  • trash-rm 从回收站中删除单个文件

更多内容请浏览trash-cli 官方主页

本工具在798的docker镜像已中经内置并默认启用

如何贡献代码

如果你想给798项目贡献代码,请遵循以下步骤

然后修改一下hg配置文件

vi ~/.hgrc

修改

username = undefined <undefined@798.com>

修改为你自己的昵称和邮箱

然后运行

ssh-keygen

一路回车生成你自己的公私钥, 然后

cat ~/.ssh/id_rsa.pub

然后注册 bitbucket , 将这个公钥贴到 右上角头像 > Manage account -> 左侧栏 SSH keys -> Add Keys ,Label可以留空,内容为上面cat显示的公钥。

  1. 注册 bitbucket 账户
  2. 访问 https://bitbucket.org/798/798/fork fork 项目 798
  3. 修改 hgrc
  4. 运行ssh-keygen生成私钥,并配置bitbucket的ssh私钥
  5. 提交pull-request

常用js函数

NProgress.js

显示进度条:

NProgress.start()

设定一个百分比:

NProgress.set(0.4)

增加一点进度:

NProgress.inc()

完成进度:

NProgress.done()

store.js

store.js 是一个兼容所有浏览器的 LocalStorage 包装器,不需要借助 Cookie 或者 Flash。store.js 会根据浏览器自动选择使用 localStorage、globalStorage 或者 userData 来实现本地存储功能。

相关链接 :

__uri

js中,可以使用编译函数__uri(path)来定位资源,fis分析js文件或html中的script标签内内容时会替换该函数所指向文件的线上url路径。 如,源码:

js = __uri('demo.js')

编译后:

js = '/demo_33c5143.js'

798.coffee

解释一下该文件的代码

其中的:

clientWidth = $(window).width()
if clientWidth < 414
    scale = (clientWidth/414)
    document.write("<style>body{zoom:#{scale}}</style>")

用于做对手机的适配

其中的:

if current_user
    current_user.fetch()
    src = __uri("/modules/798/login1.js")
else
    src = __uri("/modules/798/login0.js")

document.write("""<script src="#{src}"></script><script>require("798/login#{!!current_user-0}")</script>""")

当用户登录时,引用login1.js

当用户未登录时,引用login0.js

require.js的用法

引入require.js的原因:当我们要引用多个js文件时,首先,加载的时候,浏览器会停止网页渲染,加载文件越多,网页失去响应的时间就会越长;其次,由于js文件之间存在依赖关系,因此必须严格保证加载顺序,依赖性最大的模块一定要放到最后加载,当依赖关系很复杂的时候,代码的编写和维护都会变得困难。而require.js的异步加载方式和依赖加载方式能够很好地解决这一问题。

在coffee中引入依赖模块的写法:

require_async(
   ["jquery","wow"]
    ->
       ...
)

其中require_async接收两个参数,一个是数组,数组元素即是依赖模块文件(省略.js);另一个是回调函数,当前面指定的模块都加载成功后,它将被调用。

有关模块化编程的相关链接 :

出错提示工具$.error_tip()

工具所在文件coffee/lib/jquery_ext.coffee

$.error_tip()接收两个参数,分别是出错提示对象elem,focus出错时是否选中文本并focus第一个出错位置。

引入js工具$$

工具所在文件coffee/lib/async.coffee

为了方便调用注册,登录等模块,我们经常将其写成js,并用$$工具引入。

$$引入的js有其固定的写法,当coffee文件的位置为 coffee/SSO/auth.coffee时,该文件的开头写成:

$.SSO.auth = {
    new : ->
        ...
    login : ->
        ...
        }

可以用$$(‘SSO/auth.new’)和$$(‘SSO/auth.login’)调用

fail

一般向LeanCloud发送请求时,返回错误信息用error接收,但是我们补充用fail改写error接收。

具体查看coffee/lib/av_ext.coffee文件

基础知识:

avalon - 前端

avalon是很好用的双向绑定框架。

为了方便使用,我们做了一些小修改。

首先,ms-controller 改名叫做 ms-view ,我们觉得 controller 这个单词太长了。

其次,事件的回调函数中 return false 可以阻止事件继续传播 , 这可以jquery的使用习惯保持一致。

然后,为了方便不同的 view (controller) 之间相互调用,我们引入了一个全局变量 V 指向 avalon.vmodels 。

最后,我们因为已经使用了百度fis提供的mod作为require加载器,所以我们使用的avalon的shim版本。

发布子站到GIT CAFE

参见 如何创建Page

通过加速乐备案(或者免备案)

没有备案的话是可以使用香港节点的,备案用户可以使用国内节点。

http://www.jiasule.com/icp/

常用工具 :

vim

vim 快速入门

vim 简介

在这个蔚蓝色的星球上,流传着两大神器的传说:Emacs是神的编辑器,而Vim是编辑器之神。

VIM , 全称 Vi Improved , Vi的增强版 。

Vi 在 1976 年发布,奉行 Unix 传统的“Do one thing and do it well”哲学,每个程序只做一件事但做到最好,通过程序之间的配合得到强大的功能。

Emacs则奉行“Everything at reach”设计哲学,通过强大的扩展性,达到在一个软件里做所有的事。Emacs可以用来编辑文档、时间管理、浏览图片、阅读pdf、听音乐、写程序、运行程序、调试程序、接受发送邮件、看新闻组、玩游戏、管理系统、Telnet/FTP、版本控制、写LaTex…被称为“伪装成编辑器的操作系统”。

江湖中有一句话: “ 世界上的程序员分三种,一种使用Emacs,一种使用Vim,剩余的是其它” 。

开始入门

如果你对VIM完全没有概念,不妨先阅读一下

基本概念

Vim 有两种模式——Normal 模式和 Insert 模,所有命令都是在 Normal 模式下执行。启动 Vim 后,默认进入 Normal 模式, 可以按 i 键进入 Insert 模式,或者 s 删除当前字符并进入 Insert 模式,退出 Insert 模式进入 Normal 按 ESC

下面的教程中约定 + 表示同时按其左右的按键,小写字母(如 i)表示按该字母一次,大写字母(如 G)表示同时按 shift+g。

基本用法

  • i insert 输入
  • v 行选中
  • ctrl+v 列选中
  • G 至文末
  • gg 至文首
  • :q 未修改退出
  • :q! 强制不保存退出
  • :x / :wq 保存并退出
  • J 合并多行
  • d 删除当前所选
  • dd 删除多行并存在剪贴板中(剪切)
  • y 复制当前所选
  • yy 复制整行
  • p 粘贴
  • u 撤销操作
  • w 光标移动到下一个单词处
  • b 光标移动到上一个单词处
  • ^ 光标移动到行首
  • $ 光标移动到行尾
  • kjhl 或者上下左右键移动光标
  • shift+上下键 翻页
  • shift+左右 光标乙至上/下一个单词(以空格/标点区分单词)词首
  • u 撤销上一步操作
  • zo/zn/zc 折叠/展开代码块
  • :vsp 新建工作区
  • ctrl+w 松手后再按 方向键 切换工作区
  • :MR 选择最近打开的文件(需安装插件)
  • F12 运行当前文件
  • # 搜索光标处短语
  • :set paste 进入粘贴模式
  • :%s/target/something/g 替换全部 target 字段
  • :s/target/something/g 替换选中区域 target 字段

组合用法

注释大段文字

  • 光标移至行首
  • I 进入插入模式
  • 输入注释符号
  • 双击 ESC

vim名词解释

模式 ~~~

vim有5中基本模式,分别是

  • Normal Mode 也就是最一般的普通模式,默认进入vim之后,处于这种模式。
  • Visual Mode 一般译作可视模式,在这种模式下选定一些字符、行、多列。 在普通模式下,可以按v进入。
  • Insert Mode 插入模式,其实就是指处在编辑输入的状态。普通模式下,可以按i进入。
  • Select Mode 在gvim下常用的模式,可以叫作选择模式吧。用鼠标拖选区域的时候,就进入了选择模式。 和可视模式不同的是,在这个模式下,选择完了高亮区域后,敲任何按键就直接输入并替换选择的文本了。 和windows下的编辑器选定编辑的效果一致。普通模式下,可以按gh进入。 ps:这种模式好无用啊
  • Command-Line/Ex Mode 就叫命令行模式和Ex模式吧。两者略有不同,普通模式下按冒号(:)进入Command-Line模式,可以输入各种命令, 使用vim的各种强大功能。普通模式下按Q进入Ex模式,其实就是多行的Command-Line模式。 ps:经常使用EX模式的都是神阶vimer

注:本文中所说的快捷键若无特殊说明则是Normal Mode下的模式

Windows/窗口

vim可以将窗口分成好多个独立的块来显示不同的文件,我们把这些块叫做窗口。当然你可以选择竖着分或者横着分,横着分的叫做split window,竖着分的叫做vsplit window。

Tab/标签页

就像chrome的标签页一样。

Buffer/缓冲区

缓冲区(Buffer)是一块内存区域,里面存储着正在编辑的文件。如果没有把缓冲区里的文件存盘,那么原始文件不会被更改。 可以通过:ls或:buffer命令查看缓冲区


插件

Vundle插件管理器

Vundle的功能是用于安装和管理其他插件,它能够直接从github上下载并自动安装置顶的插件。其本身也托管在github上,我们可以使用下面的命令快捷的安装它。

git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim

然后只需要在.vimrc文件中写入要安装的插件然后在vim中运行Vundle的插件安装命令就可以自动下载安装指定的插件了。 更详细的使用方法可参考Vundle的文档

MRU最近打开的文件

MRU的功能是从底部弹出一个最近打开的插件列表,其默认启动命令是:MRU,为了使用方便我将其设为mr。

nerdtree文件目录树

nerdtree是一个用于显示目录树的工具默认启动方式是:NERDtree,好难打的样子,所以我把它设成了nt。

关于这个插件有一个非常实用的设置是它可以忽略指定类型的文件,例如我们希望将所有的pyc或者其他没用的文件从目录树中过滤调的时候就可以使用它的这个功能,就像这样

let NERDTreeIgnore=['\.pyc$', '\~$']

它在github上的readme比较渣,没有介绍什么具体的用法和功能,我这里列出一些我用过的,还有一些大家可以通过:help Nerdtree查看。

  • o.......打开文件并将焦点移动到打开的文件或展开当前文件夹
  • Enter...跟o一样
  • go......跟o一样,但将焦点留在NerdTree
  • t.......在新tab中打开文件
  • T.......同t,但保留焦点
  • i.......在一个新的 split window中打开文件
  • gi......同i,保留焦点
  • s.......在新的 vsplit 窗口打开文件
  • gs......同s保留焦点
  • O.......递归打开当前文件夹
  • x.......关闭当前文件夹的父文件夹
  • X.......递归关闭当前文件夹
  • P.......跳到根目录
  • p.......跳到当前目录的父目录
  • q.......退出NerdTree
CtrlP模糊搜索文件

CtrlP是一个用于模糊搜索文件的插件,其文档比较健全看看它的readme就能学会其用法,而且其默认启动快捷键就是Ctrl+p。

其跟NerdTree一样,也可以在split(Ctrl+s)和vsplit(Ctrl+v)窗口以及新tab(Ctrl+t)打开文件。

还有一个使用的设置就是忽略指定类型文件,像这样

let g:ctrlp_custom_ignore = {
    \'file' : '\v\.(pyc|html\.py)$',
    \}
ag和CtrlSF

ag是一个linux下非常好用的代码搜索工具(代码在github上需要手动安装),它可以快速搜索你的代码内容。vim的ag插件允许我们在vim中使用ag命令搜索代码,CtrlSF插件跟ag插件的不同在于前者可以显示代码的上下文,显然是CtrlSF更为强大。

CtrlSF的默认命令就是:CtrlSF,然后输入要搜索的字符再敲回车。好难打,好难用,所以我设置了下面的快捷键:

nmap <C-S>f :CtrlSF
nmap <C-S>o :CtrlSFOpen<CR>
nmap ss :CtrlSF <C-R><C-W><CR>
vnoremap ss y:CtrlSF <C-R>"<CR>
  • Ctrl+s+f................适用于normal模式,就跟:CtrlSF一样
  • Ctrl+s+o................适用于normal模式,打开搜索结果的窗口
  • ss......................适用于normal模式,搜索当前光标所在的单词
  • ss......................适用于visual模式,搜索当前选中的文字
tpope/vim-commentary 批量注释

这货可以批量注释代码,就像eclipse的Ctrl+j一样。当然你以可以使用选中再批量插入的方式开实现批量注释,但你需要按5个键(Ctrl,v,Shift,I,Est)而commentry只需三个键就可以了。

首先,我们设个快捷键以及将python的注释符设为#

vnoremap <Backspace> :Commentary <CR>
autocmd FileType python set commentstring=#\ %s

这样在可视模式选中要注释的内容后可以按退格键批量注释,再次选中按退格键就解除注释。

Syntastic语法检查

该插件的功能是检查和标记语法错误及不规范的问题,在我们的项目下

supertab,补全插件
vim-coffee-script,CoffeeScript语法高亮
mako.vim,mako语法高亮
vim-mercenary 支持hg blame和diff
vim-colors-solarized 漂亮的颜色主题
luochen1990/rainbow 彩虹括号,匹配的括号显示为同一颜色
godlygeek/tabular 自动对齐
hynek/vim-python-pep8-indent python自动缩进
indentLine垂直缩进对齐线
MatchTag高亮显示匹配的html标签

移动

  1. :[n] 移动光标当第n行。
  2. H,M,L 分别移动光标到当前屏幕首行,中间行和尾行。
  3. Ctrl+f和Ctrl+b向下和向上翻页,相当于pageup和pagedown。
  4. h,j,k,l向左下上右移动一个字符。
  5. f和F加字符,将光标移动到下一个或上一个该字符的位置,例如fa会将光标移动到下一个a的位置。
  6. m设定标记,`跳转到指定标记。例如可以用ma在某行设定标记,再使用`a跳转到改行。
  7. shift+左右 光标移至上/下一个单词(以空格/标点区分单词)词首。
  8. w 光标移动到下一个单词处
  9. b 光标移动到上一个单词处
  10. ^ 光标移动到行首
  11. $ 光标移动到行尾

插入

  1. a和i分别在当前字符前和后插入。
  2. A和I分别在当前行尾和行首插入。
  3. 批量插入。首先在可视模式下选中要插入的行,然后按I可在选中处之前批量插入字符

复制、粘贴、替换和删除

  1. r可以替换当前字符。
  2. yy和dd可以分别复制和剪切当前行。
  3. y2y和d2d可以分别复制和剪切当前行开始的2行。
  4. :3,8y和:3,8d可以分别复制和剪切第3到第8行。
  5. yw和dw可以分别复制和剪切光标所在的单词。
  6. d(可视模式) 删除当前所选
  7. dd 删除多行并存在剪贴板中(剪切)
  8. y 复制当前所选
  9. p 粘贴

分屏相关

  1. :vsp和:sp分别竖着和横着分割当前窗口。
  2. Ctrl + v和Ctrl + s也可以竖向和横向分屏。
  3. Ctrl + w + 箭头键(hjkl)在不同窗口键移动。
  4. Ctrl + = 将所有的窗口大小调成相同大。

查找和替换

  1. / + 要搜索的内容搜索。
  2. n和N跳到下一个或上一个搜索结果。
  3. # 搜索当前光标所在的单词。

折叠代码

  1. zc,zC,zo,zO折叠或打开折叠当前行的代码,其中大写Z和O表示折叠或打开折叠所有层。
  2. zn,zm折叠或打开折叠当前文件的所有代码。

定制的快捷键

  • F12..................运行python文件或使用zencode补全html
  • F11..................格式化代码
  • F5,F6,F7,F8..........调整窗口大小
  • Ctrl+s+f.............使用ag搜索
  • Ctrl+s+o.............打开ag搜索结果
  • ss...................使用ag搜索光标所在的单词
  • ss(可视模式).........搜索选中的单词
  • Backspace(可视模式)..注释/解除注释代码
  • nt...................打开NerdTree
  • mr...................打开MRU
  • tl...................打开taglist
  • bn...................打开下一个buffer
  • bp...................打开上一个buffer

其他

  1. u和CTRL+r分别是undo和redo的功能。
  2. :set nu和:set nonu分别为显示和不显示行号。
  3. Shift + < 或 >分表表示向左或向右缩进一层,也可以选中后批量缩进。
  4. n + Shift + < 或 >可批量缩进n层。
  • i insert 输入
  • v 行选中
  • ctrl+v 列选中
  • :q 未修改退出
  • :q! 强制不保存退出
  • :x / :wq 保存并退出
  • J 合并多行
  • shift+上下键 翻页
  • :set paste 进入粘贴模式
  • :%s/target/something/g 替换全部 target 字段

非正常退出vim后恢复文件 & deltmp

实例教程 :

实例讲解

下面是coffee/SSO/auth.coffee的部分代码:

modal = (html, color, id, callback)->
    $.modal(
        html
        {
            dimmerClassName : 'form '+color
        }
        id
        callback
    )
$.SSO.auth = {
    password_set_mail: (mail)->
        self = modal(
            __inline("/html/coffee/SSO/password_set_mail.html")
            "purple"
            "ssoAuthPasswordSetMail"
            (elem)->
                error_tip = $.error_tip(elem)
                m = {
                    o:{
                        mail
                    }
                    submit : ->

                        error={}

                        if m.o.mail.indexOf("@") <= 0
                            error.mail = "请输入有效的邮箱地址"

                        if not error_tip.set error
                            AV.User.requestPasswordReset( m.o.mail, {
                                success: ->
                                    href="http://"+m.o.mail.split("@")[1]
                                    $.modal_alert """<h1><p><span style="padding-right:30px;">重置密码邮件已发送。</span><a target="_blank" href="#{href}">点此查看</a></p><p>没有收到?<a class="resend" style="padding-left:30px;cursor:wait;" href="javascript:void(0)">点此重新发送<span class="timer"></span></a></p></h1>""", {
                                                onApprove:->
                                                    location.href="/"
                                                onShow:->
                                                    resend = $(@).find(".resend")
                                                    timer = resend.find(".timer")
                                                    run = ->
                                                        c = 60
                                                        counter =->
                                                            if c == 0
                                                                clock = ""
                                                                resend.click send
                                                                resend.css {cursor:"pointer",color:""}
                                                            else
                                                                c-=1
                                                                clock = "(#{c})"
                                                                setTimeout(counter,1000)
                                                            timer.text clock
                                                        counter()
                                                        resend.css {color:'#444'}
                                                    send = ->
                                                        AV.User.requestPasswordReset(m.o.mail, {})
                                                        resend.unbind 'click'
                                                        run()

                                                    run()

                                            }
                                error: (_error) ->
                                    if _error.code == 205
                                        error.mail = "该账号不存在"
                                    else
                                        error.mail = _error.message
                                    error_tip.set error
                            })
                        false
                }
        )
}

其中$.SSO.auth.password_set_mail是实现发送重置密码邮件的方法

该方法中调用了modal()函数,modal()函数在文件的开始定义,用于显示弹出窗。该调用分别传了__inline(“/html/coffee/SSO/password_set_mail.html”),”purple”,”ssoAuthPasswordSetMail”和一个回调函数这四个参数。第一个参数是个内嵌的html,用了fis的写法;第二个参数是一个class名的一部分;第三个参数是View的id名;最后的回调函数是该方法的主体。m对象作为avalon的View方法的第二个参数传进。m中包括对象o和方法submit,对象o即为View中的变量,用于avalon变量绑定,submit()作为提交函数定义。submit()中的AV.user.requestPasswordReset函数用于LeanCloud向用户的Email地址发送重置密码邮件,它接收一个email地址字符串,一个包含成功和错误回调函数的对象。发送成功后,success方法执行,我们用$.modal_alert来提示发送成功,弹出框里我们可以点击链接查看邮箱网站,也可以点击链接重新发送重置密码邮件。重发邮件每隔1分钟可点击一次,该部分效果写在onshow方法里。如果发送邮件失败,error方法执行,接收参数_error(加下划线用于区分error,error用于定义错误提示对象,在一定的情况下显示一定的错误信息。),然后根据错误提示码显示出错提示信息,其中$.error_tip()用于提示出错。

附录:

文档写法

开发服务器上,文档的默认路径是:

~/798/docs/source

写完之后,在:

~/798/docs/source

运行:

make html

可以生成html, 访问 798-docs.798.space 可以浏览你新生成的文档

手工配置开发环境

生成配置文件

首先创建主配置文件:

cp 798/cli/docker/config.example.py 798/cli/docker/config.py

修改 config.py 中的 HOST , 然后生成nginx和fis(pure)的配置文件

/798/cli/docker $ python make_config.py

这个脚本会输出生成的配置文件的路径。

然后打开nginx的配置文件:

sudo vi /etc/nginx/nginx.conf

在http段的靠前位置加入:

include /home/web/798/build/nginx.conf

其中,include后面的路径应为你实际生成nginx配置文件的路径。

然后重启nginx

sudo /etc/init.d/nginx restart

程序员知识点考评大纲

常用工具

Linux

基础篇
  • locate
  • ag
  • xtail

Gentoo

  • emerge –autounmask-write 然后 etc-update 然后 -3
  • emerge =xxx-版本号
自定义的命令
  • dirreplace
  • replace_line.py
  • deltmp
高级篇
  • dstat
  • dirreplace
  • replace_line.py

tmux

  • Ctrl+B

xshell

vim

  • F12
  • MR
  • 批量注释
  • = 排版
  • vsp
  • 替换
  • 替换选中部分

版本控制

  • hg
    • blame
    • log + -l
    • revert -r
    • fetch
    • st
    • ignore
    • diff
    • grep
    • bisect 定位BUG出现的版本
    • serve
    • resolve + -l + -m

自定义小工具 :

./hg_close_branch ./hg_update_branch

前端

HTML

  • label for属性

    绑定表单元素id,实现点击label选中相应radio或checkbox

  • 链接都必须写上href属性, 空链接请写成:

    <a href="javascript:void(0)"></a>
    
  • 反复出现的按钮图标用 a标签 配合 css设置背景图 来实现,不要反复的写img标签(减少代码的冗余度)

  • semantic-ui.com

CSS

  • 模块分级
    • 全局级
    • 模块级
    • 页面级
  • 分栏布局

    例如左宽665px,父容器宽1000px,在layout.css中定义:

    .R665{float: left; margin-left: 688px; width:312px;}
    .L665{float: left; width: 665px; margin-left: -100%;}
    

    参考:

    双飞翼布局 常见布局

  • 绝对底部

    CSS Sticky Footer

  • 清除浮动

  • 子选择器

    利用父级元素id进行选择

  • 图文混排

  • CSS盒模型

  • 垂直居中

  • 如何制作三角

  • :first-child 和 :last-child
    • 案例 : 圆圈 , padding
  • 如果内容可变,就不要设置高度

  • 写完页面依次检查
    • 对齐

    • 字体
      • 大小
      • 粗细
      • 颜色
    • 留白

  • 邮件

    Css Inliner Tool

  • 42web
    • HTML中如何引用图片

    图片上传至七牛,使用外链地址 * CSS中如何引用图片:

    background:url(/css/_img/xxx)
    
    • 不要引用站外的图片
  • checkbox 和 radio 的 样式

    文字对齐

  • 不要用空格做间距

我们常用的CSS样式

  • 按钮
    • 功能
    • 强调

设计

  • 对齐
  • 留白的一致性
  • 粗体
  • 字号

javascript

  • 获取时间戳:

    (new Date).getTime()
    
  • 在js中取得当前用户:

    $.current_user
    
  • $$

    例如调用弹窗(可有多个参数):

    $$('SITE/auth/login')
    
  • require

  • $.require

  • $.dialog
    • 需要登录调用$.login_dialog(参考submit_project.coffee)
  • $.errtip

    err = {}
    
    if xxx:
     err.xxx = "xx"
     if xx :
        err.xx ="xx"
    
        if not errtip.set err:
           xxxxx
    

jQuery

  • $.extend([deep],target,object)

jQuery 自定义扩展

  • $.timeago

    接受一个时间戳作为参数,返回距离当前时间描述

  • $.isotime

  • $.getJSON1
    • jsonp 跨域调用
  • $.postJSON1

  • $.html 模版

    参考egg_new.coffee

jQuery UI

  • Accordion
  • Datepicker
  • Tagit

avalon

  • 命名规则的修改

    “-“改为”_”

  • ms_view

  • 操作类似view的复用

  • view与数据结构的模块划分原则(每一个保存的url对应一个view)

  • $remove

  • $watch

  • 如何定义avalon组建
    • 创建既可以单独使用,也可以在循环中使用的avalon组件

    参考ui_follow.coffee

Firebug

  • 控制台面板中,点击“保持”按钮,页面重新载入时不清空面板

杂项

工具

  • Chrome插件
    • PerfectPixel
    • Page Ruler
  • Windows
    • Color Picker

后端

python

  • 闭包
  • 正则表达式
  • collections - defaultdict
  • itertools
  • enum - IntEnum
  • enumerate
  • time.mktime(time.strptime(“2007-03-04 21:08:12”, “%Y-%m-%d %H:%M:%S”))
  • dateparser
  • python 的 新式类与旧式类 , 以及super的意义

mongodb

  • find
    • limit
    • skip
    • sort
  • delete

  • remove(删除条件)

  • save
    • 填充默认值
  • upsert

MySQL

  • get
  • mc_get
  • mc_get_list

Kv

  • id_by_value
  • get
  • mc_get

nginx

mako

  • this 比如 this.get_argument(‘q’)
  • ${json_encode(xxx)|n}

redis

  • hset
  • set
  • zset
  • list
  • expire

mongo

  • 时间用int保存
  • mongo默认值需要是一个生成函数 * pyhton常见的默认值陷阱,以create_time=time()为例

gearman

supervisor

  • 线上服务器如何看异常

tornado

  • 通过编写 Base View简化业务开发

42web

  • 新建url页面
  • render
  • css,js的引用
  • merge.conf
  • 新建css,js,修改merge.conf需要重启开发服务器
  • View的类型
  • 分页
  • 在页面取得当前用户
  • 搜索
  • 自动补全
  • gearman 异步调用
  • JsOb
  • rendermail 发送邮件
  • redis key的定义 , R.
  • model 中 使用绝对路径import以防止redis提示key重复定义
  • import _env
  • 配置文件 的 定义 与 自适应
  • make.py 生成配置文件

开发习惯

  • 修改函数接口后, 用ag查找并修改些调用过的地方

  • 函数命名规则 :名词在前动词在后 , 常用命名如下

    • user_new 新建
    • user_rm 删除
    • user_dumps 返回一个包含各种相关数据的json对象
    • user_id_list_by_com_id(limit, offset) 查询
    • user_new 新建
    • user_rm 删除
    • user_dumps 返回一个包含各种相关数据的json对象
    • user_id_list_by_com_id(limit, offset) 查询
    • user_id_count_by_com_id

    我们通常把user_id作为第一个参数

开发流程

  • 表单
    1. 编写静态html页面
    2. coffeescript完成交互
    3. 演示并验收前端页面
    4. 定义 url 和 json数据
    5. 完成ajax保存接口
    6. 数据回填
    7. 演示并验收
    8. code review
    9. 合并到default
    10. 上线到开发服务器
    11. 合并到online
    12. 上线到线上服务器
前端
  • 确认链接都链接到了正确的页面

项目规划

类似 weebly.com 的编辑器