EtherCalc for Drupal

3,662 views

Published on

Draft slides for DrupalCamp Taipei, 2012.7.7.

Published in: Technology, Sports
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,662
On SlideShare
0
From Embeds
0
Number of Embeds
19
Actions
Shares
0
Downloads
41
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

EtherCalc for Drupal

  1. 1. EtherCalc 多人即時協作試算表
  2. 2. EtherCalc for Drupal 多人即時協作試算表
  3. 3. 僅代表個人立場
  4. 4. 只講故事不講程式
  5. 5. 概念只講故事不講程式
  6. 6. SheetNode.org
  7. 7. SheetNode.org
  8. 8. SheetNode.org‣ npm install -g ethercalc‣ ethercalc Please connect to: http://0:8000/
  9. 9. ⟪開源應用架構⟫EtherCalc.twaosabook.org
  10. 10. 緣起
  11. 11. VisiCalc, 1979Dan Bricklin
  12. 12. 哈佛商學院, 1977
  13. 13. 哈佛商學院, 1977
  14. 14. 哈佛商學院, 1977
  15. 15. 哈佛商學院, 1977
  16. 16. 哈佛商學院, 1977
  17. 17. 最初的願景
  18. 18. 最初的願景 Alto 工作站
  19. 19. 最初的願景 Alto 工作站滑鼠計算機
  20. 20. 最初的願景 Alto 工作站滑鼠計算機 頭戴顯示器
  21. 21. 最初的願景 Alto 工作站滑鼠計算機 頭戴顯示器
  22. 22. =SUM( ) 0
  23. 23. 10 20 30 =SUM( ) 60 30 10 0
  24. 24. 10 20 30 =SUM( ) 60 30 10 0
  25. 25. 1977 → 1978
  26. 26. 1977 → 1978
  27. 27. 1977 → 1978 + Integer BASIC
  28. 28. 1978 → 1979
  29. 29. 1978 → 1979 10 20 30 =SUM( ) 60
  30. 30. 1978 → 1979 A B C D1 10 20 302 =SUM( ) 60
  31. 31. 1978 → 1979 A B C D1 10 20 302 =SUM(A1,B1,C1) 60
  32. 32. 1978 → 1979 A B C D1 10 20 302 =SUM(A1,B1,C1) 60 Bob & Dan
  33. 33. 1978 → 1979 A B C D 1 10 20 30 2 =SUM(A1,B1,C1) 60‣ 6 年售出 700,000 套 Bob & Dan
  34. 34. 1978 → 1979 A B C D 1 10 20 30 2 =SUM(A1,B1,C1) 60‣ 6 年售出 700,000 套‣ 「殺手級應用」的始祖 Bob & Dan
  35. 35. 1981
  36. 36. 二十年來
  37. 37. 二十年來
  38. 38. 二十年來
  39. 39. 二十年來
  40. 40. 二十年來 始終如一
  41. 41. “打不開”
  42. 42. “打不開”“變亂碼”
  43. 43. “打不開”“變亂碼”“有病毒!”
  44. 44. 維基百科, 2001
  45. 45. 維基百科, 2001
  46. 46. 維基百科, 2001
  47. 47. wikiCalc, 2005
  48. 48. wikiCalc, 2005✓ 跨伺服器引用數值。
  49. 49. wikiCalc, 2005✓ 跨伺服器引用數值。✓ 保留每個版本,可隨時回復 。
  50. 50. wikiCalc, 2005✓ 跨伺服器引用數值。✓ 保留每個版本,可隨時回復 。✓ 支援純文字、HTML、Wiki 語法。
  51. 51. wikiCalc, 2005✓ 跨伺服器引用數值。✓ 保留每個版本,可隨時回復 。✓ 支援純文字、HTML、Wiki 語法。✓ 開放源碼!
  52. 52. wikiCalc.pl
  53. 53. wikiCalc.pl 網站./wkcdata/sites/Foo ./wkcdata/sites/Bar ./wkcdata/sites/Baz
  54. 54. wikiCalc.pl 網站 頁面./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ
  55. 55. wikiCalc.pl 網站 頁面./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ 儲存格
  56. 56. wikiCalc.pl 網站 頁面./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ 儲存格 A1: 100
  57. 57. wikiCalc.pl 網站 頁面./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ 儲存格 A1: 100 A2: =A1*2
  58. 58. wikiCalc.pl 網站 頁面./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ 儲存格 A1: 100 B1: =XXX!C1 A2: =A1*2
  59. 59. wikiCalc.pl 網站 頁面./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ 儲存格 A1: 100 B1: =XXX!C1 A2: =A1*2
  60. 60. wikiCalc.pl 網站 頁面./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ 儲存格 A1: 100 B1: =XXX!C1 A2: =A1*2 B2: =YYY!D2
  61. 61. wikiCalc.pl 網站 頁面./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ 儲存格 A1: 100 B1: =XXX!C1 A2: =A1*2 B2: =YYY!D2
  62. 62. wikiCalc.pl 網站 頁面./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ 儲存格 A1: 100 B1: =XXX!C1 A2: =A1*2 B2: =YYY!D2 跨頁引用
  63. 63. wikiCalc 編輯流程
  64. 64. wikiCalc 編輯流程 A1: 100 A2: =A1*2
  65. 65. wikiCalc 編輯流程 A1: 100 A2: =A1*2
  66. 66. wikiCalc 編輯流程 A1: 100 A2: =A1*2 POST / ajaxsetcell=host:page:A1:300 wikicalc.pl
  67. 67. wikiCalc 編輯流程 A1: 100 A2: =A1*2 POST / ajaxsetcell=host:page:A1:300 wikicalc.pl 200 OK <?xml version="1.0"?> <root><![CDATA[ A1:v:300:300:right:1:1:: A2:f:600:A1*2:right:1:1:: ]]></root>
  68. 68. “載入中…”
  69. 69. “載入中…”
  70. 70. “載入中…”“C100k” 問題
  71. 71. “載入中…”“C100k” 問題
  72. 72. 打掉重練
  73. 73. 打掉重練
  74. 74. SocialCalc, 2006Dan Bricklin Ross Mayfield
  75. 75. 設計目標
  76. 76. 設計目標‣ 引擎用 JavaScript 重寫。
  77. 77. 設計目標‣ 引擎用 JavaScript 重寫。‣ 即時編輯及還原/重作。
  78. 78. 設計目標‣ 引擎用 JavaScript 重寫。‣ 即時編輯及還原/重作。‣ 能處理十萬個儲存格。
  79. 79. 系統架構
  80. 80. 系統架構SocialCalc.jsHTTP Server
  81. 81. 系統架構 SocialCalc.jsGET HTTP Server
  82. 82. 系統架構 SocialCalc.jsGET HTTP Server
  83. 83. 系統架構 SocialCalc.jsGET GET HTTP Server
  84. 84. 系統架構 SocialCalc.jsGET GET ($) HTTP Server
  85. 85. 系統架構 SocialCalc.js PUTGET GET ($) HTTP Server
  86. 86. 指令設計模式
  87. 87. 指令設計模式set A1 value n 42
  88. 88. 指令設計模式set A1 value n 42set A2 formula A1*2
  89. 89. 指令設計模式set A1 value n 42set A2 formula A1*2merge A1:B2cut A3paste A4sort A1:B9 A up B downset sheet defaultcolor blue...
  90. 90. 指令設計模式set A1 value n 42set A2 formula A1*2‣ 背景處理計算。
  91. 91. 指令設計模式set A1 value n 42set A2 formula A1*2‣ 背景處理計算。‣ 無限次還原重做。
  92. 92. 指令設計模式set A1 value n 42set A2 formula A1*2‣ 背景處理計算。‣ 無限次還原重做。‣ 鍵盤滑鼠隨時可用!
  93. 93. “社會化” 試算表
  94. 94. “社會化” 試算表
  95. 95. “社會化” 試算表 評論、按讚、推薦、 標記、分享、嵌入...
  96. 96. 社會物件 人際連結
  97. 97. 社會物件 人際連結
  98. 98. 社會物件 人際連結
  99. 99.
  100. 100. CPAL 通用公共授權
  101. 101. CPAL 通用公共授權 ㊔BSD, MIT
  102. 102. CPAL 通用公共授權 © ㊔BSD, MIT LGPL, MPL
  103. 103. CPAL 通用公共授權 © ++© ㊔BSD, MIT LGPL, MPL GPL
  104. 104. CPAL 通用公共授權 © ++© ㊔BSD, MIT LGPL, MPL GPL “ASP
  105. 105.   ”
  106. 106. CPAL 通用公共授權 © ++© ㊔BSD, MIT LGPL, MPL GPL “ASP
  107. 107.   ” Affero GPL
  108. 108. CPAL 通用公共授權 © ++© ㊔BSD, MIT LGPL, MPL GPL “ASP
  109. 109.   ” CPAL Affero GPL
  110. 110. CPAL 通用公共授權 © ++© ㊔BSD, MIT LGPL, MPL GPL “ASP
  111. 111.   ” CPAL Affero GPL
  112. 112. CPAL 通用公共授權 © ++© ㊔BSD, MIT LGPL, MPL GPL “ASP
  113. 113.   ” CPAL Affero GPL
  114. 114. CPAL 通用公共授權 © ++© ㊔BSD, MIT LGPL, MPL GPL “ASP
  115. 115.   ” CPAL Affero GPL
  116. 116. Sheetnode, 2008Karim Ratib
  117. 117. Sheetnode, 2008 Views + Fields + CCKKarim Ratib
  118. 118. Sheetnode, 2008 Views + Fields + CCK SocialCalc.jsKarim Ratib
  119. 119. Sheetnode, 2008 Views + Fields + CCK SocialCalc.jsKarim Ratib
  120. 120. Sheetnode, 2008 Views + Fields + CCK SocialCalc.jsKarim Ratib
  121. 121. Sheetnode, 2008 Views + Fields + CCK SocialCalc.jsKarim Ratib
  122. 122. Sheetnode, 2008
  123. 123. Sheetnode, 2008I was looking for an open sourceequivalent to Google Docs thatwould allow tighter integrationwith a companys data:
  124. 124. Sheetnode, 2008 I was looking for an open source equivalent to Google Docs that would allow tighter integration with a companys data: “Real-time reports,created out of Drupal data.”
  125. 125. SheetNode.org
  126. 126. SheetNode.org
  127. 127. SheetNode.orgViews
  128. 128. OLPC, 2008
  129. 129. OLPC, 2008Luke Closs Dan
  130. 130. Mesh網絡
  131. 131. Manusheel GuptaVijit Singh
  132. 132. SocialCalcActivity.py Gecko/XPCOM SocialCalc.js XoCom.js XoCom.pyManusheel GuptaVijit Singh
  133. 133. SocialCalcActivity.py Gecko/XPCOM SocialCalc.js XoCom.js set A1 value n 42 XoCom.pyManusheel GuptaVijit Singh
  134. 134. SocialCalcActivity.py Gecko/XPCOM SocialCalc.js XoCom.js set A1 value n 42 XoCom.py D-Bus + TelepathyManusheel GuptaVijit Singh
  135. 135. SocialCalcActivity.py Gecko/XPCOM SocialCalc.js XoCom.js set A1 value n 42 XoCom.py D-Bus + Telepathy OLPC MeshManusheel Gupta 網絡廣播Vijit Singh
  136. 136. SocialCalcActivity.py Gecko/XPCOM SocialCalc.js XoCom.js set A1 value n 42 XoCom.py D-Bus + Telepathy OLPC MeshManusheel Gupta 網絡廣播 D-Bus + Telepathy Gecko/XPCOM SocialCalc.js XoCom.js XoCom.pyVijit Singh SocialCalcActivity.py
  137. 137. SocialCalcActivity.py Gecko/XPCOM SocialCalc.js XoCom.js set A1 value n 42 XoCom.py D-Bus + Telepathy OLPC MeshManusheel Gupta 網絡廣播 D-Bus + Telepathy Gecko/XPCOM set A1 value n 42 SocialCalc.js XoCom.js XoCom.pyVijit Singh SocialCalcActivity.py
  138. 138. 很讚,但是...
  139. 139. 很讚,但是...‣ 漏接訊息無法復原。
  140. 140. 很讚,但是...‣ 漏接訊息無法復原。‣ 編輯同一格時會衝突。
  141. 141. 很讚,但是...‣ 漏接訊息無法復原。‣ 編輯同一格時會衝突。‣ 只能在 OLPC 上使用!
  142. 142. YAPC::Tiny, 2009
  143. 143. EV: 事件驅動
  144. 144. Tatsumaki EV: 事件驅動 @miyagawa
  145. 145. Tatsumaki EV: 事件驅動 Web::Hippie @miyagawa @clkao
  146. 146. Tatsumaki EV: 事件驅動 Web::Hippie Feersum @miyagawa @clkao @stash
  147. 147. WebSocket 同步編輯 multiserver.pl Web::Hippie Plack Feersum EV/libev
  148. 148. WebSocket 同步編輯 SpreadsheetControl multiserver.pl Web::HippieScheduleScheetCommand set A1 value n 2046 Plack RenderSheet Feersum EV/libev
  149. 149. WebSocket 同步編輯 SpreadsheetControl multiserver.pl Web::HippieScheduleScheetCommand set A1 value n 2046 Plack RenderSheet 傳送 Feersum EV/libev
  150. 150. WebSocket 同步編輯 SpreadsheetControl multiserver.plScheduleScheetCommand Web::Hippie 群播 set A1 value n 2046 Plack RenderSheet 傳送 Feersum EV/libev
  151. 151. WebSocket 同步編輯 SpreadsheetControl multiserver.plScheduleScheetCommand Web::Hippie 群播 set A1 value n 2046 Plack ScheduleScheetCommand RenderSheet 傳送 Feersum set A1 value n 2046 (isRemote = true) EV/libev RenderSheet
  152. 152. 新增功能
  153. 153. 新增功能✓斷線重連可以復原。
  154. 154. 新增功能✓斷線重連可以復原。✓顯示別人的游標位置。
  155. 155. 新增功能✓斷線重連可以復原。✓顯示別人的游標位置。✓可以在各平台上運行!
  156. 156. 新增功能✓斷線重連可以復原。✓顯示別人的游標位置。✓可以在各平台上運行!
  157. 157. 更讚了,但是...
  158. 158. 更讚了,但是...‣ 要相信誰的目前狀態?
  159. 159. 更讚了,但是...‣ 要相信誰的目前狀態?‣ 所有人離線:資料消失?
  160. 160. 更讚了,但是...‣ 要相信誰的目前狀態?‣ 所有人離線:資料消失?‣ 重新連接:回播所有指令?
  161. 161. 更讚了,但是...‣ 要相信誰的目前狀態?‣ 所有人離線:資料消失?‣ 重新連接:回播所有指令?
  162. 162. 打掉重練
  163. 163. 打掉重練
  164. 164. YAPC::NA, 2006
  165. 165. YAPC::NA, 2006“I think, but I cannot prove, that bythe next year JavaScript 2.0 willbootstrap itself, complete selfhosting, compile back to JavaScript,and replace Ruby as the Next BigThing in all environments. ”
  166. 166. YAPC::NA, 2006
  167. 167. YAPC::NA, 2006“JavaScript will become the commonbackend for all dynamic languages,and so you can write Perl to run in thebrowser, on the server, and insidedatabases, all with the same set ofdevelopment tools. ”
  168. 168. YAPC::NA, 2006
  169. 169. YAPC::NA, 2006“Because, as we all know,worse is better, so the worstscripting language is doomedto become the best.”
  170. 170. YAPC::NA, 2006“Because, as we all know,worse is better, so the worstscripting language is doomedto become the best.” 劣即是夯
  171. 171. JavaScript: 缺點減少
  172. 172. JavaScript: 缺點減少 CoffeeScript: 標點減半 cs = (js) - js/2 JeremyAshkenas
  173. 173. JavaScript: 缺點減少 CoffeeScript: 標點減半 cs = (js) - js/2 JeremyAshkenas
  174. 174. JavaScript: 缺點減少 CoffeeScript: 標點減半 cs = (js) - js/2 “原 JavaScript 行數: 22k。  重寫過的 CoffeeScript 行數: 5k。  {async, jsdom, zappa, optimist etc}++” JeremyAshkenas
  175. 175. {x,y} = @offset
  176. 176. {x,y} = @offsetvar offset = this.offset;
  177. 177. {x,y} = @offsetvar offset = this.offset;var x = offset.x;
  178. 178. {x,y} = @offsetvar offset = this.offset;var x = offset.x;var y = offset.y;
  179. 179. {x,y} = @offsetvar offset = this.offset;var x = offset.x;var y = offset.y; js2coffee.org
  180. 180. COSCUP, 2011
  181. 181. COSCUP, 2011
  182. 182. COSCUP, 2011hack
  183. 183.  hack
  184. 184.  hack
  185. 185.  ...
  186. 186. COSCUP, 2011hack
  187. 187.  hack
  188. 188.  hack
  189. 189.  ...
  190. 190. EtherCalc 系統架構
  191. 191. EtherCalc 系統架構 main.coffee sc.coffee Socket.ioSocialCalc.js SocialCalc.js Express Node.js db.coffee EV/libuv redis.js Zappa
  192. 192. EtherCalc 系統架構 main.coffee sc.coffee Socket.ioSocialCalc.js SocialCalc.js Express Node.js db.coffee EV/libuv redis.js Zappa Redis (optional)
  193. 193. EtherCalc 系統架構 main.coffee sc.coffee Socket.ioSocialCalc.js SocialCalc.js Express Node.js db.coffee EV/libuv player.coffee redis.js Zappa SocialCalc.js SocialCalc.js Redis (optional)
  194. 194. EtherCalc 系統架構 main.coffee sc.coffee GET snapshot Socket.ioSocialCalc.js SocialCalc.js LRANGE log Express Node.js db.coffee EV/libuv player.coffee redis.js Zappa SocialCalc.js SocialCalc.js Redis (optional)
  195. 195. EtherCalc 系統架構 main.coffee sc.coffee GET snapshot Socket.ioSocialCalc.js SocialCalc.js LRANGE log Express Node.js db.coffee EV/libuv player.coffee redis.js Zappa SocialCalc.js SocialCalc.js RPUSH log cmd Redis (optional)
  196. 196. EtherCalc 系統架構 main.coffee sc.coffee GET snapshot Socket.ioSocialCalc.js SocialCalc.js LRANGE log Express Node.js db.coffee EV/libuv player.coffee redis.js Zappa SocialCalc.js SocialCalc.js RPUSH log cmd Redis (optional)
  197. 197. EtherCalc 系統架構 main.coffee sc.coffee GET snapshot Socket.ioSocialCalc.js SocialCalc.js LRANGE log Express Node.js db.coffee EV/libuv player.coffee redis.js Zappa SocialCalc.js SocialCalc.js RPUSH log cmd Redis (optional)
  198. 198. EtherCalc 系統架構 main.coffee sc.coffee GET snapshot Socket.ioSocialCalc.js SocialCalc.js LRANGE log Express Node.js db.coffee EV/libuv player.coffee redis.js Zappa SocialCalc.js SocialCalc.js Redis DEL log RPUSH log cmd (optional) SET snapshot snapshot
  199. 199. 跨頁即時更新
  200. 200. 跨頁即時更新伺服端
  201. 201. 跨頁即時更新伺 客服 戶端 端
  202. 202. 跨頁即時更新 ask.log: XXX伺 客服 戶端 端
  203. 203. 跨頁即時更新 ask.log: XXX伺 log: XXX,snapshot,log 客服 戶端 端
  204. 204. 跨頁即時更新 ask.log: XXX伺 log: XXX,snapshot,log 客 execute: set A1服 formula YYY!B2 戶端 端
  205. 205. 跨頁即時更新 ask.log: XXX伺 log: XXX,snapshot,log 客 execute: set A1服 formula YYY!B2 戶 recalc: YYY,snapshot端 端
  206. 206. 跨頁即時更新 ask.log: XXX伺 log: XXX,snapshot,log 客 execute: set A1服 formula YYY!B2 戶 recalc: YYY,snapshot端 recalc: YYY,snapshot 端
  207. 207. 跨頁即時更新 ask.log: XXX伺 log: XXX,snapshot,log 客 execute: set A1服 formula YYY!B2 戶 recalc: YYY,snapshot端 recalc: YYY,snapshot 端 recalc: YYY,snapshot
  208. 208. REST 資源界面
  209. 209. REST 資源界面GET /_/pagePUT /_/page
  210. 210. REST 資源界面GET /_/page POST /_/pagePUT /_/page {commands:[…]}
  211. 211. REST 資源界面GET /_/page POST /_/pagePUT /_/page {commands:[…]} GET /_/page/cells/A1 PUT /_/page/cells/B2
  212. 212. + =
  213. 213. + =+ = Coco
  214. 214. + = + = CocoCoco + =
  215. 215. stove.on(heat, function() {
  216. 216. stove.on(heat, function() { pot.on(boil, function() {
  217. 217. stove.on(heat, function() { pot.on(boil, function() { rice.on(ready, function(dish) {
  218. 218. stove.on(heat, function() { pot.on(boil, function() { rice.on(ready, function(dish) { setTimeout(function() {
  219. 219. stove.on(heat, function() { pot.on(boil, function() { rice.on(ready, function(dish) { setTimeout(function() { dish.serve(); }, 60000);
  220. 220. stove.on(heat, function() { pot.on(boil, function() { rice.on(ready, function(dish) { setTimeout(function() { dish.serve(); }, 60000); }); });});
  221. 221. stove.on(heat, function() { pot.on(boil, function() { rice.on(ready, function(dish) { setTimeout(function() { dish.serve(); }, 60000); }); });});
  222. 222. stove.on(heat, function() { pot.on(boil, function() { rice.on(ready, function(dish) { setTimeout(function() { dish.serve(); }, 60000); }); });});
  223. 223. stove.on heat, -
  224. 224. stove.on heat, - pot.on boil, -
  225. 225. stove.on heat, - pot.on boil, - rice.on ready, (dish) -
  226. 226. stove.on heat, - pot.on boil, - rice.on ready, (dish) - setTimeout(
  227. 227. stove.on heat, - pot.on boil, - rice.on ready, (dish) - setTimeout( - dish.serve()
  228. 228. stove.on heat, - pot.on boil, - rice.on ready, (dish) - setTimeout( - dish.serve() 60000
  229. 229. stove.on heat, - pot.on boil, - rice.on ready, (dish) - setTimeout( - dish.serve() 60000 )
  230. 230. stove.on heat, - pot.on boil, - rice.on ready, (dish) - setTimeout( - dish.serve() 60000 )
  231. 231. - stove.on heat
  232. 232. - stove.on heat- pot.on boil
  233. 233. - stove.on heat- pot.on boildish - rice.on ready
  234. 234. - stove.on heat- pot.on boildish - rice.on ready- (`setTimeout` 60000)
  235. 235. - stove.on heat- pot.on boildish - rice.on ready- (`setTimeout` 60000)dish.serve!
  236. 236. - stove.on heat- pot.on boildish - rice.on ready- (`setTimeout` 60000)dish.serve!
  237. 237. OSDC.tw, 2012
  238. 238. OSDC.tw, 2012
  239. 239. OSDC.tw, 2012
  240. 240. OSDC.tw, 2012
  241. 241. 哪來的「高風亮節」…
  242. 242. 哪來的「高風亮節」…只是沒寫過Drupal 模組。
  243. 243. 雖然 Isis 架過許多 Drupal 網站我也幫忙改了一些…
  244. 244. 雖然 Isis 架過許多 Drupal 網站我也幫忙改了一些…
  245. 245. 雖然 Isis 架過許多 Drupal 網站我也幫忙改了一些…
  246. 246. 雖然 Isis 架過許多 Drupal 網站我也幫忙改了一些…
  247. 247. 可是我對架構完全沒有概念。
  248. 248. 可是我對架構完全沒有概念。
  249. 249. ⟪開源之樂⟫, 2012. 7. 1.
  250. 250. ⟪開源之樂⟫, 2012. 7. 1.
  251. 251. ⟪開源之樂⟫, 2012. 7. 1.
  252. 252. ⟪開源之樂⟫, 2012. 7. 1. “內容過於抽象。”
  253. 253. ⟪開源之樂⟫, 2012. 7. 1. “內容過於抽象。” “這跟 Drupal 到底有何關係?”
  254. 254. 2012. 7. 2.
  255. 255. 2012. 7. 2.“你還是把EtherCalc for Drupal 寫出來,比較有意義。”
  256. 256. 2012. 7. 2.“你還是把EtherCalc for Drupal 寫出來,比較有意義。”
  257. 257. 2012. 7. 2.“你還是把EtherCalc for Drupal 寫出來,比較有意義。”
  258. 258. 2012. 7. 3.
  259. 259. 2012. 7. 3.感謝 Karim 幫忙
  260. 260. 2012. 7. 3. 感謝 Karim 幫忙 一個早上 就寫完了。
  261. 261. /** * * Implements hook_menu(). * * In sheetnode_ethercalc_menu.info: * configure = admin/config/content/sheetnode/ethercalc * */function sheetnode_ethercalc_menu() { array(admin/config/content/sheetnode/ethercalc = array( title = EtherCalc, access arguments = array(administer site configuration), page callback = drupal_get_form, page arguments = array(_sheetnode_ethercalc_settings), description = Administer settings for EtherCalc., type = MENU_LOCAL_TASK, ));}
  262. 262. /** * * Implements hook_menu(). * * In sheetnode_ethercalc_menu.info: * configure = admin/config/content/sheetnode/ethercalc * */function sheetnode_ethercalc_menu() { array(admin/config/content/sheetnode/ethercalc = array( title = EtherCalc, access arguments = array(administer site configuration), page callback = drupal_get_form, page arguments = array(_sheetnode_ethercalc_settings), description = Administer settings for EtherCalc., type = MENU_LOCAL_TASK, ));}
  263. 263. /** * Implements hook_sheetnode_plugins(). */function sheetnode_ethercalc_sheetnode_plugins( $value, $save_element, $context) { // Only turn on Ethercalc if were editing the node. if (!empty($save_element)) { $ethercalc_host = variable_get(sheetnode_ethercalc_host, ); $ethercalc_port = variable_get(sheetnode_ethercalc_port, 8000); $ethercalc_path = …; drupal_add_js($ethercalc_path . /socket.io/socket.io.js#); drupal_add_js($ethercalc_path . /zappa/zappa.js#); drupal_add_js($ethercalc_path . /static/md5.js#); drupal_add_js($ethercalc_path . /player/broadcast.js#); drupal_add_js($ethercalc_path . /player/main.js#); }}
  264. 264. /** * Implements hook_sheetnode_plugins(). */function sheetnode_ethercalc_sheetnode_plugins( $value, $save_element, $context) { // Only turn on Ethercalc if were editing the node. if (!empty($save_element)) { $ethercalc_host = variable_get(sheetnode_ethercalc_host, ); $ethercalc_port = variable_get(sheetnode_ethercalc_port, 8000); $ethercalc_path = …; drupal_add_js($ethercalc_path . /socket.io/socket.io.js#); drupal_add_js($ethercalc_path . /zappa/zappa.js#); drupal_add_js($ethercalc_path . /static/md5.js#); drupal_add_js($ethercalc_path . /player/broadcast.js#); drupal_add_js($ethercalc_path . /player/main.js#); }}
  265. 265. 2012. 7. 4.
  266. 266. 2012. 7. 4.
  267. 267. 2012. 7. 4. Lith.tw
  268. 268. 2012. 7. 4. Lith.tw
  269. 269. 2012. 7. 4. Lith.tw
  270. 270. 2012. 7. 4. Lith.tw
  271. 271. 2012. 7. 4. Lith.tw
  272. 272. 2012. 7. 4. Lith.tw
  273. 273. 結論是:
  274. 274. 結論是:
  275. 275. 結論是:寫 Drupal 模組真的很簡單!
  276. 276. 感謝收看! EtherCalc for Drupal
  277. 277. EtherCalc以著作結合本文件之人,在法律許可之範圍內,拋棄該著作依著作權法所享有之權利,及其相關或鄰接的法律權利,宣告該著作貢獻至公共領域。採用 CC0 之著作,不要求姓名表彰。 SheetNode.org

×