├── site ├── data │ └── .gitkeep ├── source │ ├── logo │ │ ├── icon.ico │ │ ├── icon.png │ │ ├── logo.png │ │ └── main-logo.png │ ├── changelog.md │ └── guide │ │ ├── introduction.md │ │ ├── routing.md │ │ ├── reusing-code.md │ │ ├── smart-components.md │ │ └── understanding-blaze.md ├── .gitignore ├── scripts │ ├── parseTagOptions.js │ ├── changelog.js │ └── dl.js ├── assets │ ├── theme-colors.less │ └── api-box.html ├── jsdoc │ ├── jsdoc-conf.json │ ├── jsdoc.sh │ └── docdata-jsdoc-template │ │ └── publish.js ├── README.md ├── package.json └── _config.yml ├── packages ├── blaze │ ├── .gitignore │ ├── .npm │ │ └── package │ │ │ ├── .gitignore │ │ │ ├── README │ │ │ └── npm-shrinkwrap.json │ ├── backcompat.js │ ├── README.md │ ├── .versions │ ├── preamble.js │ ├── package.js │ ├── exceptions.js │ ├── view_tests.js │ └── blaze.d.ts ├── htmljs │ ├── .gitignore │ ├── package.js │ ├── .versions │ ├── preamble.js │ └── htmljs_test.js ├── ui │ ├── .gitignore │ ├── README.md │ ├── package.js │ └── .versions ├── blaze-tools │ ├── .gitignore │ ├── README.md │ ├── preamble.js │ ├── package.js │ ├── .versions │ ├── token_tests.js │ └── tojs.js ├── html-tools │ ├── .gitignore │ ├── package.js │ ├── templatetag.js │ ├── main.js │ ├── .versions │ ├── utils.js │ ├── scanner.js │ └── charref_tests.js ├── spacebars │ ├── .gitignore │ ├── README.md │ ├── package.js │ ├── .versions │ └── spacebars_tests.js ├── observe-sequence │ ├── .gitignore │ ├── README.md │ ├── package.js │ └── .versions ├── spacebars-tests │ ├── .gitignore │ ├── README.md │ ├── assets │ │ ├── markdown_each1.html │ │ ├── markdown_if2.html │ │ ├── markdown_each2.html │ │ ├── markdown_if1.html │ │ └── markdown_basic.html │ ├── template_tests_server.js │ ├── package.js │ ├── .versions │ └── async_tests.html ├── spacebars-compiler │ ├── .gitignore │ ├── .npm │ │ └── package │ │ │ ├── .gitignore │ │ │ ├── npm-shrinkwrap.json │ │ │ └── README │ ├── preamble.js │ ├── README.md │ ├── package.js │ ├── .versions │ ├── react.js │ ├── whitespace.js │ ├── compiler.js │ └── compile_tests.js ├── templating-runtime │ ├── .gitignore │ ├── .npm │ │ └── package │ │ │ ├── .gitignore │ │ │ ├── npm-shrinkwrap.json │ │ │ └── README │ ├── dynamic.html │ ├── dynamic.js │ ├── .versions │ ├── package.js │ └── dynamic_tests.html ├── templating-tools │ ├── .npm │ │ └── package │ │ │ ├── .gitignore │ │ │ ├── npm-shrinkwrap.json │ │ │ └── README │ ├── throw-compile-error.js │ ├── templating-tools.js │ ├── package.js │ ├── .versions │ ├── code-generation.js │ ├── compile-tags-with-spacebars.js │ ├── README.md │ └── html-scanner.js ├── caching-html-compiler │ ├── .npm │ │ └── package │ │ │ ├── .gitignore │ │ │ ├── npm-shrinkwrap.json │ │ │ └── README │ ├── .versions │ ├── package.js │ ├── README.md │ └── caching-html-compiler.js ├── templating-compiler │ ├── compile-templates.js │ ├── package.js │ └── .versions ├── blaze-html-templates │ ├── package.js │ ├── README.md │ └── .versions ├── blaze-hot │ ├── package.js │ ├── .versions │ ├── hot.js │ └── update-templates.js └── templating │ ├── README.md │ ├── package.js │ └── .versions ├── test-app ├── .meteor │ ├── .gitignore │ ├── release │ ├── platforms │ ├── .id │ ├── .finished-upgraders │ ├── packages │ └── versions ├── package.json └── puppeteerRunner.js ├── images ├── icon.png ├── architecture_packages.png ├── architecture-static-html.png ├── architecture-templating-tools.png ├── logo-wide.svg └── logo.svg ├── .gitignore ├── .gitmodules ├── publish-all.sh ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ └── ISSUE_TEMPLATE.md ├── FUNDING.yml ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── blaze-tests.yml ├── OVERVIEW.md ├── LICENSE ├── DEPLOYMENT.md ├── SECURITY.md ├── CONTRIBUTING.md └── CODE_OF_CONDUCT.md /site/data/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/blaze/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/htmljs/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/ui/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /test-app/.meteor/.gitignore: -------------------------------------------------------------------------------- 1 | local 2 | -------------------------------------------------------------------------------- /packages/blaze-tools/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/html-tools/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/spacebars/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/observe-sequence/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/spacebars-tests/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /test-app/.meteor/release: -------------------------------------------------------------------------------- 1 | METEOR@3.0-rc.2 2 | -------------------------------------------------------------------------------- /packages/spacebars-compiler/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/templating-runtime/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /test-app/.meteor/platforms: -------------------------------------------------------------------------------- 1 | server 2 | browser 3 | -------------------------------------------------------------------------------- /packages/blaze/.npm/package/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /packages/spacebars-compiler/.npm/package/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /packages/templating-runtime/.npm/package/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /packages/templating-tools/.npm/package/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /packages/caching-html-compiler/.npm/package/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /packages/spacebars-tests/README.md: -------------------------------------------------------------------------------- 1 | This is an internal Meteor package. -------------------------------------------------------------------------------- /images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meteor/blaze/HEAD/images/icon.png -------------------------------------------------------------------------------- /site/source/logo/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meteor/blaze/HEAD/site/source/logo/icon.ico -------------------------------------------------------------------------------- /site/source/logo/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meteor/blaze/HEAD/site/source/logo/icon.png -------------------------------------------------------------------------------- /site/source/logo/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meteor/blaze/HEAD/site/source/logo/logo.png -------------------------------------------------------------------------------- /site/source/logo/main-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meteor/blaze/HEAD/site/source/logo/main-logo.png -------------------------------------------------------------------------------- /images/architecture_packages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meteor/blaze/HEAD/images/architecture_packages.png -------------------------------------------------------------------------------- /images/architecture-static-html.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meteor/blaze/HEAD/images/architecture-static-html.png -------------------------------------------------------------------------------- /site/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Thumbs.db 3 | db.json 4 | *.log 5 | node_modules/ 6 | public/ 7 | .deploy*/ 8 | data 9 | -------------------------------------------------------------------------------- /images/architecture-templating-tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meteor/blaze/HEAD/images/architecture-templating-tools.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Thumbs.db 3 | db.json 4 | *.log 5 | .idea 6 | test-app/packages 7 | node_modules 8 | package-lock.json 9 | .env -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "site/themes/meteor"] 2 | path = site/themes/meteor 3 | url = https://github.com/meteor/hexo-theme-meteor.git 4 | -------------------------------------------------------------------------------- /packages/blaze-tools/README.md: -------------------------------------------------------------------------------- 1 | # blaze-tools 2 | 3 | Compile-time utilities that are likely to be useful to any package 4 | that compiles templates for Blaze. 5 | -------------------------------------------------------------------------------- /site/source/changelog.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Changelog 3 | description: 4 | --- 5 | 6 | {%- changelog '../HISTORY.md' %} 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/ui/README.md: -------------------------------------------------------------------------------- 1 | # ui 2 | [Source code of released version](https://github.com/meteor/meteor/tree/master/packages/ui) | [Source code of development version](https://github.com/meteor/meteor/tree/devel/packages/ui) 3 | *** 4 | 5 | This is an internal Meteor package. -------------------------------------------------------------------------------- /packages/observe-sequence/README.md: -------------------------------------------------------------------------------- 1 | # observe-sequence 2 | [Source code of released version](https://github.com/meteor/meteor/tree/master/packages/observe-sequence) | [Source code of development version](https://github.com/meteor/meteor/tree/devel/packages/observe-sequence) 3 | *** 4 | 5 | This is an internal Meteor package. -------------------------------------------------------------------------------- /packages/spacebars-tests/assets/markdown_each1.html: -------------------------------------------------------------------------------- 1 |

