utopia 2.13.3 → 2.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (476) hide show
  1. checksums.yaml +4 -4
  2. data/bake/utopia/{yarn.rb → node.rb} +13 -5
  3. data/lib/utopia/command.rb +2 -2
  4. data/lib/utopia/command/site.rb +1 -1
  5. data/lib/utopia/content.rb +23 -19
  6. data/lib/utopia/content/link.rb +29 -34
  7. data/lib/utopia/content/links.rb +185 -123
  8. data/lib/utopia/content/markup.rb +1 -1
  9. data/lib/utopia/content/node.rb +15 -19
  10. data/lib/utopia/content/response.rb +5 -5
  11. data/lib/utopia/controller.rb +0 -17
  12. data/lib/utopia/controller/base.rb +23 -3
  13. data/lib/utopia/controller/respond.rb +50 -107
  14. data/lib/utopia/extensions/array_split.rb +2 -2
  15. data/lib/utopia/http.rb +3 -3
  16. data/lib/utopia/localization.rb +18 -10
  17. data/lib/utopia/middleware.rb +2 -2
  18. data/lib/utopia/path.rb +40 -36
  19. data/lib/utopia/redirection.rb +0 -2
  20. data/lib/utopia/responder.rb +76 -0
  21. data/lib/utopia/version.rb +1 -1
  22. data/setup/site/.gitignore +8 -7
  23. metadata +75 -607
  24. data/.codeclimate.yml +0 -5
  25. data/.gitignore +0 -8
  26. data/.rspec +0 -4
  27. data/.travis.yml +0 -28
  28. data/.yardopts +0 -2
  29. data/Gemfile +0 -28
  30. data/README.md +0 -92
  31. data/Rakefile +0 -33
  32. data/benchmark/call_vs_check.rb +0 -38
  33. data/benchmark/const_vs_hash.rb +0 -35
  34. data/benchmark/hash_vs_openstruct.rb +0 -54
  35. data/benchmark/string_vs_symbol.rb +0 -14
  36. data/benchmark/struct_vs_class.rb +0 -91
  37. data/docs/.nojekyll +0 -0
  38. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.apache.css +0 -6
  39. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.applescript.css +0 -5
  40. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.assembly.css +0 -8
  41. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.bash-script.css +0 -6
  42. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.bash.css +0 -10
  43. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.clang.css +0 -3
  44. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.css.css +0 -14
  45. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.diff.css +0 -16
  46. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.html.css +0 -5
  47. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.ocaml.css +0 -3
  48. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.protobuf.css +0 -2
  49. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.python.css +0 -6
  50. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.ruby.css +0 -2
  51. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.xml.css +0 -18
  52. data/docs/_components/jquery-syntax/base/jquery.syntax.core.css +0 -62
  53. data/docs/_components/jquery-syntax/base/jquery.syntax.editor.css +0 -6
  54. data/docs/_components/jquery-syntax/base/theme.js +0 -1
  55. data/docs/_components/jquery-syntax/bright/jquery.syntax.core.css +0 -27
  56. data/docs/_components/jquery-syntax/bright/theme.js +0 -1
  57. data/docs/_components/jquery-syntax/jquery.syntax.brush.apache.js +0 -41
  58. data/docs/_components/jquery-syntax/jquery.syntax.brush.applescript.js +0 -57
  59. data/docs/_components/jquery-syntax/jquery.syntax.brush.assembly.js +0 -37
  60. data/docs/_components/jquery-syntax/jquery.syntax.brush.bash-script.js +0 -67
  61. data/docs/_components/jquery-syntax/jquery.syntax.brush.bash.js +0 -33
  62. data/docs/_components/jquery-syntax/jquery.syntax.brush.basic.js +0 -51
  63. data/docs/_components/jquery-syntax/jquery.syntax.brush.clang.js +0 -89
  64. data/docs/_components/jquery-syntax/jquery.syntax.brush.csharp.js +0 -47
  65. data/docs/_components/jquery-syntax/jquery.syntax.brush.css.js +0 -80
  66. data/docs/_components/jquery-syntax/jquery.syntax.brush.diff.js +0 -24
  67. data/docs/_components/jquery-syntax/jquery.syntax.brush.go.js +0 -47
  68. data/docs/_components/jquery-syntax/jquery.syntax.brush.haskell.js +0 -45
  69. data/docs/_components/jquery-syntax/jquery.syntax.brush.html.js +0 -66
  70. data/docs/_components/jquery-syntax/jquery.syntax.brush.io.js +0 -45
  71. data/docs/_components/jquery-syntax/jquery.syntax.brush.java.js +0 -45
  72. data/docs/_components/jquery-syntax/jquery.syntax.brush.javascript.js +0 -40
  73. data/docs/_components/jquery-syntax/jquery.syntax.brush.kai.js +0 -29
  74. data/docs/_components/jquery-syntax/jquery.syntax.brush.lisp.js +0 -34
  75. data/docs/_components/jquery-syntax/jquery.syntax.brush.lua.js +0 -44
  76. data/docs/_components/jquery-syntax/jquery.syntax.brush.nginx.js +0 -31
  77. data/docs/_components/jquery-syntax/jquery.syntax.brush.ocaml.js +0 -73
  78. data/docs/_components/jquery-syntax/jquery.syntax.brush.ooc.js +0 -46
  79. data/docs/_components/jquery-syntax/jquery.syntax.brush.pascal.js +0 -51
  80. data/docs/_components/jquery-syntax/jquery.syntax.brush.perl5.js +0 -52
  81. data/docs/_components/jquery-syntax/jquery.syntax.brush.php-script.js +0 -48
  82. data/docs/_components/jquery-syntax/jquery.syntax.brush.php.js +0 -15
  83. data/docs/_components/jquery-syntax/jquery.syntax.brush.plain.js +0 -10
  84. data/docs/_components/jquery-syntax/jquery.syntax.brush.protobuf.js +0 -43
  85. data/docs/_components/jquery-syntax/jquery.syntax.brush.python.js +0 -44
  86. data/docs/_components/jquery-syntax/jquery.syntax.brush.ruby.js +0 -77
  87. data/docs/_components/jquery-syntax/jquery.syntax.brush.scala.js +0 -44
  88. data/docs/_components/jquery-syntax/jquery.syntax.brush.smalltalk.js +0 -29
  89. data/docs/_components/jquery-syntax/jquery.syntax.brush.sql.js +0 -31
  90. data/docs/_components/jquery-syntax/jquery.syntax.brush.super-collider.js +0 -57
  91. data/docs/_components/jquery-syntax/jquery.syntax.brush.swift.js +0 -55
  92. data/docs/_components/jquery-syntax/jquery.syntax.brush.trenni.js +0 -35
  93. data/docs/_components/jquery-syntax/jquery.syntax.brush.xml.js +0 -50
  94. data/docs/_components/jquery-syntax/jquery.syntax.brush.yaml.js +0 -29
  95. data/docs/_components/jquery-syntax/jquery.syntax.cache.js +0 -65
  96. data/docs/_components/jquery-syntax/jquery.syntax.core.js +0 -1098
  97. data/docs/_components/jquery-syntax/jquery.syntax.editor.js +0 -291
  98. data/docs/_components/jquery-syntax/jquery.syntax.js +0 -258
  99. data/docs/_components/jquery-syntax/jquery.syntax.min.js +0 -13
  100. data/docs/_components/jquery-syntax/paper/jquery.syntax.core.css +0 -31
  101. data/docs/_components/jquery-syntax/paper/theme.js +0 -1
  102. data/docs/_components/jquery/core.js +0 -482
  103. data/docs/_components/jquery/jquery.js +0 -10220
  104. data/docs/_components/jquery/jquery.min.js +0 -4
  105. data/docs/_components/jquery/jquery.min.map +0 -1
  106. data/docs/_components/jquery/jquery.slim.js +0 -8107
  107. data/docs/_components/jquery/jquery.slim.min.js +0 -4
  108. data/docs/_components/jquery/jquery.slim.min.map +0 -1
  109. data/docs/_static/icon.png +0 -0
  110. data/docs/_static/site.css +0 -205
  111. data/docs/_static/utopia-background.svg +0 -1
  112. data/docs/_static/utopia.svg +0 -1
  113. data/docs/code/Utopia.html +0 -517
  114. data/docs/code/Utopia/Basename.html +0 -654
  115. data/docs/code/Utopia/Bootstrap.html +0 -538
  116. data/docs/code/Utopia/Command.html +0 -213
  117. data/docs/code/Utopia/Command/Environment.html +0 -321
  118. data/docs/code/Utopia/Command/Server.html +0 -214
  119. data/docs/code/Utopia/Command/Server/Create.html +0 -222
  120. data/docs/code/Utopia/Command/Server/Environment.html +0 -236
  121. data/docs/code/Utopia/Command/Server/Update.html +0 -317
  122. data/docs/code/Utopia/Command/Setup.html +0 -145
  123. data/docs/code/Utopia/Command/Setup/Server.html +0 -298
  124. data/docs/code/Utopia/Command/Setup/Site.html +0 -180
  125. data/docs/code/Utopia/Command/Site.html +0 -285
  126. data/docs/code/Utopia/Command/Site/Create.html +0 -324
  127. data/docs/code/Utopia/Command/Site/Update.html +0 -407
  128. data/docs/code/Utopia/Command/Top.html +0 -279
  129. data/docs/code/Utopia/Content.html +0 -832
  130. data/docs/code/Utopia/Content/Document.html +0 -1822
  131. data/docs/code/Utopia/Content/Document/State.html +0 -1220
  132. data/docs/code/Utopia/Content/Link.html +0 -1286
  133. data/docs/code/Utopia/Content/Links.html +0 -847
  134. data/docs/code/Utopia/Content/MarkupParser.html +0 -881
  135. data/docs/code/Utopia/Content/MarkupParser/ParsedTag.html +0 -422
  136. data/docs/code/Utopia/Content/MarkupParser/UnbalancedTagError.html +0 -615
  137. data/docs/code/Utopia/Content/Namespace.html +0 -485
  138. data/docs/code/Utopia/Content/Node.html +0 -1188
  139. data/docs/code/Utopia/Content/Node/Context.html +0 -938
  140. data/docs/code/Utopia/Content/Response.html +0 -813
  141. data/docs/code/Utopia/Content/SymbolicHash.html +0 -419
  142. data/docs/code/Utopia/Content/Tag.html +0 -399
  143. data/docs/code/Utopia/Content/Tags.html +0 -136
  144. data/docs/code/Utopia/Content/Tags/ContentTag.html +0 -187
  145. data/docs/code/Utopia/Content/Tags/DeferredTag.html +0 -193
  146. data/docs/code/Utopia/Content/Tags/Library.html +0 -333
  147. data/docs/code/Utopia/Content/Tags/NodeTag.html +0 -193
  148. data/docs/code/Utopia/Content/UnbalancedTagError.html +0 -298
  149. data/docs/code/Utopia/ContentLength.html +0 -343
  150. data/docs/code/Utopia/Controller.html +0 -907
  151. data/docs/code/Utopia/Controller/Actions.html +0 -289
  152. data/docs/code/Utopia/Controller/Actions/Action.html +0 -984
  153. data/docs/code/Utopia/Controller/Actions/ClassMethods.html +0 -442
  154. data/docs/code/Utopia/Controller/Base.html +0 -1216
  155. data/docs/code/Utopia/Controller/Respond.html +0 -293
  156. data/docs/code/Utopia/Controller/Respond/ClassMethods.html +0 -236
  157. data/docs/code/Utopia/Controller/Respond/Converter.html +0 -256
  158. data/docs/code/Utopia/Controller/Respond/Converter/Callback.html +0 -484
  159. data/docs/code/Utopia/Controller/Respond/Converter/ToJSON.html +0 -381
  160. data/docs/code/Utopia/Controller/Respond/Passthrough.html +0 -297
  161. data/docs/code/Utopia/Controller/Respond/Responder.html +0 -535
  162. data/docs/code/Utopia/Controller/Rewrite.html +0 -290
  163. data/docs/code/Utopia/Controller/Rewrite/ClassMethods.html +0 -242
  164. data/docs/code/Utopia/Controller/Rewrite/ExtractPrefixRule.html +0 -364
  165. data/docs/code/Utopia/Controller/Rewrite/Rewriter.html +0 -464
  166. data/docs/code/Utopia/Controller/Rewrite/Rule.html +0 -209
  167. data/docs/code/Utopia/Controller/Variables.html +0 -550
  168. data/docs/code/Utopia/Controllers.html +0 -244
  169. data/docs/code/Utopia/Exceptions.html +0 -127
  170. data/docs/code/Utopia/Exceptions/Handler.html +0 -526
  171. data/docs/code/Utopia/Exceptions/Mailer.html +0 -482
  172. data/docs/code/Utopia/Extensions.html +0 -117
  173. data/docs/code/Utopia/Extensions/ArraySplit.html +0 -183
  174. data/docs/code/Utopia/Extensions/DateTimeComparison.html +0 -193
  175. data/docs/code/Utopia/Extensions/TimeDateComparison.html +0 -193
  176. data/docs/code/Utopia/HTTP.html +0 -250
  177. data/docs/code/Utopia/HTTP/Status.html +0 -415
  178. data/docs/code/Utopia/Locale.html +0 -606
  179. data/docs/code/Utopia/Localization.html +0 -1241
  180. data/docs/code/Utopia/Localization/Wrapper.html +0 -459
  181. data/docs/code/Utopia/Logger.html +0 -205
  182. data/docs/code/Utopia/Logger/CompactFormatter.html +0 -335
  183. data/docs/code/Utopia/Path.html +0 -3310
  184. data/docs/code/Utopia/Path/Matcher.html +0 -518
  185. data/docs/code/Utopia/Path/Matcher/MatchData.html +0 -475
  186. data/docs/code/Utopia/Redirection.html +0 -151
  187. data/docs/code/Utopia/Redirection/ClientRedirect.html +0 -717
  188. data/docs/code/Utopia/Redirection/DirectoryIndex.html +0 -298
  189. data/docs/code/Utopia/Redirection/Errors.html +0 -476
  190. data/docs/code/Utopia/Redirection/Moved.html +0 -312
  191. data/docs/code/Utopia/Redirection/RequestFailure.html +0 -226
  192. data/docs/code/Utopia/Redirection/Rewrite.html +0 -296
  193. data/docs/code/Utopia/Session.html +0 -889
  194. data/docs/code/Utopia/Session/LazyHash.html +0 -859
  195. data/docs/code/Utopia/Setup.html +0 -970
  196. data/docs/code/Utopia/Static.html +0 -696
  197. data/docs/code/Utopia/Static/LocalFile.html +0 -1104
  198. data/docs/code/Utopia/Static/MimeTypeLoader.html +0 -541
  199. data/docs/code/Utopia/Static/MimeTypeLoader/ExpansionError.html +0 -124
  200. data/docs/code/Utopia/Tags.html +0 -115
  201. data/docs/code/Utopia/Tags/Environment.html +0 -314
  202. data/docs/code/Utopia/Tags/EnvironmentTag.html +0 -314
  203. data/docs/code/Utopia/Tags/Library.html +0 -340
  204. data/docs/code/_index.html +0 -758
  205. data/docs/code/class_list.html +0 -51
  206. data/docs/code/css/common.css +0 -1
  207. data/docs/code/css/full_list.css +0 -58
  208. data/docs/code/css/style.css +0 -496
  209. data/docs/code/file.README.html +0 -171
  210. data/docs/code/file_list.html +0 -56
  211. data/docs/code/frames.html +0 -17
  212. data/docs/code/index.html +0 -171
  213. data/docs/code/js/app.js +0 -292
  214. data/docs/code/js/full_list.js +0 -216
  215. data/docs/code/js/jquery.js +0 -4
  216. data/docs/code/materials/utopia.png +0 -0
  217. data/docs/code/materials/utopia.svg +0 -1
  218. data/docs/code/method_list.html +0 -3443
  219. data/docs/code/top-level-namespace.html +0 -110
  220. data/docs/index.html +0 -92
  221. data/docs/wiki.html +0 -92
  222. data/docs/wiki/development-environment-setup.html +0 -60
  223. data/docs/wiki/development-environment-setup/index.html +0 -60
  224. data/docs/wiki/edit.html +0 -103
  225. data/docs/wiki/faq/what-is-xnode.html +0 -79
  226. data/docs/wiki/faq/what-is-xnode/index.html +0 -79
  227. data/docs/wiki/javascript.html +0 -153
  228. data/docs/wiki/javascript/index.html +0 -153
  229. data/docs/wiki/middleware/content.html +0 -64
  230. data/docs/wiki/middleware/content/index.html +0 -64
  231. data/docs/wiki/middleware/controller.html +0 -104
  232. data/docs/wiki/middleware/controller/actions.html +0 -117
  233. data/docs/wiki/middleware/controller/actions/index.html +0 -117
  234. data/docs/wiki/middleware/controller/actions/rewrite/index.html +0 -48
  235. data/docs/wiki/middleware/controller/index.html +0 -104
  236. data/docs/wiki/middleware/controller/rewrite.html +0 -111
  237. data/docs/wiki/middleware/controller/rewrite/index.html +0 -111
  238. data/docs/wiki/middleware/localization.html +0 -59
  239. data/docs/wiki/middleware/localization/index.html +0 -59
  240. data/docs/wiki/middleware/redirection.html +0 -61
  241. data/docs/wiki/middleware/redirection/index.html +0 -61
  242. data/docs/wiki/middleware/session.html +0 -71
  243. data/docs/wiki/middleware/session/index.html +0 -71
  244. data/docs/wiki/middleware/static.html +0 -57
  245. data/docs/wiki/middleware/static/index.html +0 -57
  246. data/docs/wiki/server-setup.html +0 -118
  247. data/docs/wiki/server-setup/index.html +0 -118
  248. data/docs/wiki/testing.html +0 -59
  249. data/docs/wiki/testing/index.html +0 -59
  250. data/docs/wiki/updating-utopia.html +0 -108
  251. data/docs/wiki/updating-utopia/index.html +0 -108
  252. data/docs/wiki/your-first-page.html +0 -80
  253. data/docs/wiki/your-first-page/index.html +0 -80
  254. data/documentation/.rspec +0 -4
  255. data/documentation/.yarnrc +0 -1
  256. data/documentation/Gemfile +0 -19
  257. data/documentation/Guardfile +0 -9
  258. data/documentation/Rakefile +0 -9
  259. data/documentation/config.ru +0 -41
  260. data/documentation/config/README.md +0 -7
  261. data/documentation/config/environment.rb +0 -12
  262. data/documentation/lib/readme.txt +0 -1
  263. data/documentation/pages/_editor.xnode +0 -64
  264. data/documentation/pages/_heading.xnode +0 -2
  265. data/documentation/pages/_page.xnode +0 -40
  266. data/documentation/pages/errors/exception.xnode +0 -5
  267. data/documentation/pages/errors/file-not-found.xnode +0 -5
  268. data/documentation/pages/links.yaml +0 -2
  269. data/documentation/pages/wiki/_listing.xnode +0 -32
  270. data/documentation/pages/wiki/_navigation.xnode +0 -15
  271. data/documentation/pages/wiki/content.md +0 -35
  272. data/documentation/pages/wiki/controller.rb +0 -48
  273. data/documentation/pages/wiki/development-environment-setup/content.md +0 -16
  274. data/documentation/pages/wiki/edit.xnode +0 -10
  275. data/documentation/pages/wiki/faq/what-is-xnode/content.md +0 -37
  276. data/documentation/pages/wiki/javascript/content.md +0 -75
  277. data/documentation/pages/wiki/links.yaml +0 -6
  278. data/documentation/pages/wiki/middleware/content/content.md +0 -21
  279. data/documentation/pages/wiki/middleware/controller/actions/content.md +0 -76
  280. data/documentation/pages/wiki/middleware/controller/content.md +0 -62
  281. data/documentation/pages/wiki/middleware/controller/links.yaml +0 -4
  282. data/documentation/pages/wiki/middleware/controller/rewrite/content.md +0 -69
  283. data/documentation/pages/wiki/middleware/localization/content.md +0 -16
  284. data/documentation/pages/wiki/middleware/redirection/content.md +0 -17
  285. data/documentation/pages/wiki/middleware/session/content.md +0 -29
  286. data/documentation/pages/wiki/middleware/static/content.md +0 -13
  287. data/documentation/pages/wiki/server-setup/content.md +0 -52
  288. data/documentation/pages/wiki/show.xnode +0 -12
  289. data/documentation/pages/wiki/testing/content.md +0 -15
  290. data/documentation/pages/wiki/updating-utopia/content.md +0 -63
  291. data/documentation/pages/wiki/your-first-page/content.md +0 -38
  292. data/documentation/public/_components/jquery-syntax/base/jquery.syntax.brush.apache.css +0 -6
  293. data/documentation/public/_components/jquery-syntax/base/jquery.syntax.brush.applescript.css +0 -5
  294. data/documentation/public/_components/jquery-syntax/base/jquery.syntax.brush.assembly.css +0 -8
  295. data/documentation/public/_components/jquery-syntax/base/jquery.syntax.brush.bash-script.css +0 -6
  296. data/documentation/public/_components/jquery-syntax/base/jquery.syntax.brush.bash.css +0 -10
  297. data/documentation/public/_components/jquery-syntax/base/jquery.syntax.brush.clang.css +0 -3
  298. data/documentation/public/_components/jquery-syntax/base/jquery.syntax.brush.css.css +0 -14
  299. data/documentation/public/_components/jquery-syntax/base/jquery.syntax.brush.diff.css +0 -16
  300. data/documentation/public/_components/jquery-syntax/base/jquery.syntax.brush.html.css +0 -5
  301. data/documentation/public/_components/jquery-syntax/base/jquery.syntax.brush.ocaml.css +0 -3
  302. data/documentation/public/_components/jquery-syntax/base/jquery.syntax.brush.protobuf.css +0 -2
  303. data/documentation/public/_components/jquery-syntax/base/jquery.syntax.brush.python.css +0 -6
  304. data/documentation/public/_components/jquery-syntax/base/jquery.syntax.brush.ruby.css +0 -2
  305. data/documentation/public/_components/jquery-syntax/base/jquery.syntax.brush.xml.css +0 -18
  306. data/documentation/public/_components/jquery-syntax/base/jquery.syntax.core.css +0 -62
  307. data/documentation/public/_components/jquery-syntax/base/jquery.syntax.editor.css +0 -6
  308. data/documentation/public/_components/jquery-syntax/base/theme.js +0 -1
  309. data/documentation/public/_components/jquery-syntax/bright/jquery.syntax.core.css +0 -27
  310. data/documentation/public/_components/jquery-syntax/bright/theme.js +0 -1
  311. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.apache.js +0 -41
  312. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.applescript.js +0 -57
  313. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.assembly.js +0 -37
  314. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.bash-script.js +0 -67
  315. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.bash.js +0 -33
  316. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.basic.js +0 -51
  317. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.clang.js +0 -89
  318. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.csharp.js +0 -47
  319. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.css.js +0 -80
  320. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.diff.js +0 -24
  321. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.go.js +0 -47
  322. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.haskell.js +0 -45
  323. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.html.js +0 -66
  324. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.io.js +0 -45
  325. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.java.js +0 -45
  326. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.javascript.js +0 -40
  327. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.kai.js +0 -29
  328. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.lisp.js +0 -34
  329. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.lua.js +0 -44
  330. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.nginx.js +0 -31
  331. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.ocaml.js +0 -73
  332. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.ooc.js +0 -46
  333. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.pascal.js +0 -51
  334. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.perl5.js +0 -52
  335. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.php-script.js +0 -48
  336. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.php.js +0 -15
  337. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.plain.js +0 -10
  338. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.protobuf.js +0 -43
  339. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.python.js +0 -44
  340. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.ruby.js +0 -77
  341. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.scala.js +0 -44
  342. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.smalltalk.js +0 -29
  343. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.sql.js +0 -31
  344. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.super-collider.js +0 -57
  345. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.swift.js +0 -55
  346. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.trenni.js +0 -35
  347. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.xml.js +0 -50
  348. data/documentation/public/_components/jquery-syntax/jquery.syntax.brush.yaml.js +0 -29
  349. data/documentation/public/_components/jquery-syntax/jquery.syntax.cache.js +0 -65
  350. data/documentation/public/_components/jquery-syntax/jquery.syntax.core.js +0 -1098
  351. data/documentation/public/_components/jquery-syntax/jquery.syntax.editor.js +0 -291
  352. data/documentation/public/_components/jquery-syntax/jquery.syntax.js +0 -258
  353. data/documentation/public/_components/jquery-syntax/jquery.syntax.min.js +0 -13
  354. data/documentation/public/_components/jquery-syntax/paper/jquery.syntax.core.css +0 -31
  355. data/documentation/public/_components/jquery-syntax/paper/theme.js +0 -1
  356. data/documentation/public/_components/jquery/core.js +0 -482
  357. data/documentation/public/_components/jquery/jquery.js +0 -10220
  358. data/documentation/public/_components/jquery/jquery.min.js +0 -4
  359. data/documentation/public/_components/jquery/jquery.min.map +0 -1
  360. data/documentation/public/_components/jquery/jquery.slim.js +0 -8107
  361. data/documentation/public/_components/jquery/jquery.slim.min.js +0 -4
  362. data/documentation/public/_components/jquery/jquery.slim.min.map +0 -1
  363. data/documentation/public/_static +0 -1
  364. data/documentation/public/materials +0 -1
  365. data/documentation/spec/website_context.rb +0 -12
  366. data/documentation/spec/website_spec.rb +0 -16
  367. data/documentation/tasks +0 -1
  368. data/materials/utopia.png +0 -0
  369. data/materials/utopia.svg +0 -1
  370. data/setup/site/.yarnrc +0 -1
  371. data/spec/mock_node.rb +0 -16
  372. data/spec/spec_helper.rb +0 -13
  373. data/spec/utopia/command_spec.rb +0 -164
  374. data/spec/utopia/content/document_spec.rb +0 -60
  375. data/spec/utopia/content/link_spec.rb +0 -47
  376. data/spec/utopia/content/links/foo/index.xnode +0 -0
  377. data/spec/utopia/content/links/foo/links.yaml +0 -2
  378. data/spec/utopia/content/links/foo/test.de.xnode +0 -0
  379. data/spec/utopia/content/links/foo/test.en.xnode +0 -0
  380. data/spec/utopia/content/links/links.yaml +0 -9
  381. data/spec/utopia/content/links/welcome.xnode +0 -0
  382. data/spec/utopia/content/links_spec.rb +0 -101
  383. data/spec/utopia/content/localized/five/index.en.xnode +0 -0
  384. data/spec/utopia/content/localized/four/index.en.xnode +0 -0
  385. data/spec/utopia/content/localized/four/index.zh.xnode +0 -0
  386. data/spec/utopia/content/localized/four/links.yaml +0 -4
  387. data/spec/utopia/content/localized/links.yaml +0 -16
  388. data/spec/utopia/content/localized/one.xnode +0 -0
  389. data/spec/utopia/content/localized/three/index.xnode +0 -0
  390. data/spec/utopia/content/localized/two.en.xnode +0 -0
  391. data/spec/utopia/content/localized/two.zh.xnode +0 -0
  392. data/spec/utopia/content/markup_spec.rb +0 -96
  393. data/spec/utopia/content/namespace_spec.rb +0 -45
  394. data/spec/utopia/content/node/lookup/content.xnode +0 -1
  395. data/spec/utopia/content/node/lookup/index.xnode +0 -1
  396. data/spec/utopia/content/node/ordered/first.xnode +0 -0
  397. data/spec/utopia/content/node/ordered/index.xnode +0 -0
  398. data/spec/utopia/content/node/ordered/links.yaml +0 -4
  399. data/spec/utopia/content/node/ordered/second.xnode +0 -0
  400. data/spec/utopia/content/node/related/foo.en.xnode +0 -0
  401. data/spec/utopia/content/node/related/foo.ja.xnode +0 -0
  402. data/spec/utopia/content/node/related/links.yaml +0 -4
  403. data/spec/utopia/content/node_spec.rb +0 -97
  404. data/spec/utopia/content/response_spec.rb +0 -54
  405. data/spec/utopia/content/tags_spec.rb +0 -82
  406. data/spec/utopia/content_spec.rb +0 -100
  407. data/spec/utopia/content_spec.ru +0 -6
  408. data/spec/utopia/content_spec/_heading.xnode +0 -1
  409. data/spec/utopia/content_spec/content/_show-value.xnode +0 -1
  410. data/spec/utopia/content_spec/content/links.yaml +0 -2
  411. data/spec/utopia/content_spec/content/test-partial.xnode +0 -1
  412. data/spec/utopia/content_spec/index.xnode +0 -1
  413. data/spec/utopia/content_spec/node/index.xnode +0 -1
  414. data/spec/utopia/content_spec/test.xnode +0 -10
  415. data/spec/utopia/controller/actions_spec.rb +0 -62
  416. data/spec/utopia/controller/middleware_spec.rb +0 -88
  417. data/spec/utopia/controller/middleware_spec.ru +0 -6
  418. data/spec/utopia/controller/middleware_spec/controller/controller.rb +0 -27
  419. data/spec/utopia/controller/middleware_spec/controller/index.xnode +0 -1
  420. data/spec/utopia/controller/middleware_spec/controller/nested/controller.rb +0 -7
  421. data/spec/utopia/controller/middleware_spec/empty/controller.rb +0 -0
  422. data/spec/utopia/controller/middleware_spec/redirect/controller.rb +0 -12
  423. data/spec/utopia/controller/middleware_spec/redirect/test/controller.rb +0 -9
  424. data/spec/utopia/controller/respond_spec.rb +0 -174
  425. data/spec/utopia/controller/respond_spec.ru +0 -12
  426. data/spec/utopia/controller/respond_spec/api/controller.rb +0 -28
  427. data/spec/utopia/controller/respond_spec/errors/controller.rb +0 -14
  428. data/spec/utopia/controller/respond_spec/errors/file-not-found.xnode +0 -8
  429. data/spec/utopia/controller/respond_spec/html/controller.rb +0 -11
  430. data/spec/utopia/controller/respond_spec/rewrite/controller.rb +0 -13
  431. data/spec/utopia/controller/rewrite_spec.rb +0 -80
  432. data/spec/utopia/controller/sequence_spec.rb +0 -135
  433. data/spec/utopia/controller/variables_spec.rb +0 -59
  434. data/spec/utopia/controller/websocket_spec.rb +0 -68
  435. data/spec/utopia/controller/websocket_spec.ru +0 -5
  436. data/spec/utopia/controller/websocket_spec/server/controller.rb +0 -11
  437. data/spec/utopia/exceptions/handler_spec.rb +0 -47
  438. data/spec/utopia/exceptions/handler_spec.ru +0 -8
  439. data/spec/utopia/exceptions/handler_spec/controller.rb +0 -19
  440. data/spec/utopia/exceptions/mailer_spec.rb +0 -43
  441. data/spec/utopia/exceptions/mailer_spec.ru +0 -10
  442. data/spec/utopia/extensions_spec.rb +0 -73
  443. data/spec/utopia/http/status_spec.rb +0 -44
  444. data/spec/utopia/locale_spec.rb +0 -58
  445. data/spec/utopia/localization_spec.rb +0 -92
  446. data/spec/utopia/localization_spec.ru +0 -15
  447. data/spec/utopia/localization_spec/controller.rb +0 -21
  448. data/spec/utopia/localization_spec/localized.de.txt +0 -1
  449. data/spec/utopia/localization_spec/localized.en.txt +0 -1
  450. data/spec/utopia/localization_spec/localized.ja.txt +0 -1
  451. data/spec/utopia/localization_spec/test.txt +0 -1
  452. data/spec/utopia/middleware_spec.rb +0 -31
  453. data/spec/utopia/path/matcher_spec.rb +0 -66
  454. data/spec/utopia/path_spec.rb +0 -162
  455. data/spec/utopia/performance_spec.rb +0 -92
  456. data/spec/utopia/performance_spec/cache/head/readme.txt +0 -1
  457. data/spec/utopia/performance_spec/cache/meta/readme.txt +0 -1
  458. data/spec/utopia/performance_spec/config.ru +0 -35
  459. data/spec/utopia/performance_spec/lib/readme.txt +0 -1
  460. data/spec/utopia/performance_spec/pages/_heading.xnode +0 -2
  461. data/spec/utopia/performance_spec/pages/_page.xnode +0 -26
  462. data/spec/utopia/performance_spec/pages/api/controller.rb +0 -8
  463. data/spec/utopia/performance_spec/pages/errors/exception.xnode +0 -5
  464. data/spec/utopia/performance_spec/pages/errors/file-not-found.xnode +0 -5
  465. data/spec/utopia/performance_spec/pages/links.yaml +0 -2
  466. data/spec/utopia/performance_spec/pages/welcome/index.xnode +0 -17
  467. data/spec/utopia/rack_helper.rb +0 -32
  468. data/spec/utopia/redirection_spec.rb +0 -77
  469. data/spec/utopia/redirection_spec.ru +0 -27
  470. data/spec/utopia/session_spec.rb +0 -189
  471. data/spec/utopia/session_spec.ru +0 -24
  472. data/spec/utopia/setup_spec.rb +0 -56
  473. data/spec/utopia/static_spec.rb +0 -49
  474. data/spec/utopia/static_spec.ru +0 -5
  475. data/spec/utopia/static_spec/test.txt +0 -1
  476. data/utopia.gemspec +0 -52
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b3a2b969739fa3a580d3c52c8755a4603b51f4f8170358f36120cb746824764
4
- data.tar.gz: 753825339c39b9e404dfe697254d8b5c56c1ae25750a81b23c89a72af5f6518b
3
+ metadata.gz: ddb5cc8a1bb593d344e0d2f2c8bf315704f297ae1e8063b4d7c0e5f3d71f4014
4
+ data.tar.gz: '09ff4febe6dd06945a3725e0c1354402e23bf837026c5aa09b6c2106b482e00d'
5
5
  SHA512:
