PageRenderTime 51ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/template/helpers/index.js

http://github.com/mde/geddy
JavaScript | 330 lines | 148 code | 36 blank | 146 comment | 24 complexity | c9aa1821cffd313e130a68a2eda39466 MD5 | raw file
Possible License(s): MIT
  1. /**
  2. * Geddy JavaScript Web development framework
  3. * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://http://apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. (function() {
  19. 'use strict';
  20. var utils = require('utilities')
  21. , path = require('path')
  22. , helperUtils = require('./utils')
  23. , flashUtils = require('./flash')
  24. , Data
  25. , _config = {}
  26. , _getAssetPath;
  27. _getAssetPath = function (assetType, src) {
  28. var host
  29. , basePath
  30. , hasProto = /^http:\/\/|^https:\/\/|^data:/
  31. , isAbs
  32. , assetPath;
  33. // Does not handle exotic protocols like SPDY, or file:// URLs
  34. isAbs = hasProto.test(src) || utils.file.isAbsolute(src);
  35. if (isAbs) {
  36. return src;
  37. }
  38. host = _config.assetHost || ''
  39. basePath = _config.assetBasePath || '/';
  40. // Include poss. extra leading slash in path.join to ensure
  41. // there's at least one
  42. assetPath = host + path.join('/', basePath, assetType, src);
  43. // If we are running server on MS Windows it generates asset paths \ instead of /
  44. // some browsers (for example FF 27.0.1) is sending this symbols as %5C in GET request
  45. // which results in 404 from server, but / is usable on any OS.
  46. return process.platform === 'win32' ? assetPath.replace(/\\/g, '/') : assetPath;
  47. };
  48. /**
  49. @name helpers
  50. @namespace helpers
  51. */
  52. // Copy a data object so it can be used in helpers
  53. exports.registerData = {
  54. name: 'registerData',
  55. action: function (data) {
  56. helperUtils.setConfig(_config);
  57. Data = data;
  58. helperUtils.registerData(data);
  59. }
  60. }
  61. /***
  62. @name helpers#urlFor
  63. @public
  64. @function
  65. @return {String} A path of the URL is returned
  66. @description Returns a URL based on the `options` provided
  67. @param {String/Object} options
  68. @param {String} [options] Simply returns the string, unless the string is `back`
  69. then a link to the previous url is returned
  70. @param {Boolean} [options.relpath=false] If true, the relative URL is returned
  71. @param {String} [options.protocol] The protocol to use(Uses Geddy's current protocol('http' default))
  72. @param {String} [options.username] Includes a username in the path. Requires `password` or
  73. it'll be ignored
  74. @param {String} [options.password] Includes a password in the path. Requires `username` or
  75. it'll be ignored
  76. @param {String} [options.subdomain] Specify a subdomain to prepend to `domain`
  77. @param {String} [options.domain] Specify a domain to use. Required if `relPath` is false(Uses
  78. Geddy's `hostname` option as default)
  79. @param {String} [options.host] Alias for `domain`
  80. @param {Integer} [options.port] Specify a port to connect to
  81. @param {String} [options.controller] Specify the controller to use for the path(Uses the current
  82. controller, but only if `action` or `id` are also being used)
  83. @param {String} [options.action] Specify the action to use for the path(Uses the index action if
  84. a `controller` and no `id` is given, uses the show action if
  85. a `id` action is given but no `action` option)
  86. @param {String} [options.id] Specify an ID to use for the path
  87. @param {Boolean} [options.trailingSlash=false] If true, a "/" will be appended to the end of the path
  88. @param {String} [options.fragment] Appends a fragment to the end of the path e,g: "#string"
  89. @param {String} [options.anchor] Alias for `fragment`
  90. */
  91. exports.urlFor = {
  92. name: 'urlFor',
  93. action: function (options) {
  94. return helperUtils.urls.urlFor(options);
  95. }
  96. }
  97. /**
  98. @name helpers#contentTag
  99. @public
  100. @function
  101. @return {String} A HTML `tag` with the given `content` and `htmlOptions`
  102. @description Creates a HTML tag with all the give options
  103. @param {String} tag The HTML tag to use, safe to use any tag with this
  104. @param {String} content The content to use with the tag, if it's a self closing tag
  105. special cases will be used for content e,g: 'src' attribute is content for images
  106. @param {Object} htmlOptions Includes any HTML attribute you want to include
  107. */
  108. exports.contentTag = {
  109. name: 'contentTag',
  110. action: function (tag, content, htmlOptions) {
  111. return helperUtils.tags.contentTagString(tag, content, htmlOptions);
  112. }
  113. }
  114. /**
  115. @name helpers#selectTag
  116. @public
  117. @function
  118. @return {String} A HTML `select tag` with the given `optionsArray` and `htmlOptions`
  119. @description Creates a HTML select tag using the given `optionsArray` to create HTML option elements.
  120. Example: selectTag(['open', 'close'], todo.status, { class:'span6', name:'status' })
  121. @param {Array} optionsArray The array options used to generate the tag elements.
  122. It could be an array of strings, numbers or an object with value and text properties to be used
  123. for the value attribute and option element content respectively.
  124. @param {String} selectedOption optionally specify the selected option
  125. @param {Object} htmlOptions Includes any HTML attribute you want to include in the select tag
  126. */
  127. exports.selectTag = {
  128. name: 'selectTag',
  129. action: function (optionsArray, selectedOption, htmlOptions) {
  130. return helperUtils.tags.selectTagString(optionsArray, selectedOption, htmlOptions);
  131. }
  132. }
  133. /**
  134. @name helpers#linkTo
  135. @public
  136. @function
  137. @return {String} A HTML tag with a link to `options`
  138. @description Creates a HTML tag that links to `options` with `content` as the content and includes
  139. the given `htmlOptions`
  140. @param {String} content The content to include for the link
  141. @param {String/Object} options Creates the URL to link to, look at `urlFor` for more details
  142. @param {Object} htmlOptions Includes any HTML attribute you want to include
  143. */
  144. exports.linkTo = {
  145. name: 'linkTo',
  146. action: function (content, options, htmlOptions) {
  147. var opts = options || {}
  148. , htmlOpts = htmlOptions || {}
  149. , url;
  150. // This is for imageLink to avoid escaping
  151. // FIXME: Kinda stupid putting this in htmlOptions, but options is taken.
  152. if(htmlOpts._escapeContent !== false) {
  153. content = utils.string.escapeXML(content);
  154. delete htmlOpts._escapeContent;
  155. }
  156. // If options is a function, assume it was from a action helper
  157. if (typeof opts === 'function') {
  158. opts = String(opts());
  159. }
  160. url = exports.urlFor.action(opts);
  161. htmlOpts.href = htmlOpts.href || url;
  162. return exports.contentTag.action('a', content, htmlOpts);
  163. }
  164. };
  165. /**
  166. @name helpers#scriptLink
  167. @public
  168. @function
  169. @return {String} A HTML script tag pointing to `source`
  170. @description Creates a HTML script tag pointing to `source` with all the give `htmlOptions`
  171. @param {String} source The URL to point to
  172. @param {Object} htmlOptions Includes any HTML attribute you want to include
  173. */
  174. exports.scriptLink = {
  175. name: 'scriptLink',
  176. action: function (source, htmlOptions) {
  177. var opts = htmlOptions || {}
  178. , src = _getAssetPath('js', source);
  179. utils.mixin(opts, {src: src});
  180. return exports.contentTag.action('script', '', opts);
  181. }
  182. };
  183. /**
  184. @name helpers#styleLink
  185. @public
  186. @function
  187. @return {String} A HTML link tag pointing to `source`
  188. @description Creates a HTML link tag pointing to `source` with all the give `htmlOptions`
  189. @param {String} source The URL to point to
  190. @param {Object} htmlOptions Includes any HTML attribute you want to include
  191. */
  192. exports.styleLink = {
  193. name: 'styleLink',
  194. action: function (source, htmlOptions) {
  195. var opts = htmlOptions || {}
  196. , src = _getAssetPath('css', source);
  197. return exports.contentTag.action('link', src, opts);
  198. }
  199. };
  200. /**
  201. @name helpers#imageTag
  202. @public
  203. @function
  204. @return {String} A HTML img tag pointing to `source`
  205. @description Creates a HTML img tag pointing to `source` with all the give `htmlOptions`
  206. @param {String} source The image URL
  207. @param {Object} htmlOptions Includes any HTML attribute you want to include
  208. @param {String} size Creates a width and height from the given size, the style must be in the
  209. format "{width}x{height}"(e,g: '40x50') or simply a single size(uses the
  210. size as both width and height.) if the size doesn't follow either format
  211. it'll be ignored
  212. */
  213. exports.imageTag = {
  214. name: 'imageTag',
  215. action: function (source, htmlOptions) {
  216. var opts = htmlOptions || {}
  217. , src = _getAssetPath('img', source);
  218. // If size option is included
  219. if('size' in opts) {
  220. var size = opts.size
  221. , pat = /([0-9]+x[0-9]*|[0-9]+)/;
  222. if (size.match(pat)) {
  223. delete opts.size;
  224. if (size.match(/[0-9]+x[0-9]*/)) {
  225. // It's separate width and height
  226. opts.width = opts.width || size.replace(/x[0-9]*/, '');
  227. opts.height = opts.height || size.replace(/[0-9]+x/, '');
  228. }
  229. else {
  230. // Same size width and height
  231. opts.width = opts.width || size;
  232. opts.height = opts.height || size;
  233. }
  234. }
  235. else {
  236. delete opts.size;
  237. }
  238. }
  239. return exports.contentTag.action('img', src, opts);
  240. }
  241. }
  242. /**
  243. @name helpers#imageLink
  244. @public
  245. @function
  246. @return {String} A HTML link tag pointing to `link` with the content as the image in `source`
  247. @description Creates a HTML link tag pointing to `link` with all the give `linkOptions` and includes
  248. the content as the image from `source` and it's `imageOptions`
  249. @param {String} source The image URL
  250. @param {String} link the URL to point to
  251. @param {Object} imageOptions Includes any HTML attribute you want to include(Supports the `size`
  252. option availble in `imageTag`)
  253. @param {Object} linkOptions Includes any HTML attribute you want to include
  254. */
  255. exports.imageLink = {
  256. name: 'imageLink',
  257. action: function (source, link, imageOptions, linkOptions) {
  258. imageOptions = imageOptions || {};
  259. linkOptions = linkOptions || {};
  260. // If link is a function, assume it was from a action helper
  261. if (typeof link === 'function') {
  262. link = String(link());
  263. }
  264. linkOptions = utils.object.merge(linkOptions, { href: link });
  265. linkOptions._escapeContent = false;
  266. var imageTag = exports.imageTag.action(source, imageOptions);
  267. return exports.linkTo.action(imageTag, link, linkOptions)
  268. }
  269. }
  270. // Docs at utils.string.truncate
  271. exports.truncate = {
  272. name: 'truncate',
  273. action: utils.string.truncate
  274. };
  275. // Docs at utils.string.truncateHTML
  276. exports.truncateHTML = {
  277. name: 'truncateHTML',
  278. action: utils.string.truncateHTML
  279. };
  280. exports.displayFlash = {
  281. name: 'displayFlash'
  282. , action: flashUtils.displayFlash
  283. };
  284. exports.t = {
  285. name: 't'
  286. , action: function () {
  287. var i18n = this.i18n;
  288. return i18n.t.apply(i18n, arguments);
  289. }
  290. };
  291. exports.setConfig = function (c) {
  292. _config = c;
  293. };
  294. }());