2 | 3 | 7 | 8 |

some paragraph to fix showdown's four space parsing below.

9 | 10 |
<b></b>
11 | 
12 | 13 |

``

14 | 15 |

<b></b>

16 | -------------------------------------------------------------------------------- /packages/spacebars/README.md: -------------------------------------------------------------------------------- 1 | # Spacebars 2 | 3 | Spacebars is a Meteor template language inspired by [Handlebars](http://handlebarsjs.com/). It shares some of the spirit and syntax of Handlebars, but it has been tailored to produce reactive Meteor templates when compiled. 4 | 5 | Read more on the [Spacebars](http://blazejs.org/api/spacebars.html). -------------------------------------------------------------------------------- /packages/templating-compiler/compile-templates.js: -------------------------------------------------------------------------------- 1 | /* global CachingHtmlCompiler TemplatingTools */ 2 | Plugin.registerCompiler({ 3 | extensions: ['html'], 4 | archMatching: 'web', 5 | isTemplate: true, 6 | }, () => new CachingHtmlCompiler( 7 | 'templating', 8 | TemplatingTools.scanHtmlForTags, 9 | TemplatingTools.compileTagsWithSpacebars 10 | )); 11 | -------------------------------------------------------------------------------- /test-app/.meteor/.id: -------------------------------------------------------------------------------- 1 | # This file contains a token that is unique to your project. 2 | # Check it into your repository along with the rest of this directory. 3 | # It can be used for purposes such as: 4 | # - ensuring you don't accidentally deploy one app on top of another 5 | # - providing package authors with aggregated statistics 6 | 7 | ourgjhbe7m.zzee6dwnngho 8 | -------------------------------------------------------------------------------- /packages/spacebars-compiler/.npm/package/npm-shrinkwrap.json: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 4, 3 | "dependencies": { 4 | "uglify-js": { 5 | "version": "3.16.1", 6 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.1.tgz", 7 | "integrity": "sha512-X5BGTIDH8U6IQ1TIRP62YC36k+ULAa1d59BxlWvPUJ1NkW5L3FwcGfEzuVvGmhJFBu0YJ5Ge25tmRISqCmLiRQ==" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/templating-runtime/.npm/package/npm-shrinkwrap.json: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 4, 3 | "dependencies": { 4 | "lodash.has": { 5 | "version": "4.5.2", 6 | "resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz", 7 | "integrity": "sha512-rnYUdIo6xRCJnQmbVFEwcxF144erlD+M3YcJUVesflU9paQaE8p+fJDcIQrlMYbxoANFL+AB9hZrzSBBk5PL+g==" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/templating-tools/.npm/package/npm-shrinkwrap.json: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 4, 3 | "dependencies": { 4 | "lodash.isempty": { 5 | "version": "4.4.0", 6 | "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", 7 | "integrity": "sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /site/scripts/parseTagOptions.js: -------------------------------------------------------------------------------- 1 | // sort of hacky but allows x:y 2 | module.exports = function(args) { 3 | if (args.length === 0) { 4 | return {}; 5 | } 6 | var argsJson = '{"' + args.join('","').replace(/:/g, '":"') + '"}'; 7 | try { 8 | return JSON.parse(argsJson); 9 | } catch (e) { 10 | console.error(args, argsJson); 11 | throw new Error("Couldn't parse arguments"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/caching-html-compiler/.npm/package/npm-shrinkwrap.json: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 4, 3 | "dependencies": { 4 | "lodash.isempty": { 5 | "version": "4.4.0", 6 | "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", 7 | "integrity": "sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/spacebars-tests/assets/markdown_if2.html: -------------------------------------------------------------------------------- 1 |

