Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Moving to rebar...

This commit is deliberately broken, fixing directory case on
a case-insensitive FS...
  • Loading branch information...
commit 13c256d5fe60bb717485b48d7c7f60b9cec26167 1 parent 797ecd4
@evanmiller evanmiller authored
Showing with 560 additions and 4,106 deletions.
  1. +0 −90 DOC/api-config.html
  2. +0 −253 DOC/api-controller.html
  3. +0 −374 DOC/api-db.html
  4. +0 −71 DOC/api-mail-controller.html
  5. +0 −113 DOC/api-mq.html
  6. +0 −304 DOC/api-record.html
  7. +0 −49 DOC/api-request.html
  8. +0 −113 DOC/api-session.html
  9. +0 −291 DOC/api-test.html
  10. +0 −287 DOC/api-view.html
  11. +0 −49 DOC/api.html
  12. +0 −244 DOC/compare-rails.html
  13. +0 −534 DOC/compare.html
  14. +0 −105 DOC/download.html
  15. +0 −71 DOC/forum.html
  16. +0 −114 DOC/guide-db-driver.html
  17. +0 −72 DOC/guide-evening.html
  18. +0 −128 DOC/guide-example.html
  19. +0 −129 DOC/guide-i18n.html
  20. +0 −67 DOC/guide.html
  21. +0 −88 DOC/index.html
  22. +0 −19 Emakefile
  23. +1 −1  LICENSE
  24. +11 −55 Makefile
  25. +0 −18 SRC/boss/boss.app
  26. +0 −20 SRC/bson/README.md
  27. +0 −56 SRC/mongodb/README.md
  28. +0 −3  START-DEV.SH
  29. +0 −3  START.SH
  30. 0  {DOC/templates → doc-src}/api-config.html
  31. 0  {DOC/templates → doc-src}/api-controller.html
  32. 0  {DOC/templates → doc-src}/api-db.html
  33. 0  {DOC/templates → doc-src}/api-mail-controller.html
  34. 0  {DOC/templates → doc-src}/api-mq.html
  35. 0  {DOC/templates → doc-src}/api-record.html
  36. 0  {DOC/templates → doc-src}/api-request.html
  37. 0  {DOC/templates → doc-src}/api-session.html
  38. 0  {DOC/templates → doc-src}/api-test.html
  39. 0  {DOC/templates → doc-src}/api-view.html
  40. 0  {DOC/templates → doc-src}/api.html
  41. 0  {DOC/templates → doc-src}/boss.css
  42. 0  {static → doc-src}/chicago-boss.png
  43. 0  {DOC/templates → doc-src}/compare-rails.html
  44. 0  {DOC/templates → doc-src}/compare.html
  45. 0  {DOC/templates → doc-src}/download.html
  46. 0  {DOC/templates → doc-src}/forum.html
  47. 0  {DOC/templates → doc-src}/guide-db-driver.html
  48. 0  {DOC/templates → doc-src}/guide-evening.html
  49. 0  {DOC/templates → doc-src}/guide-example.html
  50. 0  {DOC/templates → doc-src}/guide-i18n.html
  51. 0  {DOC/templates → doc-src}/guide.html
  52. 0  {DOC/templates → doc-src}/index.html
  53. 0  {DOC/templates → doc-src}/trivial_boss_record.erl
  54. +59 −0 ebin/boss.app
  55. 0  {SRC/boss → ebin}/boss_db_test.app
  56. 0  {SRC/boss → ebin}/boss_session_test.app
  57. 0  {SRC/boss → ebin}/boss_translator.app
  58. 0  {SRC/bson → }/ebin/bson.app
  59. 0  {SRC/epgsql → ebin}/epgsql.app
  60. 0  {SRC/erlydtl → ebin}/erlydtl.app
  61. 0  {SRC/medici → ebin}/medici.app
  62. 0  {SRC/misultin → ebin}/misultin.app
  63. 0  {SRC/mochiweb → ebin}/mochiweb.app
  64. 0  {SRC/mongodb → }/ebin/mongodb.app
  65. 0  {SRC/bson/include → include2}/bson_binary.hrl
  66. 0  {INCLUDE → include2}/httpd_r12b5.hrl
  67. 0  {INCLUDE → include2}/misultin.hrl
  68. 0  {SRC/mongodb/include → include2}/mongo_protocol.hrl
  69. 0  {INCLUDE → include2}/mysql.hrl
  70. 0  {INCLUDE → include2}/pgsql.hrl
  71. 0  {INCLUDE → include2}/simple_bridge.hrl
  72. 0  {INCLUDE → include2}/xmerl.hrl
  73. 0  {INCLUDE → include2}/yaws_api.hrl
  74. BIN  rebar
  75. +2 −0  rebar.config
  76. +42 −0 skel.template
  77. +12 −0 skel/Makefile
  78. 0  {ADMIN → skel/admin}/admin_controller.erl
  79. 0  {ADMIN → skel/admin}/model/boss_mail_failure.erl
  80. 0  {ADMIN → skel/admin}/static/lang.js
  81. 0  {ADMIN → skel/admin}/test/admin_test.erl
  82. 0  {ADMIN → skel/admin}/view/access_denied.html
  83. 0  {ADMIN → skel/admin}/view/big_red_button.html
  84. 0  {ADMIN → skel/admin}/view/create.html
  85. 0  {ADMIN → skel/admin}/view/create_lang.html
  86. 0  {ADMIN → skel/admin}/view/delete.html
  87. 0  {ADMIN → skel/admin}/view/delete_lang.html
  88. 0  {ADMIN → skel/admin}/view/error.html
  89. 0  {ADMIN → skel/admin}/view/lang.html
  90. 0  {ADMIN → skel/admin}/view/model.html
  91. 0  {ADMIN → skel/admin}/view/record.html
  92. 0  { → skel}/boss.config
  93. 0  { → skel}/controller/hello_controller.erl
  94. 0  { → skel}/mail/mail_controller.erl
  95. 0  { → skel}/mail/view/test_message.html
  96. 0  { → skel}/mail/view/test_message.txt
  97. 0  { → skel}/model/greeting.erl
  98. +3 −0  skel/start-dev.sh
  99. 0  { → skel}/start-server.bat
  100. +3 −0  skel/start.sh
  101. 0  {DOC/templates → skel/static}/chicago-boss.png
  102. 0  { → skel}/static/favicon.ico
  103. 0  { → skel}/test/mail_test.erl
  104. 0  { → skel}/view/hello/world.html
  105. 0  {SRC → src2}/aleppo/aleppo.erl
  106. +321 −321 {SRC → src2}/aleppo/aleppo_parser.erl
  107. 0  {SRC → src2}/aleppo/aleppo_parser.yrl
  108. +15 −0 src2/boss.app.src
  109. 0  {SRC → src2}/boss/boss.erl
  110. 0  {SRC → src2}/boss/boss_app.erl
  111. 0  {SRC → src2}/boss/boss_assert.erl
  112. +13 −1 {SRC → src2}/boss/boss_compiler.erl
  113. 0  {SRC → src2}/boss/boss_db.erl
  114. 0  {SRC → src2}/boss/boss_db_adapter.erl
  115. 0  {SRC → src2}/boss/boss_db_controller.erl
  116. 0  {SRC → src2}/boss/boss_db_pt.erl
  117. 0  {SRC → src2}/boss/boss_db_sup.erl
  118. 0  {SRC → src2}/boss/boss_db_test.erl
  119. 0  {SRC → src2}/boss/boss_db_test_app.erl
  120. +2 −1  {SRC → src2}/boss/boss_doc.erl
  121. +2 −2 {SRC → src2}/boss/boss_files.erl
  122. 0  {SRC → src2}/boss/boss_flash.erl
  123. 0  {SRC → src2}/boss/boss_lang.erl
  124. +65 −52 {SRC → src2}/boss/boss_load.erl
  125. 0  {SRC → src2}/boss/boss_mail.erl
  126. 0  {SRC → src2}/boss/boss_mail_controller.erl
  127. 0  {SRC → src2}/boss/boss_mail_driver_mock.erl
  128. 0  {SRC → src2}/boss/boss_mail_driver_smtp.erl
  129. 0  {SRC → src2}/boss/boss_mail_sup.erl
  130. 0  {SRC → src2}/boss/boss_mq.erl
  131. 0  {SRC → src2}/boss/boss_mq_controller.erl
  132. 0  {SRC → src2}/boss/boss_mq_sup.erl
  133. +5 −3 {SRC → src2}/boss/boss_record_compiler.erl
  134. 0  {SRC → src2}/boss/boss_record_lib.erl
  135. 0  {SRC → src2}/boss/boss_session.erl
  136. 0  {SRC → src2}/boss/boss_session_adapter.erl
  137. 0  {SRC → src2}/boss/boss_session_controller.erl
  138. 0  {SRC → src2}/boss/boss_session_sup.erl
  139. 0  {SRC → src2}/boss/boss_session_test.erl
  140. 0  {SRC → src2}/boss/boss_session_test_app.erl
  141. 0  {SRC → src2}/boss/boss_sup.erl
  142. 0  {SRC → src2}/boss/boss_test.erl
  143. 0  {SRC → src2}/boss/boss_translator.erl
  144. 0  {SRC → src2}/boss/boss_translator_app.erl
  145. 0  {SRC → src2}/boss/boss_translator_controller.erl
  146. 0  {SRC → src2}/boss/boss_translator_sup.erl
  147. +2 −3 {SRC → src2}/boss/boss_web_controller.erl
  148. 0  {SRC → src2}/boss/boss_web_test.erl
  149. 0  {SRC → src2}/boss/db_adapters/boss_db_adapter_mnesia.erl
  150. 0  {SRC → src2}/boss/db_adapters/boss_db_adapter_mock.erl
  151. 0  {SRC → src2}/boss/db_adapters/boss_db_adapter_mongodb.erl
  152. 0  {SRC → src2}/boss/db_adapters/boss_db_adapter_mysql.erl
  153. 0  {SRC → src2}/boss/db_adapters/boss_db_adapter_pgsql.erl
  154. 0  {SRC → src2}/boss/db_adapters/boss_db_adapter_tyrant.erl
  155. 0  {SRC → src2}/boss/db_adapters/test_config/mock.config
  156. 0  {SRC → src2}/boss/db_adapters/test_config/mongodb.config
  157. 0  {SRC → src2}/boss/db_adapters/test_config/mysql.config
  158. 0  {SRC → src2}/boss/db_adapters/test_config/pgsql.config
  159. 0  {SRC → src2}/boss/db_adapters/test_config/tyrant.config
  160. 0  {SRC → src2}/boss/db_adapters/test_models/boss_db_test_model.erl
  161. 0  {SRC → src2}/boss/db_adapters/test_models/boss_db_test_parent_model.erl
  162. 0  {SRC → src2}/boss/db_adapters/test_sql/mysql.sql
  163. 0  {SRC → src2}/boss/db_adapters/test_sql/pgsql.sql
  164. 0  {SRC → src2}/boss/inflector.erl
  165. 0  {SRC → src2}/boss/mq_adapters/boss_mq_adapter_mock.erl
  166. 0  {SRC → src2}/boss/session_adapters/boss_session_adapter_ets.erl
  167. 0  {SRC → src2}/boss/session_adapters/boss_session_adapter_mnesia.erl
  168. 0  {SRC → src2}/boss/session_adapters/test_config/ets.config
  169. 0  {SRC → src2}/boss/session_adapters/test_config/mnesia.config
  170. 0  {SRC/bson/src → src2/bson}/bson.erl
  171. 0  {SRC/bson/src → src2/bson}/bson_binary.erl
  172. 0  {SRC/bson/src → src2/bson}/bson_tests.erl
  173. 0  {SRC → src2}/epgsql/pgsql.erl
  174. 0  {SRC → src2}/epgsql/pgsql_binary.erl
  175. 0  {SRC → src2}/epgsql/pgsql_connection.erl
  176. 0  {SRC → src2}/epgsql/pgsql_fdatetime.erl
  177. 0  {SRC → src2}/epgsql/pgsql_idatetime.erl
  178. 0  {SRC → src2}/epgsql/pgsql_sock.erl
  179. 0  {SRC → src2}/epgsql/pgsql_types.erl
  180. 0  {SRC → src2}/erlydtl/erlydtl.erl
  181. 0  {SRC → src2}/erlydtl/erlydtl_compiler.erl
  182. 0  {SRC → src2}/erlydtl/erlydtl_dateformat.erl
  183. 0  {SRC → src2}/erlydtl/erlydtl_deps.erl
  184. 0  {SRC → src2}/erlydtl/erlydtl_filters.erl
  185. 0  {SRC → src2}/erlydtl/erlydtl_i18n.erl
  186. 0  {SRC → src2}/erlydtl/erlydtl_parser.erl
  187. 0  {SRC → src2}/erlydtl/erlydtl_parser.yrl
  188. 0  {SRC → src2}/erlydtl/erlydtl_runtime.erl
  189. 0  {SRC → src2}/erlydtl/erlydtl_scanner.erl
  190. 0  {SRC → src2}/erlydtl/i18n/po_scanner.erl
  191. 0  {SRC → src2}/gen_smtp/binstr.erl
  192. 0  {SRC → src2}/gen_smtp/gen_smtp_client.erl
  193. 0  {SRC → src2}/gen_smtp/mimemail.erl
  194. 0  {SRC → src2}/gen_smtp/smtp_util.erl
  195. 0  {SRC → src2}/gen_smtp/socket.erl
  196. 0  {SRC → src2}/medici/medici.erl
  197. 0  {SRC → src2}/medici/medici.hrl
  198. 0  {SRC → src2}/medici/medici_app.erl
  199. 0  {SRC → src2}/medici/medici_conn.erl
  200. 0  {SRC → src2}/medici/medici_conn_sup.erl
  201. 0  {SRC → src2}/medici/medici_controller.erl
  202. 0  {SRC → src2}/medici/medici_native_conn.erl
  203. 0  {SRC → src2}/medici/medici_native_controller.erl
  204. 0  {SRC → src2}/medici/medici_port_srv.erl
  205. 0  {SRC → src2}/medici/medici_port_sup.erl
  206. 0  {SRC → src2}/medici/medici_sup.erl
  207. 0  {SRC → src2}/medici/principe.erl
  208. 0  {SRC → src2}/medici/principe.hrl
  209. 0  {SRC → src2}/medici/principe_table.erl
  210. 0  {SRC → src2}/misultin/misultin.erl
  211. 0  {SRC → src2}/misultin/misultin_http.erl
  212. 0  {SRC → src2}/misultin/misultin_req.erl
  213. 0  {SRC → src2}/misultin/misultin_socket.erl
  214. 0  {SRC → src2}/misultin/misultin_utility.erl
  215. 0  {SRC → src2}/misultin/misultin_websocket.erl
  216. 0  {SRC → src2}/misultin/misultin_ws.erl
  217. 0  {SRC → src2}/mochiweb/Makefile
  218. 0  {SRC → src2}/mochiweb/internal.hrl
  219. 0  {SRC → src2}/mochiweb/mochifmt.erl
  220. 0  {SRC → src2}/mochiweb/mochifmt_records.erl
  221. 0  {SRC → src2}/mochiweb/mochifmt_std.erl
  222. 0  {SRC → src2}/mochiweb/mochiglobal.erl
  223. 0  {SRC → src2}/mochiweb/mochihex.erl
  224. 0  {SRC → src2}/mochiweb/mochijson.erl
  225. 0  {SRC → src2}/mochiweb/mochijson2.erl
  226. 0  {SRC → src2}/mochiweb/mochilists.erl
  227. 0  {SRC → src2}/mochiweb/mochinum.erl
  228. 0  {SRC → src2}/mochiweb/mochitemp.erl
  229. 0  {SRC → src2}/mochiweb/mochiutf8.erl
  230. 0  {SRC → src2}/mochiweb/mochiweb.erl
  231. 0  {SRC → src2}/mochiweb/mochiweb_acceptor.erl
  232. 0  {SRC → src2}/mochiweb/mochiweb_app.erl
  233. 0  {SRC → src2}/mochiweb/mochiweb_charref.erl
  234. 0  {SRC → src2}/mochiweb/mochiweb_cookies.erl
  235. 0  {SRC → src2}/mochiweb/mochiweb_cover.erl
  236. 0  {SRC → src2}/mochiweb/mochiweb_echo.erl
  237. 0  {SRC → src2}/mochiweb/mochiweb_headers.erl
  238. 0  {SRC → src2}/mochiweb/mochiweb_html.erl
  239. 0  {SRC → src2}/mochiweb/mochiweb_http.erl
  240. 0  {SRC → src2}/mochiweb/mochiweb_io.erl
  241. 0  {SRC → src2}/mochiweb/mochiweb_mime.erl
  242. 0  {SRC → src2}/mochiweb/mochiweb_multipart.erl
  243. 0  {SRC → src2}/mochiweb/mochiweb_request.erl
  244. 0  {SRC → src2}/mochiweb/mochiweb_response.erl
  245. 0  {SRC → src2}/mochiweb/mochiweb_skel.erl
  246. 0  {SRC → src2}/mochiweb/mochiweb_socket.erl
  247. 0  {SRC → src2}/mochiweb/mochiweb_socket_server.erl
  248. 0  {SRC → src2}/mochiweb/mochiweb_sup.erl
  249. 0  {SRC → src2}/mochiweb/mochiweb_util.erl
  250. 0  {SRC → src2}/mochiweb/reloader.erl
  251. 0  {SRC/mongodb/src → src2/mongodb}/mongo.erl
  252. +1 −1  {SRC/mongodb/src → src2/mongodb}/mongo_connect.erl
  253. 0  {SRC/mongodb/src → src2/mongodb}/mongo_cursor.erl
  254. +1 −1  {SRC/mongodb/src → src2/mongodb}/mongo_protocol.erl
  255. 0  {SRC/mongodb/src → src2/mongodb}/mongo_query.erl
  256. 0  {SRC/mongodb/src → src2/mongodb}/mongodb_app.erl
  257. 0  {SRC/mongodb/src → src2/mongodb}/mongodb_tests.erl
  258. 0  {SRC/mongodb/src → src2/mongodb}/mvar.erl
  259. 0  {SRC → src2}/mysql/mysql.erl
  260. 0  {SRC → src2}/mysql/mysql_auth.erl
  261. 0  {SRC → src2}/mysql/mysql_conn.erl
  262. 0  {SRC → src2}/mysql/mysql_recv.erl
  263. 0  {SRC → src2}/overview.edoc
  264. 0  {SRC → src2}/simple_bridge/misultin_bridge_modules/misultin_request_bridge.erl
  265. 0  {SRC → src2}/simple_bridge/misultin_bridge_modules/misultin_response_bridge.erl
  266. 0  {SRC → src2}/simple_bridge/mochiweb_bridge_modules/mochiweb_request_bridge.erl
  267. 0  {SRC → src2}/simple_bridge/mochiweb_bridge_modules/mochiweb_response_bridge.erl
  268. 0  {SRC → src2}/simple_bridge/simple_bridge.erl
  269. 0  {SRC → src2}/simple_bridge/simple_bridge_multipart.erl
  270. 0  {SRC → src2}/simple_bridge/simple_bridge_request.erl
  271. 0  {SRC → src2}/simple_bridge/simple_bridge_request_wrapper.erl
  272. 0  {SRC → src2}/simple_bridge/simple_bridge_response.erl
  273. 0  {SRC → src2}/simple_bridge/simple_bridge_response_wrapper.erl
  274. 0  {SRC → src2}/smart_exceptions/mapform0.erl
  275. 0  {SRC → src2}/smart_exceptions/smart_exceptions.erl