6
- metadata.gz: 2bae7423c0fc11004811f483219b64f73475b04865dbc95baed6ef7225c190eabdaeb72628c8e77c684393b35ba884640a35d6a916665259cb2881780098a0e6
7
- data.tar.gz: 5b6074e3558a8e0e4efd0bb02ff09c1aaf01caade4b7d520dcbc3ac0041b678797ff06c32465aac51abed761cf1338db5ea712e8308e6448cd8a5c63ef0a9ce7
6
+ metadata.gz: 6a5a89b6bf438d72007dd8617085125aae4a038ee8267716361810e149f9488166323c299aea04baf69ebd54e630e20093c32ec8e016553b11ad46bfa54fe22c
7
+ data.tar.gz: bf6fcfe77a7423b39fabd019b40309c52db7a15284661243119d32c279d32d51d2467e4bff409cf6d53924baca9cc60d7788b00bbaf4f9986b65e2b0522e5dbd
@@ -5,12 +5,20 @@ def update
5
5
  require 'fileutils'
6
6
  require 'utopia/path'
7
7
 
8
- yarn_package_root = self.root + "lib/components"
9
- yarn_install_root = self.root + "public/_components"
8
+ root = Pathname.new(context.root)
9
+ package_root = root + "node_modules"
10
10
 