true

2 | 3 |

true

4 | 5 | 9 | 10 |

some paragraph to fix showdown's four space parsing below.

11 | 12 |
true
13 | 
14 | <b>true</b>
15 | 
16 | 17 |

true

18 | 19 |

<b>true</b>

20 | -------------------------------------------------------------------------------- /packages/spacebars-tests/assets/markdown_each2.html: -------------------------------------------------------------------------------- 1 |

item

2 | 3 |

item

4 | 5 | 9 | 10 |

some paragraph to fix showdown's four space parsing below.

11 | 12 |
item
13 | 
14 | <b>item</b>
15 | 
16 | 17 |

item

18 | 19 |

<b>item</b>

20 | -------------------------------------------------------------------------------- /publish-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -u 5 | 6 | # the order is important 7 | for package in htmljs html-tools blaze-tools spacebars-compiler templating-tools caching-html-compiler observe-sequence blaze spacebars templating-compiler templating-runtime blaze-hot templating spacebars-tests blaze-html-templates ui ; do 8 | echo "Publishing $package" 9 | (cd packages/$package && meteor publish) 10 | done 11 | -------------------------------------------------------------------------------- /packages/spacebars-tests/assets/markdown_if1.html: -------------------------------------------------------------------------------- 1 |

false

2 | 3 |

false

4 | 5 | 9 | 10 |

some paragraph to fix showdown's four space parsing below.

11 | 12 |
false
13 | 
14 | <b>false</b>
15 | 
16 | 17 |

false

18 | 19 |

<b>false</b>

