├── .meteor
├── .gitignore
├── release
└── packages
├── public
├── 1.1.jpg
├── 2.1.jpg
├── 2.2.jpg
├── 3.1.jpg
└── 9.1.jpg
├── README.md
├── server
└── server.js
└── client
├── index.html
├── login.html
├── reg.html
├── client.html
└── client.js
/.meteor/.gitignore:
--------------------------------------------------------------------------------
1 | local
--------------------------------------------------------------------------------
/.meteor/release:
--------------------------------------------------------------------------------
1 | none
2 |
--------------------------------------------------------------------------------
/public/1.1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nswbmw/N-weibo/HEAD/public/1.1.jpg
--------------------------------------------------------------------------------
/public/2.1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nswbmw/N-weibo/HEAD/public/2.1.jpg
--------------------------------------------------------------------------------
/public/2.2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nswbmw/N-weibo/HEAD/public/2.2.jpg
--------------------------------------------------------------------------------
/public/3.1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nswbmw/N-weibo/HEAD/public/3.1.jpg
--------------------------------------------------------------------------------
/public/9.1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nswbmw/N-weibo/HEAD/public/9.1.jpg
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | N-weibo
2 | ======
3 |
4 | 使用 Meteor 搭建的微博网站
5 |
6 | 教程见 [wiki](https://github.com/nswbmw/N-weibo/wiki/_pages)
--------------------------------------------------------------------------------
/server/server.js:
--------------------------------------------------------------------------------
1 | Posts = new Meteor.Collection("posts");
2 |
3 | Posts.allow({
4 | insert: function (userId, doc) {
5 | return (userId && doc.user._id === userId);
6 | }
7 | });
--------------------------------------------------------------------------------
/.meteor/packages:
--------------------------------------------------------------------------------
1 | # Meteor packages used by this project, one per line.
2 | #
3 | # 'meteor add' and 'meteor remove' will edit this file for you,
4 | # but you can also edit it by hand.
5 |
6 | autopublish
7 | preserve-inputs
8 | bootstrap
9 | backbone
10 | accounts-password
11 | showdown
12 |
--------------------------------------------------------------------------------
/client/index.html:
--------------------------------------------------------------------------------
1 |
2 | {{#if currentUser}}
3 |
7 | {{/if}}
8 |
9 | {{#each posts}}
10 | {{user.username}} 说
11 | {{time}}
12 | {{#markdown}}{{post}}{{/markdown}}
13 | {{/each}}
14 |
--------------------------------------------------------------------------------
/client/login.html:
--------------------------------------------------------------------------------
1 |
2 |
22 |
--------------------------------------------------------------------------------
/client/reg.html:
--------------------------------------------------------------------------------
1 |
2 |
28 |
--------------------------------------------------------------------------------
/client/client.html:
--------------------------------------------------------------------------------
1 |
2 | weibo
3 |
6 |
7 |
8 |
9 | {{> nav}}
10 | {{> container}}
11 | {{> footer}}
12 |
13 |
14 |
15 |
38 |
39 |
40 |
41 |
42 | {{> info}}
43 | {{#if currentUrl.index}}
44 | {{> index}}
45 | {{/if}}
46 |
47 | {{#if currentUrl.login}}
48 | {{> login}}
49 | {{/if}}
50 |
51 | {{#if currentUrl.reg}}
52 | {{> reg}}
53 | {{/if}}
54 |
55 |
56 |
57 |
58 | nswbmw 2013
59 |
60 |
61 |
62 | {{#if info.success}}
63 | {{info.success}}
64 | {{/if}}
65 |
66 | {{#if info.error}}
67 | {{info.error}}
68 | {{/if}}
69 |
--------------------------------------------------------------------------------
/client/client.js:
--------------------------------------------------------------------------------
1 | Session.setDefault("currentUrl", {index: "active", login: "", reg: ""});
2 | Session.setDefault("info", {success: "", error: ""});
3 |
4 | Template.container.currentUrl = function () {
5 | return Session.get("currentUrl");
6 | };
7 |
8 | Template.nav.active = function () {
9 | return Session.get("currentUrl");
10 | };
11 |
12 | Template.info.info = function () {
13 | return Session.get("info");
14 | };
15 |
16 | var urlRouter = Backbone.Router.extend({
17 | routes: {
18 | "": "index",
19 | "login": "login",
20 | "reg": "reg",
21 | "logout": "logout"
22 | },
23 | index: function () {
24 | Session.set("currentUrl", {index: "active", login: "", reg: ""});
25 | },
26 | login: function () {
27 | if (Meteor.userId()) {
28 | this.navigate("/", true);
29 | Session.set("info", {success: "", error: "用户已在线"});
30 | return;
31 | }
32 | Session.set("currentUrl", {index: "", login: "active", reg: ""});
33 | },
34 | reg: function () {
35 | if (Meteor.userId()) {
36 | this.navigate("/", true);
37 | Session.set("info", {success: "", error: "用户已在线"});
38 | return;
39 | }
40 | Session.set("currentUrl", {index: "", login: "", reg: "active"});
41 | },
42 | logout: function () {
43 | if (Meteor.userId()) {
44 | Meteor.logout();
45 | this.navigate("/", true);
46 | Session.set("info", {success: "登出成功", error: ""});
47 | } else {
48 | this.navigate("/", true);
49 | Session.set("info", {success: "", error: "用户不在线"});
50 | }
51 | },
52 | redirect: function (url) {
53 | this.navigate(url, true);
54 | }
55 | });
56 |
57 | Router = new urlRouter;
58 |
59 | Meteor.startup(function () {
60 | Backbone.history.start({pushState: true});
61 | });
62 |
63 | Template.reg.events({
64 | 'click #submit': function (evt) {
65 | evt.preventDefault();
66 | var $username = $("#username").val();
67 | var $password = $("#password").val();
68 | var $password_repeat = $("#password-repeat").val();
69 | if ($password.length ===0 || $username.length ===0) {
70 | Session.set("info", {success: "", error: "用户名或密码不能为空"});
71 | return;
72 | }
73 | if ($password !== $password_repeat) {
74 | Session.set("info", {success: "", error: "两次输入密码不一致"});
75 | return;
76 | }
77 | Accounts.createUser({username: $username, password: $password}, function (err) {
78 | if (err) {
79 | Session.set("info", {success: "", error: err.reason});
80 | } else {
81 | Router.redirect("/");//跳转到主页
82 | Session.set("info", {success: "注册成功", error: ""});
83 | }
84 | });
85 | }
86 | });
87 |
88 | Template.login.events({
89 | 'click #submit': function (evt) {
90 | evt.preventDefault();
91 | var $username = $("#username").val();
92 | var $password = $("#password").val();
93 | if ($password.length ===0 || $username.length ===0) {
94 | Session.set("info", {success: "", error: "用户名或密码不能为空"});
95 | return;
96 | }
97 | Meteor.loginWithPassword($username, $password, function (err) {
98 | if (err) {
99 | Session.set("info", {success: "", error: err.reason});
100 | } else {
101 | Router.redirect("/");//跳转到主页
102 | Session.set("info", {success: "登陆成功", error: ""});
103 | }
104 | });
105 | }
106 | });
107 |
108 | Posts = new Meteor.Collection("posts");
109 |
110 | Template.index.events({
111 | 'click #submit': function (evt) {
112 | evt.preventDefault();
113 | var $post = $("#post").val();
114 | if ($post.length ===0 || $post.length >=140) {
115 | Session.set("info", {success: "", error: "请将字数限制在 1-140 字"});
116 | return;
117 | }
118 | Posts.insert({user: Meteor.user(), post: $post, time: new Date()}, function (err) {
119 | if (err) {
120 | Session.set("info", {success: "", error: err.reason});
121 | } else {
122 | Session.set("info", {success: "发表成功", error: ""});
123 | $("#post").val("");
124 | }
125 | });
126 | }
127 | });
128 |
129 | Template.index.posts = function () {
130 | return Posts.find({}, {sort: {time: -1}});
131 | };
--------------------------------------------------------------------------------