11
- yarn_package_root.children.select(&:directory?).collect(&:basename).each do |package_directory|
12
- install_path = @yarn_install_root + package_directory
13
- package_path = @yarn_package_root + package_directory
11
+ # This is a legacy path:
12
+ unless package_root.directory?
13
+ package_root = root + "lib/components"
14
+ end
15
+
16
+ install_root = root + "public/_components"
17
+
18
+ package_root.children.select(&:directory?).collect(&:basename).each do |package_directory|
19
+ install_path = install_root + package_directory
20
+ package_path = package_root + package_directory
21
+
14
22
  dist_path = package_path + 'dist'
15
23
 
16
24
  FileUtils::Verbose.rm_rf(install_path)
@@ -28,8 +28,8 @@ require_relative 'command/environment'
28
28
 
29
29
  module Utopia
30
30
  module Command
31
- def self.call(*args)
32
- Top.call(*args)
31
+ def self.call(*arguments)
32
+ Top.call(*arguments)
33
33
  end
34
34
 
35
35
  # The top level utopia command.
@@ -33,7 +33,7 @@ module Utopia
33
33
  # Local site setup commands.
34
34
  class Site < Samovar::Command
35
35
  # Configuration files which should be installed/updated:
36
- CONFIGURATION_FILES = ['.yarnrc', '.gitignore', 'config.ru', 'config/environment.rb', 'falcon.rb', 'Gemfile', 'Guardfile', 'bake.rb', 'spec/spec_helper.rb', 'spec/website_context.rb', 'spec/website_spec.rb']
36
+ CONFIGURATION_FILES = ['.gitignore', 'config.ru', 'config/environment.rb', 'falcon.rb', 'Gemfile', 'Guardfile', 'bake.rb', 'spec/spec_helper.rb', 'spec/website_context.rb', 'spec/website_spec.rb']
37
37
 