20 | -------------------------------------------------------------------------------- /site/scripts/changelog.js: -------------------------------------------------------------------------------- 1 | /* global hexo */ 2 | 3 | var fs = require('fs'); 4 | var showdown = require('showdown'); 5 | var converter = new showdown.Converter(); 6 | 7 | // Read the file given, strip of #vNEXT, render w/ markdown 8 | hexo.extend.tag.register('changelog', function(args) { 9 | var str = fs.readFileSync(args[0], 'utf8'); 10 | str = str.replace('## v.NEXT', ''); 11 | return converter.makeHtml(str); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/blaze/.npm/package/README: -------------------------------------------------------------------------------- 1 | This directory and the files immediately inside it are automatically generated 2 | when you change this package's NPM dependencies. Commit the files in this 3 | directory (npm-shrinkwrap.json, .gitignore, and this README) to source control 4 | so that others run the same versions of sub-dependencies. 5 | 6 | You should NOT check in the node_modules directory that Meteor automatically 7 | creates; if you are using git, the .gitignore file tells git to ignore it. 8 | -------------------------------------------------------------------------------- /packages/blaze-html-templates/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'blaze-html-templates', 3 | summary: "Compile HTML templates into reactive UI with Meteor Blaze", 4 | version: '3.0.0', 5 | git: 'https://github.com/meteor/blaze.git' 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.imply([ 10 | // A library for reactive user interfaces 11 | 'blaze@3.0.0', 12 | 13 | // Compile .html files into Blaze reactive views 14 | 'templating@1.4.4' 15 | ]); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/spacebars-compiler/.npm/package/README: -------------------------------------------------------------------------------- 1 | This directory and the files immediately inside it are automatically generated 2 | when you change this package's NPM dependencies. Commit the files in this 3 | directory (npm-shrinkwrap.json, .gitignore, and this README) to source control 4 | so that others run the same versions of sub-dependencies. 5 | 6 | You should NOT check in the node_modules directory that Meteor automatically 7 | creates; if you are using git, the .gitignore file tells git to ignore it. 8 | -------------------------------------------------------------------------------- /packages/templating-runtime/.npm/package/README: -------------------------------------------------------------------------------- 1 | This directory and the files immediately inside it are automatically generated 2 | when you change this package's NPM dependencies. Commit the files in this 3 | directory (npm-shrinkwrap.json, .gitignore, and this README) to source control 4 | so that others run the same versions of sub-dependencies. 5 | 6 | You should NOT check in the node_modules directory that Meteor automatically 7 | creates; if you are using git, the .gitignore file tells git to ignore it. 8 | -------------------------------------------------------------------------------- /packages/templating-tools/.npm/package/README: -------------------------------------------------------------------------------- 1 | This directory and the files immediately inside it are automatically generated 2 | when you change this package's NPM dependencies. Commit the files in this 3 | directory (npm-shrinkwrap.json, .gitignore, and this README) to source control 4 | so that others run the same versions of sub-dependencies. 5 | 6 | You should NOT check in the node_modules directory that Meteor automatically 7 | creates; if you are using git, the .gitignore file tells git to ignore it. 8 | -------------------------------------------------------------------------------- /packages/templating-tools/throw-compile-error.js: -------------------------------------------------------------------------------- 1 | export class CompileError {} 2 | 3 | export function throwCompileError(tag, message, overrideIndex) { 4 | const finalIndex = (typeof overrideIndex === 'number' ? 5 | overrideIndex : tag.tagStartIndex); 6 | 7 | const err = new CompileError(); 8 | err.message = message || "bad formatting in template file"; 9 | err.file = tag.sourceName; 10 | err.line = tag.fileContents.substring(0, finalIndex).split('\n').length; 11 | throw err; 12 | } 13 | -------------------------------------------------------------------------------- /packages/caching-html-compiler/.npm/package/README: -------------------------------------------------------------------------------- 1 | This directory and the files immediately inside it are automatically generated 2 | when you change this package's NPM dependencies. Commit the files in this 3 | directory (npm-shrinkwrap.json, .gitignore, and this README) to source control 4 | so that others run the same versions of sub-dependencies. 5 | 6 | You should NOT check in the node_modules directory that Meteor automatically 7 | creates; if you are using git, the .gitignore file tells git to ignore it. 8 | -------------------------------------------------------------------------------- /packages/blaze-html-templates/README.md: -------------------------------------------------------------------------------- 1 | # blaze-html-templates 2 | 3 | A meta-package that includes everything you need to compile and run Meteor templates with Spacebars and Blaze. 4 | 5 | For more details, see the documentation of the component packages: 6 | 7 | - [templating](https://atmospherejs.com/meteor/templating): compiles `.html` files 8 | - [blaze](https://atmospherejs.com/meteor/blaze): the runtime library 9 | - [spacebars](https://atmospherejs.com/meteor/spacebars): the templating language 10 | -------------------------------------------------------------------------------- /site/assets/theme-colors.less: -------------------------------------------------------------------------------- 1 | // Haven't made any changes as we want the default Meteor colors 2 | 3 | // Primary Color : #FF840E 4 | // Secondary Color : #FFDD00 5 | // Base Color : #343436 6 | // 7 | @color-primary: #FF840E; 8 | @color-secondary: #56579B;// violet 9 | @color-tertiary: #BEA76E;// gold 10 | @color-complementary: #22A699; // sea green 11 | @color-ancillary: #0F2A4A;// midnight blue 12 | 13 | @color-cloud: #fff; 14 | 15 | .nav-item { 16 | a { 17 | color: #333333 !important; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/templating-tools/templating-tools.js: -------------------------------------------------------------------------------- 1 | import { scanHtmlForTags } from './html-scanner'; 2 | import { compileTagsWithSpacebars } from './compile-tags-with-spacebars'; 3 | import { generateTemplateJS, generateBodyJS } from './code-generation'; 4 | import { CompileError, throwCompileError} from './throw-compile-error'; 5 | 6 | export const TemplatingTools = { 7 | scanHtmlForTags, 8 | compileTagsWithSpacebars, 9 | generateTemplateJS, 10 | generateBodyJS, 11 | CompileError, 12 | throwCompileError 13 | }; 14 | -------------------------------------------------------------------------------- /site/jsdoc/jsdoc-conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["plugins/markdown"], 3 | "markdown": { 4 | "parser": "gfm" 5 | }, 6 | "source": { 7 | "exclude": [ 8 | "packages/ddp/sockjs-0.3.4.js", 9 | "packages/test-in-browser/diff_match_patch_uncompressed.js", 10 | "packages/jquery/jquery.js", 11 | "packages/underscore/underscore.js", 12 | "packages/json/json2.js", 13 | "packages/minimongo/minimongo_tests.js", 14 | "tools/node_modules", 15 | "tools/skel-pack/package.js" 16 | ] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/htmljs/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'htmljs', 3 | summary: "Small library for expressing HTML trees", 4 | version: '2.0.1', 5 | git: 'https://github.com/meteor/blaze.git' 6 | }); 7 | 8 | Package.onUse(function (api) { 9 | api.use('ecmascript@0.16.9'); 10 | 11 | api.export('HTML'); 12 | api.mainModule('preamble.js'); 13 | }); 14 | 15 | Package.onTest(function (api) { 16 | api.use('ecmascript'); 17 | api.use('tinytest'); 18 | 19 | api.use('htmljs'); 20 | 21 | api.addFiles([ 22 | 'htmljs_test.js' 23 | ]); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/blaze/backcompat.js: -------------------------------------------------------------------------------- 1 | UI = Blaze; 2 | 3 | Blaze.ReactiveVar = ReactiveVar; 4 | UI._templateInstance = Blaze.Template.instance; 5 | 6 | Handlebars = {}; 7 | Handlebars.registerHelper = Blaze.registerHelper; 8 | 9 | Handlebars._escape = Blaze._escape; 10 | 11 | // Return these from {{...}} helpers to achieve the same as returning 12 | // strings from {{{...}}} helpers 13 | Handlebars.SafeString = function(string) { 14 | this.string = string; 15 | }; 16 | Handlebars.SafeString.prototype.toString = function() { 17 | return this.string.toString(); 18 | }; 19 | -------------------------------------------------------------------------------- /site/jsdoc/jsdoc.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | INFINITY=10000 4 | 5 | TOPDIR=$(pwd) 6 | 7 | # Call git grep to find all js files with the appropriate comment tags, 8 | # and only then pass it to JSDoc which will parse the JS files. 9 | # This is a whole lot faster than calling JSDoc recursively. 10 | git grep -al "@summary" -- .. | xargs -L ${INFINITY} -t \ 11 | "$TOPDIR/node_modules/.bin/jsdoc" \ 12 | -t "$TOPDIR/jsdoc/docdata-jsdoc-template" \ 13 | -c "$TOPDIR/jsdoc/jsdoc-conf.json" \ 14 | 2>&1 | grep -v 'WARNING: JSDoc does not currently handle' 15 | -------------------------------------------------------------------------------- /packages/blaze-tools/preamble.js: -------------------------------------------------------------------------------- 1 | 2 | import { 3 | EmitCode, 4 | toJSLiteral, 5 | toObjectLiteralKey, 6 | ToJSVisitor, 7 | toJS 8 | } from './tojs'; 9 | 10 | import { 11 | parseNumber, 12 | parseIdentifierName, 13 | parseExtendedIdentifierName, 14 | parseStringLiteral 15 | } from './tokens'; 16 | 17 | BlazeTools = { 18 | EmitCode, 19 | toJSLiteral, 20 | toObjectLiteralKey, 21 | ToJSVisitor, 22 | toJS, 23 | parseNumber, 24 | parseIdentifierName, 25 | parseExtendedIdentifierName, 26 | parseStringLiteral 27 | }; 28 | 29 | export { BlazeTools }; 30 | -------------------------------------------------------------------------------- /packages/blaze-hot/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'blaze-hot', 3 | summary: "Update files using Blaze's API with HMR", 4 | version: '2.0.0', 5 | git: 'https://github.com/meteor/blaze.git', 6 | documentation: null, 7 | debugOnly: true 8 | }); 9 | 10 | Package.onUse(function (api) { 11 | api.use('modules@0.20.1'); 12 | api.use('ecmascript@0.16.9'); 13 | api.use('blaze@3.0.0'); 14 | api.use('templating-runtime@2.0.0'); 15 | api.use('hot-module-replacement@0.5.4', { weak: true }); 16 | 17 | api.addFiles('hot.js', 'client'); 18 | api.addFiles('update-templates.js', 'client'); 19 | }); 20 | -------------------------------------------------------------------------------- /packages/spacebars-compiler/preamble.js: -------------------------------------------------------------------------------- 1 | import { CodeGen, builtInBlockHelpers, isReservedName } from './codegen'; 2 | import { optimize } from './optimizer'; 3 | import { parse, compile, codeGen, TemplateTagReplacer, beautify } from './compiler'; 4 | import { TemplateTag } from './templatetag'; 5 | 6 | SpacebarsCompiler = { 7 | CodeGen, 8 | _builtInBlockHelpers: builtInBlockHelpers, 9 | isReservedName, 10 | optimize, 11 | parse, 12 | compile, 13 | codeGen, 14 | _TemplateTagReplacer: TemplateTagReplacer, 15 | _beautify: beautify, 16 | TemplateTag, 17 | }; 18 | 19 | export { SpacebarsCompiler }; 20 | -------------------------------------------------------------------------------- /packages/templating/README.md: -------------------------------------------------------------------------------- 1 | # Templating 2 | 3 | Compiles Blaze templates defined in `.html` files. Also automatically includes Blaze on the client. 4 | 5 | This build plugin parses all of the HTML files in your app and looks for three top-level tags: 6 | 7 | - `` - Appended to the `head` section of your HTML. 8 | - `` - Appended to the `body` section of your HTML. 9 | - ` 61 | ``` -------------------------------------------------------------------------------- /images/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 19 | 21 | 22 | 23 | 24 | 33 | 34 | 35 | 36 | 39 | 40 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /packages/html-tools/scanner.js: -------------------------------------------------------------------------------- 1 | // This is a Scanner class suitable for any parser/lexer/tokenizer. 2 | // 3 | // A Scanner has an immutable source document (string) `input` and a current 4 | // position `pos`, an index into the string, which can be set at will. 5 | // 6 | // * `new Scanner(input)` - constructs a Scanner with source string `input` 7 | // * `scanner.rest()` - returns the rest of the input after `pos` 8 | // * `scanner.peek()` - returns the character at `pos` 9 | // * `scanner.isEOF()` - true if `pos` is at or beyond the end of `input` 10 | // * `scanner.fatal(msg)` - throw an error indicating a problem at `pos` 11 | 12 | export function Scanner (input) { 13 | this.input = input; // public, read-only 14 | this.pos = 0; // public, read-write 15 | } 16 | 17 | Scanner.prototype.rest = function () { 18 | // Slicing a string is O(1) in modern JavaScript VMs (including old IE). 19 | return this.input.slice(this.pos); 20 | }; 21 | 22 | Scanner.prototype.isEOF = function () { 23 | return this.pos >= this.input.length; 24 | }; 25 | 26 | Scanner.prototype.fatal = function (msg) { 27 | // despite this default, you should always provide a message! 28 | msg = (msg || "Parse error"); 29 | 30 | var CONTEXT_AMOUNT = 20; 31 | 32 | var input = this.input; 33 | var pos = this.pos; 34 | var pastInput = input.substring(pos - CONTEXT_AMOUNT - 1, pos); 35 | if (pastInput.length > CONTEXT_AMOUNT) 36 | pastInput = '...' + pastInput.substring(-CONTEXT_AMOUNT); 37 | 38 | var upcomingInput = input.substring(pos, pos + CONTEXT_AMOUNT + 1); 39 | if (upcomingInput.length > CONTEXT_AMOUNT) 40 | upcomingInput = upcomingInput.substring(0, CONTEXT_AMOUNT) + '...'; 41 | 42 | var positionDisplay = ((pastInput + upcomingInput).replace(/\n/g, ' ') + '\n' + 43 | (new Array(pastInput.length + 1).join(' ')) + "^"); 44 | 45 | var e = new Error(msg + "\n" + positionDisplay); 46 | 47 | e.offset = pos; 48 | var allPastInput = input.substring(0, pos); 49 | e.line = (1 + (allPastInput.match(/\n/g) || []).length); 50 | e.col = (1 + pos - allPastInput.lastIndexOf('\n')); 51 | e.scanner = this; 52 | 53 | throw e; 54 | }; 55 | 56 | // Peek at the next character. 57 | // 58 | // If `isEOF`, returns an empty string. 59 | Scanner.prototype.peek = function () { 60 | return this.input.charAt(this.pos); 61 | }; 62 | 63 | // Constructs a `getFoo` function where `foo` is specified with a regex. 64 | // The regex should start with `^`. The constructed function will return 65 | // match group 1, if it exists and matches a non-empty string, or else 66 | // the entire matched string (or null if there is no match). 67 | // 68 | // A `getFoo` function tries to match and consume a foo. If it succeeds, 69 | // the current position of the scanner is advanced. If it fails, the 70 | // current position is not advanced and a falsy value (typically null) 71 | // is returned. 72 | export function makeRegexMatcher(regex) { 73 | return function (scanner) { 74 | var match = regex.exec(scanner.rest()); 75 | 76 | if (! match) 77 | return null; 78 | 79 | scanner.pos += match[0].length; 80 | return match[1] || match[0]; 81 | }; 82 | } 83 | -------------------------------------------------------------------------------- /packages/blaze-tools/token_tests.js: -------------------------------------------------------------------------------- 1 | import { BlazeTools } from 'meteor/blaze-tools'; 2 | import { HTMLTools } from 'meteor/html-tools'; 3 | 4 | Tinytest.add("blaze-tools - token parsers", function (test) { 5 | 6 | var run = function (func, input, expected) { 7 | var scanner = new HTMLTools.Scanner('z' + input); 8 | // make sure the parse function respects `scanner.pos` 9 | scanner.pos = 1; 10 | var result = func(scanner); 11 | if (expected === null) { 12 | test.equal(scanner.pos, 1); 13 | test.equal(result, null); 14 | } else { 15 | test.isTrue(scanner.isEOF()); 16 | test.equal(result, expected); 17 | } 18 | }; 19 | 20 | var runValue = function (func, input, expectedValue) { 21 | var expected; 22 | if (expectedValue === null) 23 | expected = null; 24 | else 25 | expected = { text: input, value: expectedValue }; 26 | run(func, input, expected); 27 | }; 28 | 29 | var parseNumber = BlazeTools.parseNumber; 30 | var parseIdentifierName = BlazeTools.parseIdentifierName; 31 | var parseExtendedIdentifierName = BlazeTools.parseExtendedIdentifierName; 32 | var parseStringLiteral = BlazeTools.parseStringLiteral; 33 | 34 | runValue(parseNumber, "0", 0); 35 | runValue(parseNumber, "-0", 0); 36 | runValue(parseNumber, "-", null); 37 | runValue(parseNumber, ".a", null); 38 | runValue(parseNumber, ".1", 0.1); 39 | runValue(parseNumber, "1.", 1); 40 | runValue(parseNumber, "1.1", 1.1); 41 | runValue(parseNumber, "0x", null); 42 | runValue(parseNumber, "0xa", 10); 43 | runValue(parseNumber, "-0xa", -10); 44 | runValue(parseNumber, "1e+1", 10); 45 | 46 | [parseIdentifierName, parseExtendedIdentifierName].forEach(function (f) { 47 | run(f, "a", "a"); 48 | run(f, "true", "true"); 49 | run(f, "null", "null"); 50 | run(f, "if", "if"); 51 | run(f, "1", null); 52 | run(f, "1a", null); 53 | run(f, "+a", null); 54 | run(f, "a1", "a1"); 55 | run(f, "a1a", "a1a"); 56 | run(f, "_a8f_f8d88_", "_a8f_f8d88_"); 57 | }); 58 | run(parseIdentifierName, "@index", null); 59 | run(parseExtendedIdentifierName, "@index", "@index"); 60 | run(parseExtendedIdentifierName, "@something", "@something"); 61 | run(parseExtendedIdentifierName, "@", null); 62 | 63 | runValue(parseStringLiteral, '"a"', 'a'); 64 | runValue(parseStringLiteral, '"\'"', "'"); 65 | runValue(parseStringLiteral, '\'"\'', '"'); 66 | runValue(parseStringLiteral, '"a\\\nb"', 'ab'); // line continuation 67 | runValue(parseStringLiteral, '"a\u0062c"', 'abc'); 68 | // Note: IE 8 doesn't correctly parse '\v' in JavaScript. 69 | runValue(parseStringLiteral, '"\\0\\b\\f\\n\\r\\t\\v"', '\0\b\f\n\r\t\u000b'); 70 | runValue(parseStringLiteral, '"\\x41"', 'A'); 71 | runValue(parseStringLiteral, '"\\\\"', '\\'); 72 | runValue(parseStringLiteral, '"\\\""', '\"'); 73 | runValue(parseStringLiteral, '"\\\'"', '\''); 74 | runValue(parseStringLiteral, "'\\\\'", '\\'); 75 | runValue(parseStringLiteral, "'\\\"'", '\"'); 76 | runValue(parseStringLiteral, "'\\\''", '\''); 77 | 78 | test.throws(function () { 79 | run(parseStringLiteral, "'this is my string"); 80 | }, /Unterminated string literal/); 81 | }); 82 | -------------------------------------------------------------------------------- /packages/spacebars-tests/async_tests.html: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | 12 | 13 | 16 | 17 | 28 | 29 | 48 | 49 | 70 | 71 | 74 | 75 | 78 | 79 | 82 | 83 | 86 | 87 | 90 | 91 | 95 | 96 | 100 | 101 | 104 | 105 | 108 | 109 | 112 | -------------------------------------------------------------------------------- /site/_config.yml: -------------------------------------------------------------------------------- 1 | # Hexo Configuration 2 | ## Docs: http://hexo.io/docs/configuration.html 3 | ## Source: https://github.com/hexojs/hexo/ 4 | 5 | # Site 6 | title: BlazeJS 7 | subtitle: Developers 8 | description: 9 | author: 10 | language: en 11 | timezone: 12 | apis: 13 | # marketo: 627-RVJ-941 14 | # segment: zQx6cQifkTU79E3L0XAnmrOXP2A5bC6r 15 | # docsearch: 16 | # apiKey: bdf6b09d12024f6bae3631a0dfdd4a7f 17 | # indexName: meteor_api_guide 18 | versions: 19 | - '4.2.1' 20 | 21 | # This setting also defines the page order used to generate the Previous/Next links at the bottom of each page 22 | sidebar_categories: 23 | null: 24 | - index 25 | - changelog 26 | GUIDE: 27 | - guide/introduction 28 | - guide/spacebars 29 | - guide/reusable-components 30 | - guide/smart-components 31 | - guide/reusing-code 32 | - guide/understanding-blaze 33 | - guide/routing 34 | API: 35 | - api/templates 36 | - api/blaze 37 | - api/spacebars 38 | 39 | github_repo: 'meteor/blaze' 40 | content_root: 'site/source' 41 | 42 | # themeing 43 | favicon: '/logo/icon.ico' 44 | 45 | logo: 46 | nav_mobile: '/logo/logo.png' 47 | url: 'http://blazejs.org' 48 | title: 'BlazeJS' 49 | subtitle: 'Developers' 50 | 51 | nav_links: 52 | 'Guide': 53 | url: http://blazejs.org/guide/introduction.html 54 | 'API Docs': 55 | url: http://blazejs.org/api/templates.html 56 | 'Forums': 57 | url: https://forums.meteor.com/c/blaze 58 | target: _new 59 | 60 | social_links: 61 | github: 'https://github.com/meteor/blaze' 62 | twitter: '@meteor' 63 | 64 | 65 | # URL 66 | ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' 67 | url: http://blazejs.org/ 68 | root: / 69 | permalink: :year/:month/:day/:title/ 70 | permalink_defaults: 71 | 72 | # Directory 73 | source_dir: source 74 | public_dir: public 75 | tag_dir: tags 76 | archive_dir: archives 77 | category_dir: categories 78 | code_dir: downloads/code 79 | i18n_dir: :lang 80 | skip_render: 81 | - circle.yml 82 | 83 | # Writing 84 | new_post_name: :title.md # File name of new posts 85 | default_layout: post 86 | titlecase: false # Transform title into titlecase 87 | external_link: 88 | enable: true # Open external links in new tab 89 | filename_case: 0 90 | render_drafts: false 91 | post_asset_folder: false 92 | relative_link: false 93 | future: true 94 | highlight: 95 | enable: true 96 | line_number: true 97 | auto_detect: true 98 | tab_replace: 99 | 100 | # Category & Tag 101 | default_category: uncategorized 102 | category_map: 103 | tag_map: 104 | 105 | # Date / Time format 106 | ## Hexo uses Moment.js to parse and display date 107 | ## You can customize the date format as defined in 108 | ## http://momentjs.com/docs/#/displaying/format/ 109 | date_format: YYYY-MM-DD 110 | time_format: HH:mm:ss 111 | 112 | # Pagination 113 | ## Set per_page to 0 to disable pagination 114 | per_page: 10 115 | pagination_dir: page 116 | 117 | # Extensions 118 | ## Plugins: http://hexo.io/plugins/ 119 | ## Themes: http://hexo.io/themes/ 120 | theme: meteor 121 | api_box: 122 | data_file: 'data/data.js' 123 | marked: 124 | breaks: false 125 | 126 | # Deployment 127 | ## Docs: http://hexo.io/docs/deployment.html 128 | deploy: 129 | type: 130 | -------------------------------------------------------------------------------- /packages/htmljs/htmljs_test.js: -------------------------------------------------------------------------------- 1 | import { HTML } from 'meteor/htmljs'; 2 | 3 | Tinytest.add("htmljs - getTag", function (test) { 4 | var FOO = HTML.getTag('foo'); 5 | test.isTrue(HTML.FOO === FOO); 6 | var x = FOO(); 7 | 8 | test.equal(x.tagName, 'foo'); 9 | test.isTrue(x instanceof HTML.FOO); 10 | test.isTrue(x instanceof HTML.Tag); 11 | test.equal(x.children, []); 12 | test.equal(x.attrs, null); 13 | 14 | test.isTrue((new FOO) instanceof HTML.FOO); 15 | test.isTrue((new FOO) instanceof HTML.Tag); 16 | test.isFalse((new HTML.P) instanceof HTML.FOO); 17 | 18 | var result = HTML.ensureTag('Bar'); 19 | test.equal(typeof result, 'undefined'); 20 | var BAR = HTML.BAR; 21 | test.equal(BAR().tagName, 'Bar'); 22 | }); 23 | 24 | Tinytest.add("htmljs - construction", function (test) { 25 | var A = HTML.getTag('a'); 26 | var B = HTML.getTag('b'); 27 | var C = HTML.getTag('c'); 28 | 29 | var a = A(0, B({q:0}, C(A(B({})), 'foo'))); 30 | test.equal(a.tagName, 'a'); 31 | test.equal(a.attrs, null); 32 | test.equal(a.children.length, 2); 33 | test.equal(a.children[0], 0); 34 | var b = a.children[1]; 35 | test.equal(b.tagName, 'b'); 36 | test.equal(b.attrs, {q:0}); 37 | test.equal(b.children.length, 1); 38 | var c = b.children[0]; 39 | test.equal(c.tagName, 'c'); 40 | test.equal(c.attrs, null); 41 | test.equal(c.children.length, 2); 42 | test.equal(c.children[0].tagName, 'a'); 43 | test.equal(c.children[0].attrs, null); 44 | test.equal(c.children[0].children.length, 1); 45 | test.equal(c.children[0].children[0].tagName, 'b'); 46 | test.equal(c.children[0].children[0].children.length, 0); 47 | test.equal(c.children[0].children[0].attrs, {}); 48 | test.equal(c.children[1], 'foo'); 49 | 50 | var a2 = new A({m:1}, {n:2}, B(), {o:3}, 'foo'); 51 | test.equal(a2.tagName, 'a'); 52 | test.equal(a2.attrs, {m:1}); 53 | test.equal(a2.children.length, 4); 54 | test.equal(a2.children[0], {n:2}); 55 | test.equal(a2.children[1].tagName, 'b'); 56 | test.equal(a2.children[2], {o:3}); 57 | test.equal(a2.children[3], 'foo'); 58 | 59 | // tests of HTML.isConstructedObject (indirectly) 60 | test.equal(A({x:1}).children.length, 0); 61 | var f = function () {}; 62 | test.equal(A(new f).children.length, 1); 63 | test.equal(A(new Date).children.length, 1); 64 | test.equal(A({constructor: 'blah'}).children.length, 0); 65 | test.equal(A({constructor: Object}).children.length, 0); 66 | 67 | test.equal(HTML.toHTML(HTML.CharRef({html: '&', str: '&'})), '&'); 68 | test.throws(function () { 69 | HTML.CharRef({html: '&'}); // no 'str' 70 | }); 71 | }); 72 | 73 | // copied from here https://github.com/meteor/blaze/blob/ed9299ea32afdd04f33124957f22ce2b18b7f3ff/packages/html-tools/utils.js#L3 74 | // to avoid circular dependency between htmljs and html-tools pacakge. 75 | // this circular dependency was blocking the publish process. 76 | var asciiLowerCase = function (str) { 77 | return str.replace(/[A-Z]/g, function (c) { 78 | return String.fromCharCode(c.charCodeAt(0) + 32); 79 | }); 80 | }; 81 | 82 | Tinytest.add("htmljs - utils", function (test) { 83 | 84 | test.notEqual("\u00c9".toLowerCase(), "\u00c9"); 85 | test.equal(asciiLowerCase("\u00c9"), "\u00c9"); 86 | 87 | test.equal(asciiLowerCase("Hello There"), "hello there"); 88 | 89 | test.isTrue(HTML.isVoidElement("br")); 90 | test.isFalse(HTML.isVoidElement("div")); 91 | test.isTrue(HTML.isKnownElement("div")); 92 | 93 | }); 94 | 95 | Tinytest.add("htmljs - details", function (test) { 96 | test.equal(HTML.toHTML(false), "false"); 97 | }); 98 | -------------------------------------------------------------------------------- /site/source/guide/smart-components.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Writing smart components with Blaze 3 | description: 4 | --- 5 | 6 | Some of your components will need to access state outside of their data context---for instance, data from the server via subscriptions or the contents of client-side store. As discussed in the [data loading](https://guide.meteor.com/data-loading.html#patterns) and [UI](https://guide.meteor.com/ui-ux.html#smart-components) articles, you should be careful and considered in how you use such smart components. 7 | 8 | All of the suggestions about reusable components apply to smart components. In addition: 9 | 10 | ## Subscribe from `onCreated` 11 | 12 | You should subscribe to publications from the server from an `onCreated` callback (within an `autorun` block if you have reactively changing arguments). In the Todos example app, in the `Lists_show_page` template we subscribe to the `todos.inList` publication based on the current `_id` FlowRouter param: 13 | 14 | ```js 15 | Template.Lists_show_page.onCreated(function() { 16 | this.getListId = () => FlowRouter.getParam('_id'); 17 | 18 | this.autorun(() => { 19 | this.subscribe('todos.inList', this.getListId()); 20 | }); 21 | }); 22 | ``` 23 | 24 | We use `this.subscribe()` as opposed to `Meteor.subscribe()` so that the component automatically keeps track of when the subscriptions are ready. We can use this information in our HTML template with the built-in `{% raw %}{{Template.subscriptionsReady}}{% endraw %}` helper or within helpers using `instance.subscriptionsReady()`. 25 | 26 | Notice that in this component we are also accessing the global client-side state store `FlowRouter`, which we wrap in a instance method called `getListId()`. This instance method is called both from the `autorun` in `onCreated`, and from the `listIdArray` helper: 27 | 28 | ```js 29 | Template.Lists_show_page.helpers({ 30 | // We use #each on an array of one item so that the "list" template is 31 | // removed and a new copy is added when changing lists, which is 32 | // important for animation purposes. 33 | listIdArray() { 34 | const instance = Template.instance(); 35 | const listId = instance.getListId(); 36 | return Lists.findOne(listId) ? [listId] : []; 37 | }, 38 | }); 39 | ``` 40 | 41 | ## Fetch in helpers 42 | 43 | As described in the [UI/UX article](https://guide.meteor.com/ui-ux.html#smart-components), you should fetch data in the same component where you subscribed to that data. In a Blaze smart component, it's usually simplest to fetch the data in a helper, which you can then use to pass data into a reusable child component. For example, in the `Lists_show_page`: 44 | 45 | ```html 46 | {{> Lists_show_page (listArgs listId)}} 47 | ``` 48 | 49 | The `listArgs` helper fetches the data that we've subscribed to above: 50 | 51 | ```js 52 | Template.Lists_show_page.helpers({ 53 | listArgs(listId) { 54 | const instance = Template.instance(); 55 | return { 56 | todosReady: instance.subscriptionsReady(), 57 | // We pass `list` (which contains the full list, with all fields, as a function 58 | // because we want to control reactivity. When you check a todo item, the 59 | // `list.incompleteCount` changes. If we didn't do this the entire list would 60 | // re-render whenever you checked an item. By isolating the reactiviy on the list 61 | // to the area that cares about it, we stop it from happening. 62 | list() { 63 | return Lists.findOne(listId); 64 | }, 65 | // By finding the list with only the `_id` field set, we don't create a dependency on the 66 | // `list.incompleteCount`, and avoid re-rendering the todos when it changes 67 | todos: Lists.findOne(listId, {fields: {_id: true}}).todos() 68 | }; 69 | } 70 | }); 71 | 72 | ``` 73 | -------------------------------------------------------------------------------- /packages/templating-tools/compile-tags-with-spacebars.js: -------------------------------------------------------------------------------- 1 | import isEmpty from 'lodash.isempty'; 2 | import { SpacebarsCompiler } from 'meteor/spacebars-compiler'; 3 | import { generateBodyJS, generateTemplateJS } from './code-generation'; 4 | import { throwCompileError } from './throw-compile-error'; 5 | 6 | export function compileTagsWithSpacebars(tags, hmrAvailable) { 7 | var handler = new SpacebarsTagCompiler(); 8 | 9 | tags.forEach((tag) => { 10 | handler.addTagToResults(tag, hmrAvailable); 11 | }); 12 | 13 | return handler.getResults(); 14 | } 15 | 16 | 17 | class SpacebarsTagCompiler { 18 | constructor() { 19 | this.results = { 20 | head: '', 21 | body: '', 22 | js: '', 23 | bodyAttrs: {} 24 | }; 25 | } 26 | 27 | getResults() { 28 | return this.results; 29 | } 30 | 31 | addTagToResults(tag, hmrAvailable) { 32 | this.tag = tag; 33 | 34 | // do we have 1 or more attributes? 35 | const hasAttribs = !isEmpty(this.tag.attribs); 36 | 37 | if (this.tag.tagName === "head") { 38 | if (hasAttribs) { 39 | this.throwCompileError("Attributes on not supported"); 40 | } 41 | 42 | this.results.head += this.tag.contents; 43 | return; 44 | } 45 | 46 | 47 | // or