View
90 DOC/api-config.html
@@ -1,90 +0,0 @@
-<html>
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8">
- </head>
- <body>
- <link rel="stylesheet" type="text/css" href="/stylesheets/boss.css" />
-
-<div style="text-align: center; font-style: italic;">
-<p>The Chicago Boss API is mostly stable, but still might change before 1.0.</p>
-</div>
-<div class="subnav">
-
- <a href="api-db.html">BossDB</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-record.html">Models</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-controller.html">Web Controllers</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-mq.html">BossMQ (Comet)</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-session.html">Sessions</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-mail-controller.html">Mail</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-view.html">Templates</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-test.html">Tests</a>
-
-</div>
-<div style="padding-top: 20px;">
-
-<p>All configuration takes place in <code>boss.config</code> in your project directory. Valid configuration options are:</p>
-<ul>
- <li><code>assume_locale</code> - The presumed locale of translatable strings. Defaults to "en".</li>
- <li><code>db_host</code> - The hostname of the database. Defaults to "localhost".</li>
- <li><code>db_port</code> - The port of the database. Defaults to 1978.</li>
- <li><code>db_username</code> - The username used for connecting to the database (if needed).</li>
- <li><code>db_password</code> - The password used for connecting to the database (if needed).</li>
- <li><code>db_database</code> - The name of the database to connect to (if needed).</li>
- <li><code>db_adapter</code> - The database adapter to use. Valid values are:
- <ul>
- <li><code>mock</code> - In-memory (non-persistent) database, useful for testing</li>
- <li><code>mnesia</code> - Mnesia</li>
- <li><code>mysql</code> - MySQL</li>
- <li><code>pgsql</code> - PostgreSQL</li>
- <li><code>tyrant</code> - Tokyo Tyrant</li>
- </ul></li>
- <li><code>default_action</code> - The action to call if none is specified. Defaults to "index"</li>
- <li><code>default_actions</code> - A proplist of default actions to call if none is specified, keyed by controller name.</li>
- <li><code>front_page</code> - The {Controller, Action} pair to be used on the home page. Defaults to <code>{"hello", "world"}</code>.</li>
- <li><code>log_dir</code> - Directory in which to keep log files. Location is relative to the project directory. Defaults to "log".</li>
- <li><code>mail_driver</code> - The email delivery driver to use. Valid values are:
- <ul>
- <li><code>boss_mail_driver_smtp</code> - SMTP delivery. If <code>mail_relay</code> is present, it is used as a relay, otherwise direct delivery is attempted.</li>
- <li><code>boss_mail_driver_mock</code> - A black hole, useful for testing.</li>
- </ul></li>
- <li><code>mail_relay</code> - The relay server for SMTP mail deliveries.</li>
- <li><code>port</code> - The port to run the server on. Defaults to 8001.</li>
- <li><code>server</code> - The HTTP server to use. Valid values are:
- <ul>
- <li><code>mochiweb</code> - The <a href="http://code.google.com/p/mochiweb/">Mochiweb</a> Web Server</li>
- <li><code>misultin</code> - The <a href="http://code.google.com/p/misultin/">Misultin</a> Web Server</li>
- </ul>
- <li><code>session_adapter</code> Selects the session driver to use. Valid values:</li>
- <ul>
- <li><code>ets</code> (default)</li>
- <li><code>mnesia</code></li>
- </ul>
- <li><code>session_key</code>: Cookie key for sessions. Defaults to "_boss_session"</li>
- <li><code>session_exp_time</code>: Expiration time for the session cookie. Defaults to 525600</li>
- <li><code>session_mnesia_nodes</code>: (optional, Mnesia sessions only) - List of Mnesia nodes, defaults to node()</li>
-</ul>
-
-</div>
-</body>
-</html>
View
253 DOC/api-controller.html
@@ -1,253 +0,0 @@
-<html>
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8">
- </head>
- <body>
- <link rel="stylesheet" type="text/css" href="/stylesheets/boss.css" />
-
-<div style="text-align: center; font-style: italic;">
-<p>The Chicago Boss API is mostly stable, but still might change before 1.0.</p>
-</div>
-<div class="subnav">
-
- <a href="api-db.html">BossDB</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-record.html">Models</a>
-
- &nbsp; | &nbsp;
-
- <strong>Web Controllers</strong>
-
- &nbsp; | &nbsp;
-
- <a href="api-mq.html">BossMQ (Comet)</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-session.html">Sessions</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-mail-controller.html">Mail</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-view.html">Templates</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-test.html">Tests</a>
-
-</div>
-<div style="padding-top: 20px;">
-
-<p style="font-size: 14px;"><em>Jump to:</em>
-&nbsp; <a href="#auth">Authorization</a>
-&nbsp; <a href="#return_values">Return values</a>
-&nbsp; <a href="#filter">Post-processing</a>
-&nbsp; <a href="#simplebridge">SimpleBridge request object</a></p>
-<p>Chicago Boss associates each URL with a function of a controller.
-The URL <nobr>/foo/bar</nobr> will call the function <code>foo_controller:bar</code>.
-Each controller module should go into your project's controller/ directory and the file name should end with "_controller.erl".
-Helper functions should go into your project's lib/ directory.
-Controllers should take one parameter, the <a href="#simplebridge">SimpleBridge request object</a>. Declare it like:</p>
-<div class="code">
- <span class="attr">-module</span>(my_controller, [Req]).
-</div>
-<p>Each exported controller function takes two or three arguments:</p>
-<ul>
- <li>First argument: the HTTP request method as an atom, e.g. <code>'GET'</code> or <code>'POST'</code></li>
- <li>Second argument: the list of slash-separated tokens after the action name in the URL.</li>
- <li>Third argument (optional): the result of a function named <code>before_</code> in the controller</li>
-</ul>
-
-<p>Example function clauses:</p>
-
-<div class="code">
-<span class="comment">% GET /blog/view</span><br />
-view(<span class="atom">'GET'</span>, []) -&gt;<br />
-&nbsp;&nbsp;&nbsp;&nbsp;...<br />
-<span class="comment">% GET /blog/view/1234</span><br />
-view(<span class="atom">'GET'</span>, [Id]) -&gt;<br />
-&nbsp;&nbsp;&nbsp;&nbsp;...<br />
-<span class="comment">% GET /blog/view/tag/funny</span><br />
-view(<span class="atom">'GET'</span>, [<span class="string">"tag"</span>, Tag]) -&gt;<br />
-&nbsp;&nbsp;&nbsp;&nbsp;...<br />
-<span class="comment">% GET /blog/view/tag/funny/author/saint-paul</span><br />
-view(<span class="atom">'GET'</span>, [<span class="string">"tag"</span>, Tag, <span class="string">"author"</span>, AuthorName]) -&gt;<br />
-&nbsp;&nbsp;&nbsp;&nbsp;...<br />
-<span class="comment">% GET /blog/view/2009/08</span><br />
-view(<span class="atom">'GET'</span>, [Year, Month]) -&gt;<br />
-&nbsp;&nbsp;&nbsp;&nbsp;...<br />
-</div>
-
-<a name="auth"></a>
-<h3>Authorization</h3>
-
-<p>If an action takes three arguments, then the function <code>before_/1</code> in your controller will be passed the action name as a string and should return one of:</P>
-
-<div class="code">
- {ok, ExtraInfo}
-</div>
-
-<p><code>ExtraInfo</code> will be passed as the third argument to the action, and as a variable called "before_" to the templates.</p>
-
-<div class="code">
- {redirect, Location<span class="typevar">::string()</span>}
-</div>
-
-<p>Do not execute the action. Instead, perform a 302 redirect to <code>Location</code>.</p>
-
-<p>Probably most common before_ looks like:</p>
-
-<div class="code">
-before_(_) -&gt;<br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="function">my_user_lib</span>:<span class="function">require_login</span>(Req).
-</div>
-
-<p>Which might return a tuple of user credential or else redirect to a login page. This way, if you want to require a login to a set of actions, just give those actions a <code>User</code> argument, and the actions will be login protected and have access to the <code>User</code> variable.</p>
-
-<br />
-<a name="return_values"></a>
-<h3>Return values</h3>
-
-<p>Whether or not it takes a third argument, a controller action should return with one of the following:</p>
-
-<div class="code">
- ok
-</div>
-<p>The template will be rendered without any variables.</p>
-<div class="code">
- {ok, Variables<span class="typevar">::proplist()</span>}
-</div>
-<p><code>Variables</code> will be passed into the associated <a href="api-view.html#nav">Django template</a>.</p>
-
-<div class="code">
- {ok, Variables<span class="typevar">::proplist()</span>, Headers<span class="typevar">::proplist()</span>}
-</div>
-
-<p><code>Variables</code> will be passed into the associated Django template, and <code>Headers</code> are HTTP headers you want to set (e.g., <code>Content-Type</code>).</p>
-
-<div class="code">
- {redirect, Location<span class="typevar">::string()</span>}
-</div>
-<p>Perform a 302 HTTP redirect to <code>Location</code>.</p>
-<div class="code">
- {redirect, Location<span class="typevar">::string()</span>, Headers<span class="typevar">::proplist()</span>}
-</div>
-<p>Perform a 302 HTTP redirect to <code>Location</code> and set additional HTTP <code>Headers</code>.</p>
-
-<div class="code">
- {action_other, OtherLocation}
-</div>
-
-<p><code>OtherLocation = {Controller<span class="typevar">::atom()</span>, Action<span class="typevar">::atom()</span>}</code></p>
-
-<p>Execute the specified controller action, but without performing an HTTP redirect.</p>
-
-<div class="code">
- {render_other, OtherLocation}
-</div>
-<p><code>OtherLocation = {Controller<span class="typevar">::atom()</span>, Action<span class="typevar">::atom()</span>}</code></p>
-
-<p>Render the view from <code>OtherLocation</code>, but don't actually execute the associated controller action.</p>
-
-<div class="code">
- {render_other, OtherLocation, Variables}
-</div>
-
-<p><code>OtherLocation = {Controller<span class="typevar">::atom()</span>, Action<span class="typevar">::atom()</span>}</code></p>
-
-<p>Render the view from <code>OtherLocation</code> using <code>Variables</code>, but don't actually execute the associated controller action.</p>
-
-<div class="code">
- {output, Output<span class="typevar">::iolist()</span>}
-</div>
-
-<p>Skip views altogether and return <code>Output</code> to the client.</p>
-
-<div class="code">
- {output, Output<span class="typevar">::iolist()</span>, Headers<span class="typevar">::proplist()</span>}
-</div>
-
-<p>Skip views altogether and return <code>Output</code> to the client while setting additional HTTP <code>Headers</code>.</p>
-
-<div class="code">
- {json, Data<span class="typevar">::proplist()</span>}
-</div>
-
-<p>Return <code>Data</code> as a JSON object to the client. Performs appropriate serialization if the values in Data contain a BossRecord or a list of BossRecords.</p>
-
-<div class="code">
- {json, Data<span class="typevar">::proplist()</span>, Headers<span class="typevar">::proplist()</span>}
-</div>
-
-<p>Return <code>Data</code> to the client as a JSON object while setting additional HTTP <code>Headers</code>.</p>
-
-<br />
-<a name="filter"></a>
-<h3>Post-processing</h3>
-<p>If it exists, a function called <code>after_</code> in your controller will be passed the result that is about to be returned to the client. The 'after_' function takes two or three arguments:</p>
-<ol>
- <li>The action name, as a string</li>
- <li>The HTTP result tuple</li>
- <li>The result of the before_ function, provided one exists</li>
-</ol>
-<p>The <code>after_</code> function should return a (possibly) modified HTTP result tuple. Result tuples may be one of:</p>
-<div class="code">
- {redirect, Location<span class="typevar">::string()</span>, Headers<span class="typevar">::proplist()</span>}
-</div>
-<p>Performs a 302 HTTP redirect to <code>Location</code> and sets additional HTTP <code>Headers</code>.</p>
-
-<div class="code">
- {ok, Payload<span class="typevar">::iolist()</span>, Headers<span class="typevar">::proplist()</span>}
-</div>
-<p>Returns a 200 OK response to the client with <code>Payload</code> as the HTTP body, and sets additional HTTP <code>Headers</code>.</p>
-<br />
-<a name="simplebridge"></a>
-<h3>SimpleBridge</h3>
-
-<p>Controller functions are passed a SimpleBridge request object (slightly modified for Boss's purposes). Useful functions in the request object include:</p>
-
-<div class="code">
- request_method() -&gt; atom()
-</div>
-
-<p>Get the request method, e.g. GET, POST, etc.</p>
-
-<div class="code">
- query_param( Key<span class="typevar">::string()</span> ) -&gt; string() | undefined
-</div>
-
-<p>Get the value of a given query string parameter (e.g. "?id=1234")</p>
-
-<div class="code">
- post_param( Key<span class="typevar">::string()</span> ) -&gt; string() | undefined
-</div>
-
-<p>Get the value of a given POST parameter</p>
-
-<div class="code">
- deep_param( [ Path<span class="typevar">::string()</span> ] ) -&gt; DeepParam | undefined
-</div>
-
-<p>Get the value of a given "deep" POST parameter.
-This function parses parameters that have numerical or labeled indices, such as "widget[4][name]", and returns either a value or a set of nested lists (for numerical indices) and proplists (for string indices).</p>
-
-<div class="code">
- header( Key<span class="typevar">::string()</span> ) -&gt; string() | undefined
-</div>
-
-<p>Get the value of a given HTTP request header</p>
-
-<div class="code">
- cookie( Key<span class="typevar">::string()</span> ) -&gt; string() | undefined
-</div>
-
-<p>Get the value of a given cookie.</p>
-
-</div>
-</body>
-</html>
View
374 DOC/api-db.html
@@ -1,374 +0,0 @@
-<html>
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8">
- </head>
- <body>
- <link rel="stylesheet" type="text/css" href="/stylesheets/boss.css" />
-
-<div style="text-align: center; font-style: italic;">
-<p>The Chicago Boss API is mostly stable, but still might change before 1.0.</p>
-</div>
-<div class="subnav">
-
- <strong>BossDB</strong>
-
- &nbsp; | &nbsp;
-
- <a href="api-record.html">Models</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-controller.html">Web Controllers</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-mq.html">BossMQ (Comet)</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-session.html">Sessions</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-mail-controller.html">Mail</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-view.html">Templates</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-test.html">Tests</a>
-
-</div>
-<div style="padding-top: 20px;">
-
-<p>BossDB is a database abstraction layer used for querying and updating the database. Currently Tokyo Tyrant, Mnesia, MySQL, and PostgreSQL are supported.</p>
-
-<h2>Conditions and Comparison Operators</h2>
-
-<p>The "find" and "count" functions each take a set of <code>Conditions</code>, which specify search criteria. Similar to Microsoft's <a href="http://msdn.microsoft.com/en-us/library/bb308959.aspx">LINQ</a>, the <code>Conditions</code> can use a special non-Erlang syntax for conciseness. This special syntax can't be compiled with Erlang's default compiler, so you'll have to let Boss compile your controllers which use it.</p>
-
-<p><code>Conditions</code> looks like a list, but each element in the list uses a notation very similar to abstract mathematical notation with a left-hand side (an atom corresponding to a record attribute), a single-character operator, and a right-hand side (values to match to the attribute). <strong>The mathematical operators are not all ASCII!</strong> You may want to copy-paste the UTF-8 operators below. As an alternative, you can also specify each condition with a 3-tuple with easier-to-type operator names.</p>
-
-<p>As a quick example, to count the number of people younger than 25 with occupation listed as "student" or "unemployed", you would use:</p>
-<div class="code">
- boss_db:count(person, <br />
- &nbsp;&nbsp;&nbsp;&nbsp;[age &lt; 25, occupation ∈ ["student", "unemployed"]]).
-</div>
-<p>This could also be written:</p>
-<div class="code">
- boss_db:count(person, <br />
- &nbsp;&nbsp;&nbsp;&nbsp;
- [{age, 'lt', 25},<br />
- &nbsp;&nbsp;&nbsp;&nbsp;
- &nbsp;&nbsp;&nbsp;&nbsp;
- {occupation, 'in', ["student", "unemployed"]}]).
-</div>
-
-<p>Valid conditions are:</p>
-
-<div class="code">
- key = Value
-</div>
-<div class="code">
- {key, 'equals', Value}
-</div>
-<p>The "key" attribute is exactly equal to Value.</p>
-
-<div class="code">
- key ≠ Value
-</div>
-<div class="code">
- {key, 'not_equals', Value}
-</div>
-<p>The "key" attribute is not exactly equal to Value.</p>
-
-<div class="code">
- key ∈ [Value1, Value2, ...]
-</div>
-<div class="code">
- {key, 'in', [Value1, Value2, ...]}
-</div>
-<p>The "key" attribute is equal to at least one element on the right-hand side.</p>
-
-<div class="code">
- key ∉ [Value1, Value2, ...]
-</div>
-<div class="code">
- {key, 'not_in', [Value1, Value2, ...]}
-</div>
-<p>The "key" attribute is not equal to any element on the right-hand side.</p>
-
-<div class="code">
- key ∈ {Min, Max}
-</div>
-<div class="code">
- {key, 'in', {Min, Max}}
-</div>
-<p>The "key" attribute is numerically between Min and Max.</p>
-
-<div class="code">
- key ∉ {Min, Max}
-</div>
-<div class="code">
- {key, 'not_in', {Min, Max}}
-</div>
-<p>The "key" attribute is not between Min and Max.</p>
-
-<div class="code">
- key ∼ RegularExpression
-</div>
-<div class="code">
- {key, 'matches', RegularExpression}
-</div>
-<p>The "key" attribute matches the RegularExpression.</p>
-
-<div class="code">
- key ≁ RegularExpression
-</div>
-<div class="code">
-{key, 'not_matches', RegularExpression}
-</div>
-<p>The "key" attribute does not match the RegularExpression.</p>
-
-<div class="code">
- key ∋ Token
-</div>
-<div class="code">
-{key, 'contains', Token}
-</div>
-<p>The "key" attribute contains Token.</p>
-
-<div class="code">
- key ∌ Token
-</div>
-<div class="code">
-{key, 'not_contains', Token}
-</div>
-<p>The "key" attribute does not contain Token.</p>
-
-<div class="code">
- key ⊇ [Token1, Token2, ...]
-</div>
-<div class="code">
-{key, 'contains_all', [Token1, Token2, ...]}
-</div>
-<p>The "key" attribute contains all tokens on the right-hand side.</p>
-
-<div class="code">
- key ⊉ [Token1, Token2, ...]
-</div>
-<div class="code">
-{key, 'not_contains_all', [Token1, Token2, ...]}
-</div>
-<p>The "key" attribute does not contain all tokens on the right-hand side.</p>
-
-<div class="code">
- key ∩ [Token1, Token2, ...]
-</div>
-<div class="code">
-{key, 'contains_any', [Token1, Token2, ...]}
-</div>
-<p>The "key" attribute contains at least one of the tokens on the right-hand side.</p>
-
-<div class="code">
- key ⊥ [Token1, Token2, ...]
-</div>
-<div class="code">
-{key, 'contains_none', [Token1, Token2, ...]}
-</div>
-<p>The "key" attribute contains none of the tokens on the right-hand side.</p>
-
-<div class="code">
- key &gt; Value
-</div>
-<div class="code">
-{key, 'gt', Value}
-</div>
-<p>The "key" attribute is greater than Value.</p>
-
-<div class="code">
- key &lt; Value
-</div>
-<div class="code">
-{key, 'lt', Value}
-</div>
-<p>The "key" attribute is less than Value.</p>
-
-<div class="code">
- key ≥ Value
-</div>
-<div class="code">
-{key, 'ge', Value}
-</div>
-<p>The "key" attribute is greater than or equal to Value.</p>
-
-<div class="code">
- key ≤ Value
-</div>
-<div class="code">
-{key, 'le', Value}
-</div>
-<p>The "key" attribute is less than or equal to Value.</p>
-
-
-<h2>Functions</h2>
-
-<p>Functions in the <code>boss_db</code> module include:</p>
-
-
-
-
-
-
-
-
-<div class="code">
- find(Id<span class="typevar">::string()</span>) -> BossRecord | {error, Reason}
-</div>
-<p>Find a BossRecord with the specified <code>Id</code>.</p>
-
-
-
-<div class="code">
- find(Type<span class="typevar">::atom()</span>, Conditions) -> [BossRecord]
-</div>
-<p>Query for BossRecords. Returns all BossRecords of type
- <code>Type</code> matching all of the given <code>Conditions</code></p>
-
-
-
-<div class="code">
- find(Type<span class="typevar">::atom()</span>, Conditions, Max<span class="typevar">::integer()</span> | many) -> [BossRecord]
-</div>
-<p>Query for BossRecords. Returns up to <code>Max</code> number of BossRecords of type
- <code>Type</code> matching all of the given <code>Conditions</code></p>
-
-
-
-<div class="code">
- find(Type<span class="typevar">::atom()</span>, Conditions, Max<span class="typevar">::integer()</span> | many, Skip<span class="typevar">::integer()</span>) -> [BossRecord]
-</div>
-<p>Query for BossRecords. Returns up to <code>Max</code> number of BossRecords of type
- <code>Type</code> matching all of the given <code>Conditions</code>, skipping the first <code>Skip</code> results.</p>
-
-
-
-<div class="code">
- find(Type<span class="typevar">::atom()</span>, Conditions, Max<span class="typevar">::integer()</span> | many, Skip<span class="typevar">::integer()</span>, Sort<span class="typevar">::atom()</span>) -> [BossRecord]
-</div>
-<p>Query for BossRecords. Returns up to <code>Max</code> number of BossRecords of type
- <code>Type</code> matching all of the given <code>Conditions</code>, skipping the
- first <code>Skip</code> results, sorted on the attribute <code>Sort</code>.</p>
-
-
-
-<div class="code">
- find(Type<span class="typevar">::atom()</span>, Conditions, Max<span class="typevar">::integer()</span> | many, Skip<span class="typevar">::integer()</span>, Sort<span class="typevar">::atom()</span>, SortOrder) -> [BossRecord]
-</div>
-<p>Query for BossRecords. Returns up to <code>Max</code> number of BossRecords of type
- Type matching all of the given <code>Conditions</code>, skipping the
- first <code>Skip</code> results, sorted on the attribute <code>Sort</code>. <code>SortOrder</code> specifies whether
- to treat values as strings or as numbers, and whether to sort ascending or
- descending. (<code>SortOrder</code> = <code>num_ascending</code>, <code>num_descending</code>, <code>str_ascending</code>, or
- <code>str_descending</code>)<br /><br />
-
- Note that Time attributes are stored internally as numbers, so you should
- sort them numerically.</p>
-
-
-
-<div class="code">
- count(Type<span class="typevar">::atom()</span>) -> <span class="typevar">::integer()</span>
-</div>
-<p>Count the number of BossRecords of type <code>Type</code> in the database.</p>
-
-
-
-<div class="code">
- count(Type<span class="typevar">::atom()</span>, Conditions) -> <span class="typevar">::integer()</span>
-</div>
-<p>Count the number of BossRecords of type <code>Type</code> in the database matching
- all of the given <code>Conditions</code>.</p>
-
-
-
-<div class="code">
- counter(Id<span class="typevar">::string()</span>) -> <span class="typevar">::integer()</span>
-</div>
-<p>Treat the record associated with <code>Id</code> as a counter and return its value.
- Returns 0 if the record does not exist, so to reset a counter just use
- "delete".</p>
-
-
-
-<div class="code">
- incr(Id<span class="typevar">::string()</span>) -> <span class="typevar">::integer()</span>
-</div>
-<p>Treat the record associated with <code>Id</code> as a counter and atomically increment its value by 1.</p>
-
-
-
-<div class="code">
- incr(Id<span class="typevar">::string()</span>, Increment<span class="typevar">::integer()</span>) -> <span class="typevar">::integer()</span>
-</div>
-<p>Treat the record associated with <code>Id</code> as a counter and atomically increment its value by <code>Increment</code>.</p>
-
-
-
-<div class="code">
- delete(Id<span class="typevar">::string()</span>) -> ok | {error, Reason}
-</div>
-<p>Delete the BossRecord with the given <code>Id</code>.</p>
-
-
-
-
-
-
-
-
-
-
-
-<div class="code">
- execute(Commands<span class="typevar">::iolist()</span>) -> RetVal
-</div>
-<p>Execute raw database commands on SQL databases</p>
-
-
-
-<div class="code">
- save_record(RecordBossRecord) -> {ok, SavedBossRecord} | {error, [ErrorMessages]}
-</div>
-<p>Save (that is, create or update) the given BossRecord in the database.
- Performs validation first; see <code>validate_record/1</code>.</p>
-
-
-
-<div class="code">
- validate_record(RecordBossRecord) -> ok | {error, [ErrorMessages]}
-</div>
-<p>Validate the given BossRecord without saving it in the database.
- <code>ErrorMessages</code> are generated from the list of tests returned by the BossRecord's
- <code>validation_tests/0</code> function (if defined). The returned list should consist of
- <code>{TestFunction, ErrorMessage}</code> tuples, where <code>TestFunction</code> is a fun of arity 0
- that returns <code>true</code> if the record is valid or <code>false</code> if it is invalid.
- <code>ErrorMessage</code> should be a (constant) string which will be included in <code>ErrorMessages</code>
- if the <code>TestFunction</code> returns <code>false</code> on this particular BossRecord.</p>
-
-
-
-<div class="code">
- type(Id<span class="typevar">::string()</span>) -> <span class="typevar">::atom()</span>
-</div>
-<p>Returns the type of the BossRecord with <code>Id</code>, or <code>undefined</code> if the record does not exist.</p>
-
-
-
-
-
-</div>
-</body>
-</html>
View
71 DOC/api-mail-controller.html
@@ -1,71 +0,0 @@
-<html>
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8">
- </head>
- <body>
- <link rel="stylesheet" type="text/css" href="/stylesheets/boss.css" />
-
-<div style="text-align: center; font-style: italic;">
-<p>The Chicago Boss API is mostly stable, but still might change before 1.0.</p>
-</div>
-<div class="subnav">
-
- <a href="api-db.html">BossDB</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-record.html">Models</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-controller.html">Web Controllers</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-mq.html">BossMQ (Comet)</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-session.html">Sessions</a>
-
- &nbsp; | &nbsp;
-
- <strong>Mail</strong>
-
- &nbsp; | &nbsp;
-
- <a href="api-view.html">Templates</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-test.html">Tests</a>
-
-</div>
-<div style="padding-top: 20px;">
-
-<p>Chicago Boss provides an API for sending emails using Django templates and custom controller logic. No SMTP configuration or server is necessary. Mail controller logic should go into <code>mail/mail_controller.erl</code> in your project directory, and templates should go into <code>mail/view/</code>. To send an email from a web controller, call:</p>
-<div class="code">
- boss_mail:send(foo_message, [Arg1, Arg2, ...])
-</div>
-<p>That will invoke <code>mail_controller:foo_message(Arg1, Arg2, ...)</code> and use the return value to populate the templates <code>mail/view/foo_message.txt</code> and <code>mail/view/foo_message.html</code>, then send the email in a background process. Your mail controller function should return:</div>
-<div class="code">
- {ok, FromAddress, ToAddress, HeaderFields} | <br />
- {ok, FromAddress, ToAddress, HeaderFields, Variables} | <br />
- nevermind
-</div>
-<p>If the return value is <code>nevermind</code>, no email will be sent. Otherwise,</p>
-<ul>
- <li><p><code>FromAddress</code> is the sender's email address. The address should <em>not</em> be in "friendly" form, i.e. "foo@example.com" is OK, but "Kai Foo &lt;foo@example.com&gt;" is not.</p></li>
- <li><p><code>ToAddress</code> is recipient's email address.</p></li>
- <li><p><code>HeaderFields</code> is a proplist of email header fields, e.g. <code>[{"From", "SECRETARY TO CHARLES TAYLOR &lt;mo@hotmail.com&gt;"}, {"Subject", "Unclaimed Lottery Winnings"}]</code>.
- If you want the From: and To: fields to appear in the message, you need to provide values here; they will not be taken from <code>FromAddress</code> and <code>ToAddress</code>.
- However, the header fields for Message-ID: and Date: will be populated automatically if not provided.
- </p></li>
- <li><p><code>Variables</code> (if present) will be passed to the associated Django template(s), which will form the body of the message.</p></li>
-</ul>
-<p><strong>Formatting.</strong> If templates ending only in ".txt" are present, the message will be sent in plain-text; if templates ending only in ".html" are present, the message will be sent as HTML; but if both ".txt" and ".html" templates are present, the message will be sent as a a MIME multi-part message with alternative plain-text and HTML representations.</p>
-<p><strong>I18n.</strong> To use Chicago Boss's i18n machinery in emails, specify the desired language in the "Content-Language" header field returned from the mail controller.</p>
-
-</div>
-</body>
-</html>
View
113 DOC/api-mq.html
@@ -1,113 +0,0 @@
-<html>
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8">
- </head>
- <body>
- <link rel="stylesheet" type="text/css" href="/stylesheets/boss.css" />
-
-<div style="text-align: center; font-style: italic;">
-<p>The Chicago Boss API is mostly stable, but still might change before 1.0.</p>
-</div>
-<div class="subnav">
-
- <a href="api-db.html">BossDB</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-record.html">Models</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-controller.html">Web Controllers</a>
-
- &nbsp; | &nbsp;
-
- <strong>BossMQ (Comet)</strong>
-
- &nbsp; | &nbsp;
-
- <a href="api-session.html">Sessions</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-mail-controller.html">Mail</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-view.html">Templates</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-test.html">Tests</a>
-
-</div>
-<div style="padding-top: 20px;">
-
-<p>BossMQ is an abstraction layer for channel-based messaging that can be used to implement real-time notifications (i.e. Comet). With BossMQ, any controller action can function as a long-polling endpoint simply by calling <code>boss_mq:pull/2</code>:</p>
-
-<div class="code">
-receive_chat('GET', []) -&gt;<br />
-&nbsp;&nbsp;{ok, Timestamp, Messages} = boss_mq:pull("my-channel", now)<br />
-&nbsp;&nbsp;{output, Messages}.
-</div>
-
-<p>The call to <code>pull/2</code> blocks until a message arrives on "my-channel". Because of Erlang's lightweight process model, you usually don't need to worry if <code>pull/2</code> takes a long time to complete.</p>
-
-<p>To send a message to a channel, you call <code>boss_mq:push/2</code>:</p>
-
-<div class="code">
- boss_mq:push("my-channel", &lt;&lt;"Secret Message"&gt;&gt;)
-</div>
-
-<p>Currently, only an in-memory message queue is supported, so all messaging must occur on the same CB server. Additional adapters will be added in the future to support more complex installations.</p>
-
-<h2>boss_mq API</h2>
-
-
-
-
-
-
-
-
-
-<div class="code">
- pull(Channel<span class="typevar">::string()</span>) -> {ok, Timestamp, [Message]} | {error, Reason}
-</div>
-<p>Pull messages from the specified <code>Channel</code>. If none are in the queue, blocks
- until a message is pushed to the queue.</p>
-
-
-
-<div class="code">
- pull(Channel<span class="typevar">::string()</span>, Since<span class="typevar">::tuple()</span> | now) -> {ok, Timestamp, [Message]} | {error, Reason}
-</div>
-<p>Pull messages from the specified <code>Channel</code> after <code>Since</code> (an <code>erlang:now/0</code> tuple). If no such messages
- are in the queue, blocks until a message is pushed to the queue.</p>
-
-
-
-<div class="code">
- poll(Channel<span class="typevar">::string()</span>) -> {ok, Timestamp, [Message]} | {error, Reason}
-</div>
-<p>Like <code>pull/1</code>, but returns immediately if no messages are in the queue.</p>
-
-
-
-<div class="code">
- poll(Channel<span class="typevar">::string()</span>, Since<span class="typevar">::tuple()</span>) -> {ok, Timestamp, [Message]} | {error, Reason}
-</div>
-<p>Like <code>pull/2</code>, but returns immediately if no matching messages are in the queue.</p>
-
-
-
-<div class="code">
- push(Channel<span class="typevar">::string()</span>, Message) -> ok
-</div>
-<p>Pushes a message to the specified <code>Channel</code>.</p>
-
-
-
-</div>
-</body>
-</html>
View
304 DOC/api-record.html
@@ -1,304 +0,0 @@
-<html>
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8">
- </head>
- <body>
- <link rel="stylesheet" type="text/css" href="/stylesheets/boss.css" />
-
-<div style="text-align: center; font-style: italic;">
-<p>The Chicago Boss API is mostly stable, but still might change before 1.0.</p>
-</div>
-<div class="subnav">
-
- <a href="api-db.html">BossDB</a>
-
- &nbsp; | &nbsp;
-
- <strong>Models</strong>
-
- &nbsp; | &nbsp;
-
- <a href="api-controller.html">Web Controllers</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-mq.html">BossMQ (Comet)</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-session.html">Sessions</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-mail-controller.html">Mail</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-view.html">Templates</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-test.html">Tests</a>
-
-</div>
-<div style="padding-top: 20px;">
-
-<p style="font-size: 14px;"><em>Jump to: </em>
-<a href="#instance">Generated instance methods</a>
-&nbsp; <a href="#associations">Associations (<code>belongs_to</code>, <code>has</code>)</a>
-&nbsp; <a href="#hooks">Save hooks</a>
-</p>
-<p>
-BossRecords are <em>specially compiled parameterized modules</em> that follow the "active record" pattern. BossRecords go into your project's model/ folder and will have functions generated for saving them into the database and for accessing related BossRecords. Important aspects of BossRecords:
-</p>
-
-<ul>
- <li><p>The first parameter of a BossRecord should always be called <code>Id</code>, and the
- other parameters should be CamelCased attributes of your data model.</p></li>
-
- <li><p>All parameters will be available as lower-case, underscored functions,
- e.g. <code>-module(foo, [Id, TheText])</code> will generate the getter functions
- <code>id()</code> and <code>the_text()</code>, and the setters <code>id(NewId)</code>
- and <code>the_text(NewText)</code>. Note that setters do not save the BossRecord.</p></li>
-
- <li><p>To auto-generate an ID, pass the atom <code>'id'</code> as the first parameter to <code>my_module:new</code>.</p></li>
-
- <li><p>Call <code>new</code> with strings, floats, integers, atoms, or binaries for all other parameters</p></li>
-
- <li><p>Parameters that end in "Time" (e.g., <code>CreationTime</code>, <code>UpdateTime</code>) should be
- passed either <code>erlang:now()</code> or a DateTime tuple.</p></li>
-
- <li><p>You can add your own functions to a BossRecord module, which will have access to the generated functions described below.</p></li>
-
- <li><p>To see the full API for a BossRecord called <code>foo</code> at any time during development, point your browser to /doc/foo on your dev server.</p></li>
-</ul>
-<a name="instance"></a>
-<h2>Generated functions</h2>
-<p>Generated instance functions of a BossRecord include:</p>
-
-
-
-
-<a name="save"></a>
-<div class="code">
- save() -> {ok, SavedBossRecord} | {error, [ErrorMessages]}
-</div>
-<p>
-
-Saves this <code>boss_record</code> record to the database. The returned record
- will have an auto-generated ID if the record's ID was set to 'id'.
- Performs validation first, returning <code>ErrorMessages</code> if validation fails. See <code>validate/0</code>.
-
-</p>
-
-
-
-<a name="validate"></a>
-<div class="code">
- validate() -> ok | {error, [ErrorMessages]}
-</div>
-<p>
-
-Validates this <code>boss_record</code> without saving to the database.
- Errors are generated from this model's <code>validation_tests/0</code> function (if defined),
- which should return a list of <code>{TestFunction, ErrorMessage}</code> tuples. For each test,
- <code>TestFunction</code> should be a fun of arity 0 that returns <code>true</code> if the record is valid
- or <code>false</code> if it is invalid. <code>ErrorMessage</code> should be a (constant) string that will be
- included in <code>ErrorMessages</code> if the associated <code>TestFunction</code> returns <code>false</code> on this
- particular <code>boss_record</code>.
-
-</p>
-
-
-
-<a name="attributes"></a>
-<div class="code">
- attributes(Proplist) -> BossRecord
-</div>
-<p>
-
-Set multiple record attributes at once. Does not save the record.
-
-</p>
-
-
-
-<a name="attributes"></a>
-<div class="code">
- attributes() -> [{Key<span class="typevar">::atom()</span>, Value<span class="typevar">::string()</span> | undefined}]
-</div>
-<p>
-
-A proplist of the <code>boss_record</code> parameters and their values.
-
-</p>
-
-
-
-<a name="attribute_names"></a>
-<div class="code">
- attribute_names() -> [<span class="typevar">::atom()</span>]
-</div>
-<p>
-
-A list of the lower-case <code>boss_record</code> parameters.
-
-</p>
-
-
-
-
-
-<a name="reset"></a>
-<div class="code">
- reset(Counter<span class="typevar">::atom()</span>) -> ok | {error, Reason}
-</div>
-<p>
-
-Reset a counter to zero
-
-</p>
-
-
-
-<a name="incr"></a>
-<div class="code">
- incr(Counter<span class="typevar">::atom()</span>) -> <span class="typevar">::integer()</span>
-</div>
-<p>
-
-Atomically increment a counter by 1.
-
-</p>
-
-
-
-<a name="incr"></a>
-<div class="code">
- incr(Counter<span class="typevar">::atom()</span>, Increment<span class="typevar">::integer()</span>) -> <span class="typevar">::integer()</span>
-</div>
-<p>
-
-Atomically increment a counter by the specified increment
-
-</p>
-
-
-
-<a name="belongs_to_names"></a>
-<div class="code">
- belongs_to_names() -> [{<span class="typevar">::atom()</span>}]
-</div>
-<p>
-
-Retrieve a list of the names of <code>belongs_to</code> associations.
-
-</p>
-
-
-
-<a name="belongs_to"></a>
-<div class="code">
- belongs_to() -> [{<span class="typevar">::atom()</span>, BossRecord}]
-</div>
-<p>
-
-Retrieve all of the <code>belongs_to</code> associations at once.
-
-</p>
-
-
-
-<a name="id"></a>
-<div class="code">
- id() -> Id
-</div>
-<p>
-
-Returns the value of <code>Id</code>
-
-</p>
-
-
-
-<a name="id"></a>
-<div class="code">
- id(Id<span class="typevar">::string()</span>) -> BossRecord
-</div>
-<p>
-
-Set the value of <code>Id</code>.
-
-</p>
-
-
-
-
-<p>Other getters and setters are generated based on the parameters of your BossRecord.</p>
-
-<a name="associations"></a>
-<h2>Associations</h2>
-
-<p>Special associations are generated from the following module attributes:</p>
-
-<div class="code">
- <span class="attr">-belongs_to</span>(foo).
-</div>
-
-<p>Requires a matching <code>FooId</code> in the parameter list. Adds a function <code>foo()</code> which returns the BossRecord (of any type, usually <code>foo</code>) with ID equal to the current BossRecord's <code>FooId</code>.</p>
-
-<div class="code">
- <span class="attr">-has</span>({bar, 1}).<br />
- <span class="attr">-has</span>({bars, Count}). % Count &gt; 1<br />
- <span class="attr">-has</span>({bars, many}). % alias for 1 million<br />
-</div>
-
-<p>Generates a function <code>bar()</code> or <code>bars()</code> which returns up to <code>Count</code> "bar" BossRecords with <code>FooId</code> equal to this BossRecord's ID. If Count is greater than 1, also creates <code>first_bar()</code> and <code>last_bar()</code> which return the first and last items in the association.</p>
-
-<p>When <code>Count</code> is not equal to 1, <code>has</code> can also take a proplist of options as the third element in the tuple:</p>
-<div class="code">
- <span class="attr">-has</span>({bars, many, [{sort_by, first_name}]}).</span>
-</div>
-<p>Valid options are:</p>
-<ul>
- <li><code>sort_by</code> - attribute to sort on. Defaults to 'id'</li>
- <li><code>sort_order</code> - whether to sort numerically or as a string, and ascending or descending. Valid values are:
- <ul>
- <li><code>str_ascending</code> - As string in dictionary order A-Z</li>
- <li><code>str_descending</code> - As string in reverse dictionary order Z-A</li>
- <li><code>num_ascending</code> - As number, low numbers first</li>
- <li><code>num_descending</code> - As number, high numbers first</li>
- </ul>
- <li><code>module</code> - If the assocation name is different than the underlying module, use this option to specify the underlying module.</li>
- <li><code>foreign_key</code> - If the associated module uses something unexpected for the foreign key, use this option to specify the foreign key (e.g. <code>person_id</code>).</li>
-</ul>
-
-<p>Note that Time and float attributes are stored internally as integers, so sort them with <code>num_ascending</code> or <code>num_descending</code>.</p>
-
-<p>The two above attributes work similar to <code>belongs_to</code> and <code>has_many/has_one</code> in Rails.</p>
-
-<div class="code">
- <span class="attr">-counter</span>(foo_counter).
-</div>
-
-<p>Generates a function <code>foo_counter()</code> which returns the value of the counter, initialized to zero. Each BossRecord may have an unlimited number of counters. Manipulate the counters with <code>reset</code> and <code>incr</code> above.</p>
-
-<p>SPECIAL NOTE: Everything in the Model directory will be compiled as a BossRecord rather than as a regular Erlang module; you don't need to do or declare anything special.</p>
-
-<a name="hooks"></a>
-<h2>Save hooks</h2>
-
-<p>You can specify logic to be run anytime a BossRecord is saved. Just define one or more of these functions in your module:</p>
-<ul>
- <li><code>before_create()</code> - executed just before a new BossRecord is saved to the database.</li>
- <li><code>before_update()</code> - executed just before an existing BossRecord is saved to the database.</li>
- <li><code>after_create()</code> - executed just after a new BossRecord is saved to the database.</li>
- <li><code>after_update()</code> - executed just after an existing BossRecord is saved to the database.</li>
-</ul>
-
-<p>Return values are ignored.</p>
-
-
-</div>
-</body>
-</html>
View
49 DOC/api-request.html
@@ -1,49 +0,0 @@
-<html>
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8">
- </head>
- <body>
- <link rel="stylesheet" type="text/css" href="/stylesheets/boss.css" />
-
-<div style="text-align: center; font-style: italic;">
-<p>The Chicago Boss API is mostly stable, but still might change before 1.0.</p>
-</div>
-<div class="subnav">
-
- <a href="api-db.html">BossDB</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-record.html">Models</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-controller.html">Web Controllers</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-mq.html">BossMQ (Comet)</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-session.html">Sessions</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-mail-controller.html">Mail</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-view.html">Templates</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-test.html">Tests</a>
-
-</div>
-<div style="padding-top: 20px;">
-
-
-</div>
-</body>
-</html>
View
113 DOC/api-session.html
@@ -1,113 +0,0 @@
-<html>
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8">
- </head>
- <body>
- <link rel="stylesheet" type="text/css" href="/stylesheets/boss.css" />
-
-<div style="text-align: center; font-style: italic;">
-<p>The Chicago Boss API is mostly stable, but still might change before 1.0.</p>
-</div>
-<div class="subnav">
-
- <a href="api-db.html">BossDB</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-record.html">Models</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-controller.html">Web Controllers</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-mq.html">BossMQ (Comet)</a>
-
- &nbsp; | &nbsp;
-
- <strong>Sessions</strong>
-
- &nbsp; | &nbsp;
-
- <a href="api-mail-controller.html">Mail</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-view.html">Templates</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-test.html">Tests</a>
-
-</div>
-<div style="padding-top: 20px;">
-
-<p>BossSession is a multiadapter session management. Currently ets and Mnesia (for distributed setups) are supported. For distributed setups, it is necessary to start Boss with a node name.</p>
-
-<p>BossSession is automatically started, so, by default an ets based session support is provided</p>
-
-<p>BossFlash is a utility on top of boss_session, you can store messages between requests, automatically populated to the view as {{ boss_flash }} and deleted from session after used.</p>
-
-<h2>boss_session</h2>
-
-<h3>get_session_data/1</h3>
-<div class="code">
-boss_session:get_session_data(Req) -&gt; list | {error, Reason}
-</div>
-<p>Get all session data associated to the Request.</p>
-
-<h3>get_session_data/2</h3>
-<div class="code">
-boss_session:get_session_data(Req, Key) -&gt; list | {error, Reason}
-</div>
-<p>Get session data for the Request for a given Key.</p>
-
-
-<h3>set_session_data/3</h3>
-<div class="code">
-set_session_data(Req,Key,Value) -&gt; ok | {error, Reason}
-</div>
-<p>Set session data for the Request with key Key and value Value.</p>
-
-<h3>delete_session/1</h3>
-<div class="code">
-delete_session(Req) -&gt; ok | {error, Reason}
-</div>
-<p>Delete all session data for the Request.</p>
-
-<h3>remove_session_data/2</h3>
-<div class="code">
-remove_session_data(Sid, Key) -&gt; ok | {error, Reason}
-</div>
-<p>Remove the Key from session data for the Request.</p>
-
-
-
-<h2>boss_flash</h2>
-
-<p>Add flash messages in the controller like:</p>
-
-<div class="code">
-boss_flash:add(Req, notice, "Flash Title", "Flash Message")
-</div>
-
-<p>Use the boss_flash var in the view, should render "notice - Flash Title - Flash Message":</p>
-<div class="code">
-{% if boss_flash %}
-{{ boss_flash.method }} - {{ boss_flash.title }} - {{ boss_flash.message }}
-{% endif %}
-</div>
-
-<h2>Functions</h2>
-
-<h3>boss_flash:add/3</h3>
-<p>add(Req, Type, Title)</p>
-
-<h3>boss_flash:add/4</h3>
-<p>add(Req, Type, Title, Message)</p>
-
-
-</div>
-</body>
-</html>
View
291 DOC/api-test.html
@@ -1,291 +0,0 @@
-<html>
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8">
- </head>
- <body>
- <link rel="stylesheet" type="text/css" href="/stylesheets/boss.css" />
-
-<div style="text-align: center; font-style: italic;">
-<p>The Chicago Boss API is mostly stable, but still might change before 1.0.</p>
-</div>
-<div class="subnav">
-
- <a href="api-db.html">BossDB</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-record.html">Models</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-controller.html">Web Controllers</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-mq.html">BossMQ (Comet)</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-session.html">Sessions</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-mail-controller.html">Mail</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-view.html">Templates</a>
-
- &nbsp; | &nbsp;
-
- <strong>Tests</strong>
-
-</div>
-<div style="padding-top: 20px;">
-
-<p style="font-size: 14px;"><em>Jump to: </em> <a href="#boss_test"><code>boss_test</code></a>
-&nbsp; <a href="#boss_assert">boss_assert</a></p>
-<p>Chicago Boss ships with a unique functional test framework, where tests are structured as trees of continuations. All assertions are performed in callbacks, and additional tests are also performed in callbacks. For more information on the design of Boss's functional tests, see <a href="http://www.evanmiller.org/functional-tests-as-a-tree-of-continuations.html">&#8220;Functional Tests As A Tree Of Continuations&#8221;</a>.</p>
-
-<p>To create a test suite, create a module in the test/ directory. Your test module should export a <code>start/0</code> function, which should invoke a function from the <code>boss_test</code> module. This function will in turn invoke functions in the <a href="#boss_assert"><code>boss_assert</code></a> module (to run assertions) and the <a href="#boss_test"><code>boss_test</code></a> module (to run further tests).</p>
-
-<p>When you are ready to run your test suite, type "make test" in your project directory.</p>
-
-<a name="boss_test"></a>
-<h3>boss_test</h3>
-<p>Functions in the <code>boss_test</code> issue HTTP requests to your web application (or check for emails sent by it). All functions in the <code>boss_test</code> module take the same two final arguments.</p>
-
-<p>Second to last, <code>Assertions</code> is a list of funs that must return a tuple <code>{Passed, ErrorMessage}</code>, where:
-<ul>
- <li><code>Passed</code> - a boolean indicating whether the test passed</li>
- <li><code>ErrorMessage</code> - an error message to be displayed if the test failed</li>
-</ul>
-<p>Each fun in <code>Assertions</code> takes a single argument, which is the response object of the current test. The response object will usually by an HTTP response, but in <code>boss_test:read_email/4</code>, it's an email.</p>
-
-<p>Most assertions will take the form of calls to <a href="#boss_assert"><code>boss_assert</code></a>, which is documented below.</p>
-
-<p>The last argument to any <code>boss_test</code> function is called <code>Continuations</code>. <code>Continuations</code> is a list of additional tests &mdash; funs that take the HTTP response value as their only argument, and use it to invoke additional tests from the <code>boss_test</code> module. Funs in <code>Continuations</code> should be preceded by a string label, e.g.:</p>
-<div class="code">
- boss_test:get_request("/", [], [], <br />
- &nbsp;&nbsp;&nbsp;[ "Click the register link", fun(Res) -&gt; ... end,<br />
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Click the copyright link", fun(Res) -&gt; ... end,
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;... ]).
-</div>
-<p>The key thing to understand about <code>Continuations</code> is that they are <em>performed in parallel</em>. Any database manipulations that occur in one continuation cannot affect sibling continuations.</p>
-
-<p>Functions available in the <code>boss_test</code> module include:</p>
-
-
-
-
-
-
-
-
-<div class="code">
- get_request(Url, Headers, Assertions, Continuations) -> [{NumPassed, ErrorMessages}]
-</div>
-<p>This test issues an HTTP GET request to <code>Url</code> (a path such as "/"
- -- no "http://" or domain name), passing in <code>RequestHeaders</code> to the
- server.</p>
-
-
-
-<div class="code">
- post_request(Url, Headers, Contents, Assertions, Continuations) -> [{NumPassed, ErrorMessages}]
-</div>
-<p>This test issues an HTTP POST request to <code>Url</code> (a path such as "/"
- -- no "http://" or domain name), passing in <code>RequestHeaders</code> to the
- server, and <code>Contents</code> as the request body.</p>
-
-
-
-<div class="code">
- follow_link(LinkName, Response, Assertions, Continuations) -> [{NumPassed, ErrorMessages}]
-</div>
-<p>This test looks for a link labeled <code>LinkName</code> in <code>Response</code> and issues
- an HTTP GET request to the associated URL. The label may be an "alt" attribute of a
- hyperlinked &lt;img&gt; tag.</p>
-
-
-
-<div class="code">
- follow_redirect(Response, Assertions, Continuations) -> [{NumPassed, ErrorMessages}]
-</div>
-<p>This test follows an HTTP redirect; that is, it issues a GET request to
- the URL specified by the "Location" header in <code>Response</code></p>
-
-
-
-<div class="code">
- submit_form(FormName, FormValues<span class="typevar">::proplist()</span>, Response, Assertions, Continuations) -> [{NumPassed, ErrorMessages}]
-</div>
-<p>This test inspects <code>Response</code> for an HTML form with a "name" attribute equal to <code>FormName</code>,
- and submits it using <code>FormValues</code>, a proplist with keys equal to the labels of form fields.
- (So all visible form fields should be labeled with a &lt;label&gt; HTML tag!)
- If a particular value is not specified, the form's default value is used.</p>
-
-
-
-<div class="code">
- read_email(ToAddress, Subject, Assertions, Continuations) -> [{NumPassed, ErrorMessages}]
-</div>
-<p>This test retrieves the most recent email sent by the application to <code>ToAddress</code> with
- subject equal to <code>Subject</code>.</p>
-
-
-
-
-
-<a name="boss_assert"></a>
-<h3>boss_assert</h3>
-<p>The <code>Assertions</code> list in a <code>boss_test</code> invocation will usually refer to functions in the <code>boss_assert</code> module. Available functions include:</p>
-
-
-<div class="code">
- http_ok(Response) -> {Passed, ErrorMessage}
-</div>
-<p>Compares the HTTP status code in <code>Response</code> to 200 (HTTP OK).</p>
-
-
-
-<div class="code">
- http_partial_content(Response) -> {Passed, ErrorMessage}
-</div>
-<p>Compares the HTTP status code in <code>Response</code> to 206 (HTTP Partial Content)</p>
-
-
-
-<div class="code">
- http_redirect(Response) -> {Passed, ErrorMessage}
-</div>
-<p>Compares the HTTP status code in <code>Response</code> to 302 (HTTP Found).</p>
-
-
-
-<div class="code">
- http_not_modified(Response) -> {Passed, ErrorMessage}
-</div>
-<p>Compares the HTTP status code in <code>Response</code> to 304 (HTTP Not Modified).</p>
-
-
-
-<div class="code">
- http_bad_request(Response) -> {Passed, ErrorMessage}
-</div>
-<p>Compares the HTTP status code in <code>Response</code> to 400 (HTTP Bad Request).</p>
-
-
-
-<div class="code">
- http_not_found(Response) -> {Passed, ErrorMessage}
-</div>
-<p>Compares the HTTP status code in <code>Response</code> to 404 (HTTP Not Found).</p>
-
-
-
-<div class="code">
- link_with_text(Text, Response) -> {Passed, ErrorMessage}
-</div>
-<p>Looks in <code>Response</code> for a link with text equal to <code>Text</code>.
- The text may be the inner text of an &lt;a&gt; tag, or the
- "alt" attribute of a hyperlinked &lt;img&gt; tag.
- <code>Response</code> may be an HTTP response, or an email.</p>
-
-
-
-<div class="code">
- tag_with_text(Tag, Text, Response) -> {Passed, ErrorMessage}
-</div>
-<p>Looks in <code>Response</code> for an HTML tag of type <code>Tag</code> with inner
- text equal to <code>Text</code>. <code>Response</code> may be an HTTP response, or an email.</p>
-
-
-
-<div class="code">
- header(Key, Value, Response) -> {Passed, ErrorMessage}
-</div>
-<p>Compares the <code>Key</code> header in <code>Response</code> (HTTP or email) to <code>Value</code>.</p>
-
-
-
-<div class="code">
- location_header(Url, Response) -> {Passed, ErrorMessage}
-</div>
-<p>Compares <code>Url</code> to the Location: header of <code>Response</code>.</p>
-
-
-
-<div class="code">
- content_language_header(ContentLanguage, Response) -> {Passed, ErrorMessage}
-</div>
-<p>Compares <code>ContentLanguage</code> to the Content-Language: header of <code>Response</code></p>
-
-
-
-<div class="code">
- content_type_header(ContentType, Response) -> {Passed, ErrorMessage}
-</div>
-<p>Compares <code>ContentType</code> to the Content-Type: header of <code>Response</code></p>
-
-
-
-<div class="code">
- from_header(FromAddress, Email) -> {Passed, ErrorMessage}
-</div>
-<p>Compares <code>FromAddress</code> to the From: header field in <code>Email</code></p>
-
-
-
-<div class="code">
- email_has_text(Email) -> {Passed, ErrorMessage}
-</div>
-<p>Checks whether <code>Email</code> contains a plain-text body.</p>
-
-
-
-<div class="code">
- email_has_html(Email) -> {Passed, ErrorMessage}
-</div>
-<p>Checks whether <code>Email</code> contains an HTML body.</p>
-
-
-
-<div class="code">
- email_is_text_only(Email) -> {Passed, ErrorMessage}
-</div>
-<p>Checks whether <code>Email</code> contains a plain-text body and not an HTML body.</p>
-
-
-
-<div class="code">
- email_is_html_only(Email) -> {Passed, ErrorMessage}
-</div>
-<p>Checks whether <code>Email</code> contains an HTML body and not a plain-text body.</p>
-
-
-
-<div class="code">
- email_is_multipart(Email) -> {Passed, ErrorMessage}
-</div>
-<p>Checks whether <code>Email</code> contains alternative text and HTML representations.</p>
-
-
-
-<div class="code">
- email_received(Email) -> {Passed, ErrorMessage}
-</div>
-<p>Checks whether <code>Email</code> exists</p>
-
-
-
-<div class="code">
- email_not_received(Email) -> {Passed, ErrorMessage}
-</div>
-<p>Checks whether <code>Email</code> is undefined</p>
-
-
-
-</div>
-</body>
-</html>
View
287 DOC/api-view.html
@@ -1,287 +0,0 @@
-<html>
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8">
- </head>
- <body>
- <link rel="stylesheet" type="text/css" href="/stylesheets/boss.css" />
-
-<div style="text-align: center; font-style: italic;">
-<p>The Chicago Boss API is mostly stable, but still might change before 1.0.</p>
-</div>
-<div class="subnav">
-
- <a href="api-db.html">BossDB</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-record.html">Models</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-controller.html">Web Controllers</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-mq.html">BossMQ (Comet)</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-session.html">Sessions</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-mail-controller.html">Mail</a>
-
- &nbsp; | &nbsp;
-
- <strong>Templates</strong>
-
- &nbsp; | &nbsp;
-
- <a href="api-test.html">Tests</a>
-
-</div>
-<div style="padding-top: 20px;">
-
-<p>Chicago Boss liked <a href="http://docs.djangoproject.com/en/dev/topics/templates/">Django's templating language</a> so much, he decided to steal it. Template files go in your project's view/ folder (in subdirectories that correspond to the controller name), and will have access to the variables you pass from your <a href="api-controller.html#nav">Controller</a>. The template file associated with the function <code>foo_controller:bar</code> will be view/foo/bar.html.</p>
-
-<p>Note: if you use the the <code>extends</code> tag, the file path should be relative to your project's view/ directory.</p>
-
-<p>Chicago Boss has support for the most common features of the Django Template Language, so many existing Django templates should work out of the box. Your templates will be compiled down to Erlang BEAM code using <a href="http://code.google.com/p/erlydtl/">ErlyDTL</a> to give you the fastest Erlang templates this side of Stockholm.</p>
-
-<p>The following Django filters are supported in Chicago Boss. Hopefully this list will grow over time.</p>
-
-<table style="margin-left: 80px; margin-top: 30px;">
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#add">add</a></td>
- <td>Adds a number to the value.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#addslashes">addslashes</a></td>
- <td>Adds slashes before quotes.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#capfirst">capfirst</a></td>
- <td>Capitalizes the first character of the value.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#center">center</a></td>
- <td>Centers the value in a field of a given width.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#cut">cut</a></td>
- <td>Removes all values of arg from the given string.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date">date</a></td>
- <td>Formats a date according to the given format.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#default">default</a></td>
- <td>If value evaluates to <code>false</code>, use given default.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#default_if_none">default_if_none</a></td>
- <td>If (and only if) value is <code>undefined</code>, use given default.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#divisibleby">divisibleby</a></td>
- <td>Returns <code>true</code> if the value is divisible by the argument.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#escapejs">escapejs</a></td>
- <td>Escapes characters for use in JavaScript strings.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#filesizeformat">filesizeformat</a></td>
- <td>Format the value like a human-readable file size.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#first">first</a></td>
- <td>Returns the first item in a list.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#fix_ampersands">fix_ampersands</a></td>
- <td>Replaces ampersands with & entities.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#force_escape">force_escape</a></td>
- <td>Applies HTML escaping to a string.</td>
- </tr>
-
-
-
-
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#get_digit">get_digit</a></td>
- <td>Given a whole number, returns the requested digit, where 1 is the right-most digit.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#join">join</a></td>
- <td>Joins a list with a given separator.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#last">last</a></td>
- <td>Returns the last item in a list.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#length">length</a></td>
- <td>Returns the length of the value.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#length_is">length_is</a></td>
- <td>Returns True iff the value's length is the argument.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#linebreaksbr">linebreaksbr</a></td>
- <td>Converts all newlines to HTML line breaks.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#ljust">ljust</a></td>
- <td>Left-aligns the value in a field of a given width.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#lower">lower</a></td>
- <td>Converts a string into all lowercase.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#phone2numeric">phone2numeric</a></td>
- <td>Converts a phone number (possibly containing letters) to its numerical equivalent.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#random">random</a></td>
- <td>Returns a random item from the given list.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#rjust">rjust</a></td>
- <td>Right-aligns the value in a field of a given width.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#slugify">slugify</a></td>
- <td>Converts to lowercase, removes non-word characters (alphanumerics and underscores) and converts spaces to hyphens.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#title">title</a></td>
- <td>Converts a string into titlecase.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#truncatewords">truncatewords</a></td>
- <td>Truncates a string after a certain number of words.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#upper">upper</a></td>
- <td>Converts a string into all uppercase.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#urlencode">urlencode</a></td>
- <td>Escapes a value for use in a URL.</td>
- </tr>
-
-
-
- <tr><td>
- <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#wordcount">wordcount</a></td>
- <td>Returns the number of words.</td>
- </tr>
-
-
-</table>
-<h2>Custom tags</h2>
-<p>If you repeated logic or template snippets, you can put helper templates into your project's view/lib/ directory. The variables appearing in helper templates must be supplied by the caller. For example, if you have a file called "view/lib/my_custom_tag.html" which uses a variable called "foo", you can invoke it from other templates like:</p>
-<div class="code">
- {% my_custom_tag foo="bar" %}
-</div>
-<p>String literals or variables may be passed as arguments to custom tags. Another option for factoring out repeated logic is to use ErlyDTL's "include" tag. The difference between using an "include" tag and custom tags is that "include" will have access to all variables currently in the caller's scope, whereas custom tags only have access to the variables explicitly passed in. (In addition, custom tags are compiled only once for the entire project, but included files are compiled for each template that includes it.)</p>
-
-</div>
-</body>
-</html>
View
49 DOC/api.html
@@ -1,49 +0,0 @@
-<html>
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8">
- </head>
- <body>
- <link rel="stylesheet" type="text/css" href="/stylesheets/boss.css" />
-
-<div style="text-align: center; font-style: italic;">
-<p>The Chicago Boss API is mostly stable, but still might change before 1.0.</p>
-</div>
-<div class="subnav">
-
- <a href="api-db.html">BossDB</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-record.html">Models</a>
-
- &nbsp; | &nbsp;
-
- <a href="api-controller.html">Web Controllers</a>
-