38
38
  # Directories that should exist:
39
39
  DIRECTORIES = ["config", "lib", "pages", "public", "tasks", "spec"]
@@ -59,7 +59,7 @@ module Utopia
59
59
  # The core namespace for utopia specific functionality:
60
60
  @namespaces[UTOPIA_NAMESPACE] ||= Tags
61
61
  end
62
-
62
+
63
63
  def freeze
64
64
  return self if frozen?
65
65
 
@@ -72,6 +72,7 @@ module Utopia
72
72
 
73
73
  attr :root
74
74
 
75
+ # TODO we should remove this method and expose `@links` directly.
75
76
  def links(path, **options)
76
77
  @links.index(path, **options)
77
78
  end
@@ -91,20 +92,23 @@ module Utopia
91
92
  end
92
93
  end
93
94
 
94
- # The request_path is an absolute uri path, e.g. /foo/bar. If an xnode file exists on disk for this exact path, it is instantiated, otherwise nil.
95
- def lookup_node(request_path)
96
- name = request_path.last
97
- name_xnode = name.to_s + XNODE_EXTENSION
98
-
99
- node_path = File.join(@root, request_path.dirname.components, name_xnode)
100
-
101
- if File.exist? node_path
102
- return Node.new(self, request_path.dirname + name, request_path, node_path)
95
+ # @param path [Path] the request_path is an absolute uri path, e.g. `/foo/bar`. If an xnode file exists on disk for this exact path, it is instantiated, otherwise nil.
96
+ def lookup_node(path, locale = nil)
97
+ resolve_link(
98
+ @links.for(path, locale)
99
+ )
100
+ end
101
+
102
+ def resolve_link(link)
103
+ if path = link&.path
104
+ full_path = File.join(@root, path.dirname, link.key + XNODE_EXTENSION)
105
+
106
+ if File.exist?(full_path)
107
+ return Node.new(self, path, path, full_path)
108
+ end
103
109
  end
