diff --git a/.eslintrc b/.eslintrc index a26890e..377ec71 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,21 +1,31 @@ { + "extends": "eslint:recommended", "rules": { "brace-style": [2, "1tbs", { "allowSingleLine": true }], "strict": 0, "quotes": [2, "single"], "no-underscore-dangle": 0, - "curly": 0 + "curly": 0, + "no-unused-vars": 1, + "no-console": 0, + "no-var": 2 }, "env": { - "browser": true, "node": true, - "jquery": true, "meteor": true, "es6": true }, "globals": { - "Mailer": false + "Mailer": true, + "Utils": true, + "juice": false, + "FlowRouter": false, + "Router": false, + "TemplateHelpers": true, + "SSR": false, + "Picker": false, + "Routing": true } } diff --git a/README.md b/README.md index 2cb86e2..18fa5f8 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Help is appreciated in order to hammer out potential issues and bugs. meteor add lookback:emails ``` -[Annotated source](http://lookback.github.io/meteor-emails/docs/emails.html) +[Annotated source](http://lookback.github.io/meteor-emails/docs/mailer.html) A `Mailer` global will exported on the *server*. diff --git a/docs/docco.css b/docs/docco.css new file mode 100644 index 0000000..a2899ac --- /dev/null +++ b/docs/docco.css @@ -0,0 +1,506 @@ +/*--------------------- Typography ----------------------------*/ + +@font-face { + font-family: 'aller-light'; + src: url('public/fonts/aller-light.eot'); + src: url('public/fonts/aller-light.eot?#iefix') format('embedded-opentype'), + url('public/fonts/aller-light.woff') format('woff'), + url('public/fonts/aller-light.ttf') format('truetype'); + font-weight: normal; + font-style: normal; +} + +@font-face { + font-family: 'aller-bold'; + src: url('public/fonts/aller-bold.eot'); + src: url('public/fonts/aller-bold.eot?#iefix') format('embedded-opentype'), + url('public/fonts/aller-bold.woff') format('woff'), + url('public/fonts/aller-bold.ttf') format('truetype'); + font-weight: normal; + font-style: normal; +} + +@font-face { + font-family: 'novecento-bold'; + src: url('public/fonts/novecento-bold.eot'); + src: url('public/fonts/novecento-bold.eot?#iefix') format('embedded-opentype'), + url('public/fonts/novecento-bold.woff') format('woff'), + url('public/fonts/novecento-bold.ttf') format('truetype'); + font-weight: normal; + font-style: normal; +} + +/*--------------------- Layout ----------------------------*/ +html { height: 100%; } +body { + font-family: "aller-light"; + font-size: 14px; + line-height: 18px; + color: #30404f; + margin: 0; padding: 0; + height:100%; +} +#container { min-height: 100%; } + +a { + color: #000; +} + +b, strong { + font-weight: normal; + font-family: "aller-bold"; +} + +p { + margin: 15px 0 0px; +} + .annotation ul, .annotation ol { + margin: 25px 0; + } + .annotation ul li, .annotation ol li { + font-size: 14px; + line-height: 18px; + margin: 10px 0; + } + +h1, h2, h3, h4, h5, h6 { + color: #112233; + line-height: 1em; + font-weight: normal; + font-family: "novecento-bold"; + text-transform: uppercase; + margin: 30px 0 15px 0; +} + +h1 { + margin-top: 40px; +} + +hr { + border: 0; + background: 1px #ddd; + height: 1px; + margin: 20px 0; +} + +pre, tt, code { + font-size: 12px; line-height: 16px; + font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace; + margin: 0; padding: 0; +} + .annotation pre { + display: block; + margin: 0; + padding: 7px 10px; + background: #fcfcfc; + -moz-box-shadow: inset 0 0 10px rgba(0,0,0,0.1); + -webkit-box-shadow: inset 0 0 10px rgba(0,0,0,0.1); + box-shadow: inset 0 0 10px rgba(0,0,0,0.1); + overflow-x: auto; + } + .annotation pre code { + border: 0; + padding: 0; + background: transparent; + } + + +blockquote { + border-left: 5px solid #ccc; + margin: 0; + padding: 1px 0 1px 1em; +} + .sections blockquote p { + font-family: Menlo, Consolas, Monaco, monospace; + font-size: 12px; line-height: 16px; + color: #999; + margin: 10px 0 0; + white-space: pre-wrap; + } + +ul.sections { + list-style: none; + padding:0 0 5px 0;; + margin:0; +} + +/* + Force border-box so that % widths fit the parent + container without overlap because of margin/padding. + + More Info : http://www.quirksmode.org/css/box.html +*/ +ul.sections > li > div { + -moz-box-sizing: border-box; /* firefox */ + -ms-box-sizing: border-box; /* ie */ + -webkit-box-sizing: border-box; /* webkit */ + -khtml-box-sizing: border-box; /* konqueror */ + box-sizing: border-box; /* css3 */ +} + + +/*---------------------- Jump Page -----------------------------*/ +#jump_to, #jump_page { + margin: 0; + background: white; + -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; + -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; + font: 16px Arial; + cursor: pointer; + text-align: right; + list-style: none; +} + +#jump_to a { + text-decoration: none; +} + +#jump_to a.large { + display: none; +} +#jump_to a.small { + font-size: 22px; + font-weight: bold; + color: #676767; +} + +#jump_to, #jump_wrapper { + position: fixed; + right: 0; top: 0; + padding: 10px 15px; + margin:0; +} + +#jump_wrapper { + display: none; + padding:0; +} + +#jump_to:hover #jump_wrapper { + display: block; +} + +#jump_page { + padding: 5px 0 3px; + margin: 0 0 25px 25px; +} + +#jump_page .source { + display: block; + padding: 15px; + text-decoration: none; + border-top: 1px solid #eee; +} + +#jump_page .source:hover { + background: #f5f5ff; +} + +#jump_page .source:first-child { +} + +/*---------------------- Low resolutions (> 320px) ---------------------*/ +@media only screen and (min-width: 320px) { + .pilwrap { display: none; } + + ul.sections > li > div { + display: block; + padding:5px 10px 0 10px; + } + + ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol { + padding-left: 30px; + } + + ul.sections > li > div.content { + overflow-x:auto; + -webkit-box-shadow: inset 0 0 5px #e5e5ee; + box-shadow: inset 0 0 5px #e5e5ee; + border: 1px solid #dedede; + margin:5px 10px 5px 10px; + padding-bottom: 5px; + } + + ul.sections > li > div.annotation pre { + margin: 7px 0 7px; + padding-left: 15px; + } + + ul.sections > li > div.annotation p tt, .annotation code { + background: #f8f8ff; + border: 1px solid #dedede; + font-size: 12px; + padding: 0 0.2em; + } +} + +/*---------------------- (> 481px) ---------------------*/ +@media only screen and (min-width: 481px) { + #container { + position: relative; + } + body { + background-color: #F5F5FF; + font-size: 15px; + line-height: 21px; + } + pre, tt, code { + line-height: 18px; + } + p, ul, ol { + margin: 0 0 15px; + } + + + #jump_to { + padding: 5px 10px; + } + #jump_wrapper { + padding: 0; + } + #jump_to, #jump_page { + font: 10px Arial; + text-transform: uppercase; + } + #jump_page .source { + padding: 5px 10px; + } + #jump_to a.large { + display: inline-block; + } + #jump_to a.small { + display: none; + } + + + + #background { + position: absolute; + top: 0; bottom: 0; + width: 350px; + background: #fff; + border-right: 1px solid #e5e5ee; + z-index: -1; + } + + ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol { + padding-left: 40px; + } + + ul.sections > li { + white-space: nowrap; + } + + ul.sections > li > div { + display: inline-block; + } + + ul.sections > li > div.annotation { + max-width: 350px; + min-width: 350px; + min-height: 5px; + padding: 13px; + overflow-x: hidden; + white-space: normal; + vertical-align: top; + text-align: left; + } + ul.sections > li > div.annotation pre { + margin: 15px 0 15px; + padding-left: 15px; + } + + ul.sections > li > div.content { + padding: 13px; + vertical-align: top; + border: none; + -webkit-box-shadow: none; + box-shadow: none; + } + + .pilwrap { + position: relative; + display: inline; + } + + .pilcrow { + font: 12px Arial; + text-decoration: none; + color: #454545; + position: absolute; + top: 3px; left: -20px; + padding: 1px 2px; + opacity: 0; + -webkit-transition: opacity 0.2s linear; + } + .for-h1 .pilcrow { + top: 47px; + } + .for-h2 .pilcrow, .for-h3 .pilcrow, .for-h4 .pilcrow { + top: 35px; + } + + ul.sections > li > div.annotation:hover .pilcrow { + opacity: 1; + } +} + +/*---------------------- (> 1025px) ---------------------*/ +@media only screen and (min-width: 1025px) { + + body { + font-size: 16px; + line-height: 24px; + } + + #background { + width: 525px; + } + ul.sections > li > div.annotation { + max-width: 525px; + min-width: 525px; + padding: 10px 25px 1px 50px; + } + ul.sections > li > div.content { + padding: 9px 15px 16px 25px; + } +} + +/*---------------------- Syntax Highlighting -----------------------------*/ + +td.linenos { background-color: #f0f0f0; padding-right: 10px; } +span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } +/* + +github.com style (c) Vasily Polovnyov + +*/ + +pre code { + display: block; padding: 0.5em; + color: #000; + background: #f8f8ff +} + +pre .hljs-comment, +pre .hljs-template_comment, +pre .hljs-diff .hljs-header, +pre .hljs-javadoc { + color: #408080; + font-style: italic +} + +pre .hljs-keyword, +pre .hljs-assignment, +pre .hljs-literal, +pre .hljs-css .hljs-rule .hljs-keyword, +pre .hljs-winutils, +pre .hljs-javascript .hljs-title, +pre .hljs-lisp .hljs-title, +pre .hljs-subst { + color: #954121; + /*font-weight: bold*/ +} + +pre .hljs-number, +pre .hljs-hexcolor { + color: #40a070 +} + +pre .hljs-string, +pre .hljs-tag .hljs-value, +pre .hljs-phpdoc, +pre .hljs-tex .hljs-formula { + color: #219161; +} + +pre .hljs-title, +pre .hljs-id { + color: #19469D; +} +pre .hljs-params { + color: #00F; +} + +pre .hljs-javascript .hljs-title, +pre .hljs-lisp .hljs-title, +pre .hljs-subst { + font-weight: normal +} + +pre .hljs-class .hljs-title, +pre .hljs-haskell .hljs-label, +pre .hljs-tex .hljs-command { + color: #458; + font-weight: bold +} + +pre .hljs-tag, +pre .hljs-tag .hljs-title, +pre .hljs-rules .hljs-property, +pre .hljs-django .hljs-tag .hljs-keyword { + color: #000080; + font-weight: normal +} + +pre .hljs-attribute, +pre .hljs-variable, +pre .hljs-instancevar, +pre .hljs-lisp .hljs-body { + color: #008080 +} + +pre .hljs-regexp { + color: #B68 +} + +pre .hljs-class { + color: #458; + font-weight: bold +} + +pre .hljs-symbol, +pre .hljs-ruby .hljs-symbol .hljs-string, +pre .hljs-ruby .hljs-symbol .hljs-keyword, +pre .hljs-ruby .hljs-symbol .hljs-keymethods, +pre .hljs-lisp .hljs-keyword, +pre .hljs-tex .hljs-special, +pre .hljs-input_number { + color: #990073 +} + +pre .hljs-builtin, +pre .hljs-constructor, +pre .hljs-built_in, +pre .hljs-lisp .hljs-title { + color: #0086b3 +} + +pre .hljs-preprocessor, +pre .hljs-pi, +pre .hljs-doctype, +pre .hljs-shebang, +pre .hljs-cdata { + color: #999; + font-weight: bold +} + +pre .hljs-deletion { + background: #fdd +} + +pre .hljs-addition { + background: #dfd +} + +pre .hljs-diff .hljs-change { + background: #0086b3 +} + +pre .hljs-chunk { + color: #aaa +} + +pre .hljs-tex .hljs-formula { + opacity: 0.5; +} diff --git a/docs/mailer.html b/docs/mailer.html new file mode 100644 index 0000000..5cf7a28 --- /dev/null +++ b/docs/mailer.html @@ -0,0 +1,559 @@ + + + + + mailer.js + + + + + +
+
+ + + + +
+ + diff --git a/docs/public/fonts/aller-bold.eot b/docs/public/fonts/aller-bold.eot new file mode 100644 index 0000000..1b32532 Binary files /dev/null and b/docs/public/fonts/aller-bold.eot differ diff --git a/docs/public/fonts/aller-bold.ttf b/docs/public/fonts/aller-bold.ttf new file mode 100644 index 0000000..dc4cc9c Binary files /dev/null and b/docs/public/fonts/aller-bold.ttf differ diff --git a/docs/public/fonts/aller-bold.woff b/docs/public/fonts/aller-bold.woff new file mode 100644 index 0000000..fa16fd0 Binary files /dev/null and b/docs/public/fonts/aller-bold.woff differ diff --git a/docs/public/fonts/aller-light.eot b/docs/public/fonts/aller-light.eot new file mode 100644 index 0000000..40bd654 Binary files /dev/null and b/docs/public/fonts/aller-light.eot differ diff --git a/docs/public/fonts/aller-light.ttf b/docs/public/fonts/aller-light.ttf new file mode 100644 index 0000000..c2c7290 Binary files /dev/null and b/docs/public/fonts/aller-light.ttf differ diff --git a/docs/public/fonts/aller-light.woff b/docs/public/fonts/aller-light.woff new file mode 100644 index 0000000..81a09d1 Binary files /dev/null and b/docs/public/fonts/aller-light.woff differ diff --git a/docs/public/fonts/novecento-bold.eot b/docs/public/fonts/novecento-bold.eot new file mode 100644 index 0000000..98a9a7f Binary files /dev/null and b/docs/public/fonts/novecento-bold.eot differ diff --git a/docs/public/fonts/novecento-bold.ttf b/docs/public/fonts/novecento-bold.ttf new file mode 100644 index 0000000..2af39b0 Binary files /dev/null and b/docs/public/fonts/novecento-bold.ttf differ diff --git a/docs/public/fonts/novecento-bold.woff b/docs/public/fonts/novecento-bold.woff new file mode 100644 index 0000000..de558b5 Binary files /dev/null and b/docs/public/fonts/novecento-bold.woff differ diff --git a/docs/public/stylesheets/normalize.css b/docs/public/stylesheets/normalize.css new file mode 100644 index 0000000..73abb76 --- /dev/null +++ b/docs/public/stylesheets/normalize.css @@ -0,0 +1,375 @@ +/*! normalize.css v2.0.1 | MIT License | git.io/normalize */ + +/* ========================================================================== + HTML5 display definitions + ========================================================================== */ + +/* + * Corrects `block` display not defined in IE 8/9. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section, +summary { + display: block; +} + +/* + * Corrects `inline-block` display not defined in IE 8/9. + */ + +audio, +canvas, +video { + display: inline-block; +} + +/* + * Prevents modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/* + * Addresses styling for `hidden` attribute not present in IE 8/9. + */ + +[hidden] { + display: none; +} + +/* ========================================================================== + Base + ========================================================================== */ + +/* + * 1. Sets default font family to sans-serif. + * 2. Prevents iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ + -ms-text-size-adjust: 100%; /* 2 */ +} + +/* + * Removes default margin. + */ + +body { + margin: 0; +} + +/* ========================================================================== + Links + ========================================================================== */ + +/* + * Addresses `outline` inconsistency between Chrome and other browsers. + */ + +a:focus { + outline: thin dotted; +} + +/* + * Improves readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/* ========================================================================== + Typography + ========================================================================== */ + +/* + * Addresses `h1` font sizes within `section` and `article` in Firefox 4+, + * Safari 5, and Chrome. + */ + +h1 { + font-size: 2em; +} + +/* + * Addresses styling not present in IE 8/9, Safari 5, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/* + * Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/* + * Addresses styling not present in Safari 5 and Chrome. + */ + +dfn { + font-style: italic; +} + +/* + * Addresses styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + + +/* + * Corrects font family set oddly in Safari 5 and Chrome. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, serif; + font-size: 1em; +} + +/* + * Improves readability of pre-formatted text in all browsers. + */ + +pre { + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; +} + +/* + * Sets consistent quote types. + */ + +q { + quotes: "\201C" "\201D" "\2018" "\2019"; +} + +/* + * Addresses inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/* + * Prevents `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* ========================================================================== + Embedded content + ========================================================================== */ + +/* + * Removes border when inside `a` element in IE 8/9. + */ + +img { + border: 0; +} + +/* + * Corrects overflow displayed oddly in IE 9. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* ========================================================================== + Figures + ========================================================================== */ + +/* + * Addresses margin not present in IE 8/9 and Safari 5. + */ + +figure { + margin: 0; +} + +/* ========================================================================== + Forms + ========================================================================== */ + +/* + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/* + * 1. Corrects color not being inherited in IE 8/9. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/* + * 1. Corrects font family not being inherited in all browsers. + * 2. Corrects font size not being inherited in all browsers. + * 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome + */ + +button, +input, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 2 */ + margin: 0; /* 3 */ +} + +/* + * Addresses Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +button, +input { + line-height: normal; +} + +/* + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Corrects inability to style clickable `input` types in iOS. + * 3. Improves usability and consistency of cursor style between image-type + * `input` and others. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/* + * Re-set default cursor for disabled elements. + */ + +button[disabled], +input[disabled] { + cursor: default; +} + +/* + * 1. Addresses box sizing set to `content-box` in IE 8/9. + * 2. Removes excess padding in IE 8/9. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/* + * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome. + * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome + * (include `-moz` to future-proof). + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/* + * Removes inner padding and search cancel button in Safari 5 and Chrome + * on OS X. + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* + * Removes inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/* + * 1. Removes default vertical scrollbar in IE 8/9. + * 2. Improves readability and alignment in all browsers. + */ + +textarea { + overflow: auto; /* 1 */ + vertical-align: top; /* 2 */ +} + +/* ========================================================================== + Tables + ========================================================================== */ + +/* + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} \ No newline at end of file diff --git a/docs/routing.html b/docs/routing.html new file mode 100644 index 0000000..3cf7273 --- /dev/null +++ b/docs/routing.html @@ -0,0 +1,216 @@ + + + + + Routes + + + + + +
+
+ + + + +
+ + diff --git a/docs/template-helpers.html b/docs/template-helpers.html new file mode 100644 index 0000000..ba243ff --- /dev/null +++ b/docs/template-helpers.html @@ -0,0 +1,112 @@ + + + + + Template helpers + + + + + +
+
+ + + + +
+ + diff --git a/docs/utils.html b/docs/utils.html new file mode 100644 index 0000000..cfc9bd0 --- /dev/null +++ b/docs/utils.html @@ -0,0 +1,315 @@ + + + + + Utils package for `lookback:emails` + + + + + +
+
+ + + + +
+ + diff --git a/emails.coffee b/emails.coffee deleted file mode 100644 index d232b52..0000000 --- a/emails.coffee +++ /dev/null @@ -1,421 +0,0 @@ -# `lookback:emails` is a small package for Meteor which helps you -# tremendously in the process of building, testing and debugging -# HTML emails in Meteor applications. -# -# See the [GitHub repo](https://github.com/lookback/meteor-emails) for README. -# Made by Johan Brook for [Lookback](https://github.com/lookback). - -TAG = 'mailer' - -CONTENT_TYPES = { - html: 'text/html', - text: 'text/plain' -} - -# ## Setup - -# Main exported symbol with some initial settings: -# -# - `routePrefix` is the top level path for the preview and send routes (see further down). -# - `baseUrl` is what root domain to base relative paths from. -# - `testEmail`, when testing emails, set this variable. -# - `logger`, optionally inject an external logger. Defaults to `console`. -# - `disabled`, optionally disable the actual email sending. Useful for E2E testing. Defaults to `false`. -# - `addRoutes`, should we add preview and send routes? Defaults to `true` in development. -Mailer = - settings: - silent: false - routePrefix: 'emails' - baseUrl: process.env.ROOT_URL - testEmail: null - logger: console - disabled: false - addRoutes: process.env.NODE_ENV is 'development' - language: 'html' - plainText: true - plainTextOpts: {} - juiceOpts: - preserveMediaQueries: true - removeStyleTags: true - webResources: - images: false - - config: (newSettings) -> - @settings = _.extend(@settings, newSettings) - -# ## Deps -# -Utils = share.MailerUtils - -# ## Template helpers -# -# Built-in template helpers. -Helpers = - - # `baseUrl` gives you a full absolute URL from a relative path. - # - # {{ baseUrl '/some-path' }} => http://root-domain.com/some-path - baseUrl: (path) -> - Utils.joinUrl(Mailer.settings.baseUrl, path) - - # `emailUrlFor` takes an Iron Router route (with optional params) and - # creates an absolute URL. - # - # {{ emailUrlFor 'myRoute' param='foo' }} => http://root-domain.com/my-route/foo - emailUrlFor: (routeName, params) -> - # if Iron Router - theRouter = null - if Package['iron:router'] - theRouter = Router - else if Package['kadira:flow-router'] - theRouter = FlowRouter - - if theRouter && theRouter.path - Utils.joinUrl(Mailer.settings.baseUrl, theRouter.path.call(theRouter, routeName, params.hash)) - else - Utils.Logger.warn("We noticed that neither Iron Router nor FlowRouter is installed, thus 'emailUrlFor' can't render a path to the route '#{routeName}'.", TAG) - return '#' - -# # The mailer -# -# This is the "blueprint" of the Mailer object. It has the following interface: -# -# - `precompile` -# - `render` -# - `send` -# -# As you can see, the mailer takes care of precompiling and rendering templates -# with data, as well as sending emails from those templates. - -MailerClass = (options) -> - check options, Match.ObjectIncluding( - # Mailer *must* take a `templates` object with template names as keys. - templates: Object - # Take optional template helpers. - helpers: Match.Optional Object - # Take an optional layoute template object. - layout: Match.Optional Match.OneOf(Object, Boolean) - ) - - settings = _.extend({}, Mailer.settings, options.settings) - blazeHelpers = if typeof Blaze isnt 'undefined' then Blaze._globalHelpers else {} - globalHelpers = _.extend({}, Helpers, blazeHelpers, options.helpers) - - Utils.setupLogger(settings.logger, suppressInfo: settings.silent) - - addHelpers = (template) -> - check template.name, String - check template.helpers, Match.Optional Object - - # Use the built-in helpers, any global Blaze helpers, and injected helpers - # from options, and *additional* template helpers, and apply them to - # the template. - Template[template.name].helpers _.extend({}, globalHelpers, template.helpers) - - # ## Compile - # - # Function for compiling a template with a name and path to - # a HTML file to a template function, to be placed - # in the Template namespace. - # - # A `template` must have a path to a template HTML file, and - # can optionally have paths to any SCSS and CSS stylesheets. - compile = (template) -> - check template, Match.ObjectIncluding( - path: String - name: String - scss: Match.Optional String - css: Match.Optional String - layout: Match.Optional Match.OneOf(Boolean, - name: String - path: String - scss: Match.Optional String - css: Match.Optional String - ) - ) - - # Read the template as a string. - try - content = Utils.readFile template.path - catch ex - Utils.Logger.error 'Could not read template file: '+template.path, TAG - return false - - layout = template.layout or options.layout - - if layout and template.layout isnt false - layoutContent = Utils.readFile(layout.path) - - SSR.compileTemplate(layout.name, layoutContent, language: settings.language) - addHelpers layout - - - # This will place the template function in - # - # Template. - tmpl = SSR.compileTemplate(template.name, content, language: settings.language) - - # Add helpers to template. - addHelpers template - - return tmpl - - # ## Render - # - # Render a template by name, with optional data context. - # Will compile the template if not done already. - render = (templateName, data) -> - check templateName, String - check data, Match.Optional Object - - template = _.findWhere(options.templates, name: templateName) - - if !templateName of Template - compile template - - tmpl = Template[templateName] - - if not tmpl - throw new Meteor.Error 500, 'Could not find template: '+templateName - - rendered = SSR.render tmpl, data - layout = template.layout or options.layout - - if layout and template.layout isnt false - # When applying to a layout, some info from the template - # (like the first preview lines) needs to be applied to the - # layout scope as well. - # - # Thus we fetch a `preview` helper from the template or - # `preview` prop in the data context to apply to the layout. - if tmpl.__helpers.has 'preview' - preview = tmpl.__helpers.get('preview') - else if data.preview - preview = data.preview - - # The `extraCSS` property on a `template` is applied to - # the layout in `