104
-
105
- return nil
106
110
  end
107
-
111
+
108
112
  def call(env)
109
113
  request = Rack::Request.new(env)
110
114
  path = Path.create(request.path_info)
@@ -112,17 +116,17 @@ module Utopia
112
116
  # Check if the request is to a non-specific index. This only works for requests with a given name:
113
117
  basename = path.basename
114
118
  directory_path = File.join(@root, path.dirname.components, basename)
115
-
119
+
116
120
  # If the request for /foo/bar is actually a directory, rewrite it to /foo/bar/index:
117
121
  if File.directory? directory_path
118
122
  index_path = [basename, INDEX]
119
123
 
120
124
  return [307, {HTTP::LOCATION => path.dirname.join(index_path).to_s}, []]
121
125
  end
122
-
126
+
123
127
  locale = env[Localization::CURRENT_LOCALE_KEY]
124
128
  if link = @links.for(path, locale)
125
- if link.path and node = lookup_node(link.path)
129
+ if node = resolve_link(link)
126
130
  attributes = request.env.fetch(VARIABLES_KEY, {}).to_hash
127
131
 
128
132
  return node.process!(request, attributes)
@@ -153,14 +157,14 @@ module Utopia
153
157
 
154
158
  while components.any?
155
159
  tag_path = File.join(@root, components, name_path)
156
-
160
+
157
161
  if File.exist? tag_path
158
162
  return Node.new(self, Path[components] + name, parent_path + name, tag_path)
159
163
  end
160
-
164
+
161
165
  if String === name_path
162
166
  tag_path = File.join(@root, components, '_' + name_path)
163
-
167
+
164
168
  if File.exist? tag_path
165
169
  return Node.new(self, Path[components] + name, parent_path + name, tag_path)
166
170
  end
@@ -30,60 +30,55 @@ require_relative '../locale'
30
30
 
31
31
  module Utopia
32
32
  class Content
33
- INDEX = 'index'.freeze
34
-
35
33
  # Represents a link to some content with associated metadata.
36
34
  class Link
37
- def initialize(kind, path, info = nil)
38
- path = Path.create(path)
39
-
40
- @info = info || {}
35
+ # @param kind [Symbol] the kind of link.
36
+ def initialize(kind, name, locale, path, info, title = nil)
41
37
  @kind = kind
42
-
43
- case @kind
44
- when :file
45
- @name, @locale = path.last.split('.', 2)
46
- @path = path
47
- when :directory
48
- @name = path.basename
49
-
50
- if @name == INDEX
51
- @name = path.dirname.basename
52
- end
53
-
54
- @locale = path.extension
55
- @path = path
56
- when :virtual
57
- @name, @locale = path.to_s.split('.', 2)
58
- @path = @info[:path] ? Path.create(@info[:path]) : nil
38
+ @name = name
39
+ @locale = locale
40
+ @path = Path.create(path)
41
+ @info = info || {}
42
+ @title = Trenni::Strings.to_title(title || name)
43
+ end
44
+
45
+ def key
46
+ if locale
47
+ "#{@path.last}.#{@locale}"
59
48
  else
60
- raise ArgumentError.new("Unknown link kind #{@kind} with path #{path}")
49
+ @path.last
61
50
  end
62
-
63
- @title = Trenni::Strings.to_title(@name)
64
51
  end
65
-
52
+
66
53
  def href
67
54
  @href ||= @info.fetch(:uri) do
68
55
  (@path.dirname + @path.basename).to_s if @path
69
56
  end
70
57
  end
71
-
58
+
72
59
  # Look up from the `links.yaml` metadata with a given symbolic key.
73
60
  def [] key
74
61
  @info[key]
75
62
  end
76
-
63
+
77
64
  attr :kind
78
65
  attr :name
79
66
  attr :path
80
67
  attr :info
81
68
  attr :locale
82
-
69
+
83
70
  def href?
84
71
  !!href
85
72
  end
86
-
73
+
74
+ def index?
75
+ @kind == :index
76
+ end
77
+
78
+ def virtual?
79
+ @kind == :virtual
80
+ end
81
+
87
82
  def relative_href(base = nil)
88
83
  if base and href.start_with? '/'
89
84
  Path.shortest_path(href, base)
@@ -91,11 +86,11 @@ module Utopia
91
86
  href
92
87
  end
93
88
  end
94
-
89
+
95
90
  def title
96
91
  @info.fetch(:title, @title)
97
92
  end
98
-
93
+
99
94
  def to_anchor(base: nil, content: self.title, builder: nil, **attributes)
100
95
  attributes[:class] ||= 'link'
101
96
 
@@ -124,7 +119,7 @@ module Utopia
124
119
  def eql? other
125
120
  self.class.eql?(other.class) and kind.eql?(other.kind) and name.eql?(other.name) and path.eql?(other.path) and info.eql?(other.info)
126
121
  end
127
-
122
+
128
123
  def == other
129
124
  other and kind == other.kind and name == other.name and path == other.path
130
125
  end
@@ -27,7 +27,8 @@ require 'concurrent/map'
27
27
  module Utopia
28
28
  class Content
29
29
  # The file extension for markup nodes on disk.
30
- XNODE_EXTENSION = '.xnode'.freeze
30
+ XNODE_EXTENSION = '.xnode'
31
+ INDEX = "index"
31
32
 
32
33
  class Links
33
34
  def self.for(root, path, locale = nil)
@@ -40,47 +41,55 @@ module Utopia
40
41
  self.new(root).index(path, **options)
41
42
  end
42
43
 
43
- XNODE_FILTER = /^(.+)#{Regexp.escape XNODE_EXTENSION}$/
44
- INDEX_XNODE_FILTER = /^(index(\..+)*)#{Regexp.escape XNODE_EXTENSION}$/
45
-
46
- def initialize(root)
44
+ def initialize(root, extension: XNODE_EXTENSION)
47
45
  @root = root
48
46
 
49
- @cache = Concurrent::Map.new
47
+ @extension = extension
48
+ @file_filter = /\A(?<key>(?<name>[^.]+)(\.(?<locale>.+))?)#{Regexp.escape extension}\Z/
49
+ @index_filter = /\A(?<key>(?<name>index)(\.(?<locale>.+))?)#{Regexp.escape extension}\Z/
50
+
51
+ @metadata_cache = Concurrent::Map.new
52
+ @links_cache = Concurrent::Map.new
50
53
  end
51
54
 
55
+ attr :extension
56
+ attr :file_filter
57
+ attr :index_filter
58
+
59
+ # Resolve a link for the specified path, which must be a path to a specific link.
60
+ # for(Path["/index"])
52
61
  def for(path, locale = nil)
53
- links = Resolved.new(self, path.dirname)
54
-
55
- links.lookup(path.last, locale)
62
+ links(path.dirname).lookup(path.last, locale)
56
63
  end
57
64
 
58
- DEFAULT_INDEX_OPTIONS = {
59
- :directories => true,
60
- :files => true,
61
- :virtuals => true,
62
- :indices => false,
63
- :sort => :order,
64
- :display => :display,
65
- }
66
-
67
- def index(path, **options)
68
- options = DEFAULT_INDEX_OPTIONS.merge(options)
65
+ # Give an index of all links that can be reached from the given path.
66
+ def index(path, name: nil, locale: nil, display: :display, sort: :order, sort_default: 0, directories: true, files: true, virtuals: true, indices: false)
67
+ ordered = links(path).ordered.dup
68
+
69
+ # Ignore specific kinds of links:
70
+ ignore = []
71
+ ignore << :directory unless directories
72
+ ignore << :file unless files
73
+ ignore << :virtual unless virtuals
74
+ ignore << :index unless indices
69
75
 
70
- ordered = Resolved.new(self, path, options).ordered
76
+ if ignore.any?
77
+ ordered.reject!{|link| ignore.include?(link.kind)}
78
+ end
71
79
 
72
- # This option filters a link based on the display parameter.
73
- if display_key = options[:display]
74
- ordered.reject!{|link| link.info[display_key] == false}
80
+ # Filter links by display key:
81
+ if display
82
+ ordered.reject!{|link| link.info[display] == false}
75
83
  end
76
84
 
77
- # Named:
78
- if name = options[:name]
85
+ # Filter links by name:
86
+ if name
79
87
  # We use pattern === name, which matches either the whole string, or matches a regexp.
80
88
  ordered.select!{|link| name === link.name}
81
89
  end
82
90
 
83
- if locale = options[:locale]
91
+ # Filter by locale:
92
+ if locale
84
93
  locales = {}
85
94
 
86
95
  ordered.each do |link|
@@ -94,10 +103,10 @@ module Utopia
94
103
  ordered = locales.values
95
104
  end
96
105
 
97
- # Sort:
98
- if sort_key = options[:sort]
106
+ # Order by sort key:
107
+ if sort
99
108
  # Sort by sort_key, otherwise by title.
100
- ordered.sort_by!{|link| [link[sort_key] || options[:sort_default] || 0, link.title]}
109
+ ordered.sort_by!{|link| [link[sort] || sort_default, link.title]}
101
110
  end
102
111
 
103
112
  return ordered
@@ -105,38 +114,65 @@ module Utopia
105
114
 
106
115
  attr :root
107
116
 
108
- # Represents a list of {Link} instances relating to the structure of the content. They are formed from the `links.yaml` file and the actual directory structure on disk.
109
- class Resolved
110
- DEFAULT_OPTIONS = {
111
- :directories => true,
112
- :files => true,
113
- :virtuals => true,
114
- :indices => true,
115
- }
117
+ def metadata(path)
118
+ @metadata_cache.fetch_or_store(path.to_s) do
119
+ load_metadata(path)
120
+ end
121
+ end
122
+
123
+ def links(path)
124
+ @links_cache.fetch_or_store(path.to_s) do
125
+ load_links(path)
126
+ end
127
+ end
128
+
129
+ private
130
+
131
+ def symbolize_keys(map)
132
+ # Second level attributes should be symbolic:
133
+ map.each do |key, info|
134
+ map[key] = info.each_with_object({}) { |(k,v),result| result[k.to_sym] = v }
135
+ end
116
136
 
117
- def initialize(links, top = Path.root, options = DEFAULT_OPTIONS)
137
+ return map
138
+ end
139
+
140
+ LINKS_YAML = "links.yaml"
141
+
142
+ def load_metadata(path)
143
+ yaml_path = File.join(path, LINKS_YAML)
144
+
145
+ if File.exist?(yaml_path) && data = YAML::load_file(yaml_path)
146
+ return symbolize_keys(data)
147
+ else
148
+ return {}
149
+ end
150
+ end
151
+
152
+ # Represents a list of {Link} instances relating to the structure of the content. They are formed from the `links.yaml` file and the actual directory structure on disk.
153
+ class Resolver
154
+ def initialize(links, top = Path.root)
118
155
  raise ArgumentError.new("top path must be absolute") unless top.absolute?
119
156
 
120
157
  @links = links
121
158
 
122
159
  @top = top
123
- @options = options
124
160
 
125
161
  # top.components.first == '', but this isn't a problem here.
126
162
  @path = File.join(links.root, top.components)
127
163
 
128
164
  @ordered = []
129
- @named = Hash.new{|h,k| h[k] = []}
165
+ @named = {}
130
166
 
131
- if File.directory? @path
167
+ if File.directory?(@path)
132
168
  @metadata = links.metadata(@path)
133
169
 
134
170
  load_links(@metadata.dup) do |link|
135
171
  @ordered << link
136
- @named[link.name] << link
172
+ (@named[link.name] ||= []) << link
137
173
  end
138
174
  else
139
- @metadata = {}
175
+ @metadata = nil
140
176
  end
141
177
  end
142
178
 
@@ -144,6 +180,10 @@ module Utopia
144
180
  attr :ordered
145
181
  attr :named
146
182
 
183
+ def indices
184
+ return @ordered.select{|link| link.index?}
185
+ end
186
+
147
187
  def each(locale)
148
188
  return to_enum(:each, locale) unless block_given?
149
189
 
@@ -155,115 +195,137 @@ module Utopia
155
195
  def lookup(name, locale = nil)
156
196
  # This allows generic links to serve any locale requested.
157
197
  if links = @named[name]
158
- links.find{|link| link.locale == locale} || links.find{|link| link.locale == nil}
198
+ generic_link = nil
199
+
200
+ links.each do |link|
201
+ if link.locale == locale
202
+ return link
203
+ elsif link.locale.nil?
204
+ generic_link = link
205
+ end
206
+ end
207
+
208
+ return generic_link
159
209
  end
160
210
  end
161
211
 
162
212
  private
163
213
 
164
- def indices(path, &block)
165
- Dir.entries(path).select{|filename| filename.match(INDEX_XNODE_FILTER)}
214
+ def entries(path)
215
+ Dir.entries(path).reject{|entry| entry.match(/^[\._]/)}
166
216
  end
167
217
 
168
- def load_indices(name, path, metadata)
169
- directory_metadata = metadata.delete(name) || {}
170
- indices_metadata = @links.metadata(path)
218
+ # @param name [String] the name of the directory.
219
+ def load_directory(name, metadata, &block)
220
+ defaults = metadata.delete(name) || {}
171
221
 
172
- indices_count = 0
222
+ links = @links.links(@top + name).indices
173
223
 
174
- indices(path).each do |filename|
175
- index_name = File.basename(filename, XNODE_EXTENSION)
176
- # Values in indices_metadata will override values in directory_metadata:
177
- index_metadata = directory_metadata.merge(indices_metadata[index_name] || {})
178
-
179
- directory_link = Link.new(:directory, @top + [name, index_name], index_metadata)
180
-
181
- # Merge metadata from foo.en into foo/index.en
182
- if directory_link.locale
183
- localized_key = "#{directory_link.name}.#{directory_link.locale}"
184
- if localized_metadata = metadata.delete(localized_key)
185
- directory_link.info.update(localized_metadata)
186
- end
224
+ links.each do |link|
225
+ # We extract the metadata according to the localized link:
226
+ if info = metadata.delete("#{name}.#{link.locale}")
227
+ info = info.merge(link.info)
228
+ else
229
+ info = link.info
187
230
  end
188
231
 
189
- yield directory_link
190
-
191
- indices_count += 1
232
+ yield Link.new(:directory, name, link.locale, link.path, defaults.merge(info))
233
+ end
234
+ end
235
+
236
+ def load_index(name, locale, info)
237
+ info ||= {}
238
+
239
+ if locale and defaults = @metadata[name]
240
+ info = defaults.merge(info)
192
241
  end
193
242
 
194
- if indices_count == 0
195
- # Specify a nil uri if no index could be found for the directory:
196
- yield Link.new(:directory, top + [name], {:uri => nil}.merge(directory_metadata))
243
+ path = @top + name
244
+
245
+ yield Link.new(:index, name, locale, path, info, path[-2])
246
+ end
247
+
248
+ def load_default_index(name = INDEX, info = {})
249
+ path = @top + name
250
+
251
+ if info
252
+ info = {uri: nil}.merge(info)
253
+ else
254
+ info = {uri: nil}
197
255
  end
256
+
257
+ # Specify a nil uri if no index could be found for the directory:
258
+ yield Link.new(:index, name, nil, @top, info, path[-2])
198
259
  end
199
260
 
200
- def entries(path)
201
- Dir.entries(path).reject{|filename| filename.match(/^[\._]/)}
261
+ def load_file(name, locale, info)
262
+ info ||= {}
263
+
264
+ if locale and defaults = @metadata[name]
265
+ info = defaults.merge(info)
266
+ end
267
+
268
+ path = @top + name
269
+
270
+ yield Link.new(:file, name, locale, path, info)
202
271
  end
203
272
 
204
- def load_links(metadata, &block)
205
- # Load all metadata for a given path:
206
- metadata = @metadata.dup
273
+ def load_virtuals(metadata)
274
+ virtuals = {}
207
275
 
208
- # Check all entries in the given directory:
209
- entries(@path).each do |filename|
210
- path = File.join(@path, filename)
276
+ # After processing all directory entries, we are left with virtual links:
277
+ metadata.each do |key, info|
278
+ name, locale = key.split('.', 2)
279
+ localized = (virtuals[name] ||= {})
280
+ localized[locale] = info
281
+ end
282
+
283
+ virtuals.each do |name, localized|
284
+ defaults = localized[nil]
211
285
 
212
- # There are two types of filelinks based links:
213
- # 1/ Named files, e.g. foo.xnode, name=foo
214
- # 2/ Directories, e.g. bar/index.xnode, name=bar
215
- if File.directory?(path) and @options[:directories]
216
- load_indices(filename, path, metadata, &block)
217
- elsif filename.match(INDEX_XNODE_FILTER) and @options[:indices] == false
218
- metadata.delete($1) # We don't include indices in the list of pages.
219
- elsif filename.match(XNODE_FILTER) and @options[:files]
220
- yield Link.new(:file, @top + $1, metadata.delete($1))
286
+ localized.each do |locale, info|
287
+ info = defaults&.merge(info) || info
288
+ path = info[:path]
289
+
290
+ yield Link.new(:virtual, name, locale, path, info)
221
291
  end
222
292
  end
293
+ end
294
+
295
+ def load_links(metadata, &block)
296
+ index_loaded = false
223
297
 
224
- if @options[:virtuals]
225
- # After processing all directory entries, we are left with virtual entries in the metadata:
226
- metadata.each do |name, info|
227
- virtual_link = Link.new(:virtual, name, info)
298
+ # Check all entries in the given directory:
299
+ entries(@path).each do |entry|
300
+ path = File.join(@path, entry)
301
+
302
+ # There are serveral types of file based links:
303
+
304
+ # 1. Directories, e.g. bar/ (name=bar)
305
+ if File.directory?(path)
306
+ load_directory(entry, metadata, &block)
228
307
 
229
- # Given a virtual named such as "welcome.cn", merge it with metadata from "welcome" if it exists:
230
- if virtual_metadata = @metadata[virtual_link.name]
231
- virtual_link.info.update(virtual_metadata)
232
- end
308
+ # 2. Index files, e.g. index.xnode, name=parent
309
+ elsif match = entry.match(@links.index_filter)
310
+ load_index(match[:name], match[:locale], metadata.delete(match[:key]), &block)
311
+ index_loaded = true
233
312
 
234
- yield virtual_link
313
+ # 3. Named files, e.g. foo.xnode, name=foo
314
+ elsif match = entry.match(@links.file_filter)
315
+ load_file(match[:name], match[:locale], metadata.delete(match[:key]), &block)
235
316
  end
236
317
  end
318
+
319
+ unless index_loaded
320
+ load_default_index(INDEX, metadata.delete(INDEX), &block)
321
+ end
322
+
323
+ load_virtuals(metadata, &block)
237
324
  end
238
325
  end
239
326
 
240
- def metadata(path)
241
- @cache.fetch_or_store(path.to_s) do
242
- load(path).freeze
243
- end
244
- end
245
-
246
- private
247
-
248
- def symbolize_keys(hash)
249
- # Second level attributes should be symbolic:
250
- hash.each do |key, info|
251
- hash[key] = info.each_with_object({}) { |(k,v),result| result[k.to_sym] = v }
252
- end
253
-
254
- return hash
255
- end
256
-
257
- LINKS_YAML = "links.yaml"
258
-
259
- def load(path)
260
- yaml_path = File.join(path, LINKS_YAML)
261
-
262
- if File.exist?(yaml_path) && data = YAML::load_file(yaml_path)
263
- return symbolize_keys(data)
264
- else
265
- return {}
266
- end
327
+ def load_links(path)
328
+ Resolver.new(self, Path.create(path))
267
329
  end
268
330
  end
269
331
  end