├── Site Mechanics.md
├── WebKit Browsers.md
├── OSI Model Network Layer.md
├── OSI Model Physical Layer.md
├── OSI Model Data-Link Layer.md
├── OSI Model Transport Layer.md
├── OSI Model Application Layer.md
├── OSI Model Presentation Layer.md
├── _book
├── .gitignore
└── gitbook
│ ├── images
│ └── favicon.ico
│ ├── fonts
│ ├── helvetica
│ │ ├── normal.eot
│ │ ├── normal.ttf
│ │ ├── normal.woff
│ │ ├── ultralight.eot
│ │ ├── ultralight.ttf
│ │ ├── ultralight.woff
│ │ └── normal.svg
│ └── fontawesome
│ │ ├── FontAwesome.otf
│ │ ├── fontawesome-webfont.eot
│ │ ├── fontawesome-webfont.ttf
│ │ └── fontawesome-webfont.woff
│ ├── jsrepl
│ ├── sandbox.html
│ ├── langs
│ │ └── javascript
│ │ │ └── jsrepl_js.js
│ ├── engines
│ │ └── javascript-default.js
│ ├── sandbox.js
│ └── jsrepl.js
│ └── print.css
├── Meteor Style Guide.md
├── .gitattributes
├── Reserved Words.md
├── README.md
├── Quickstart.md
├── Video IO.md
├── Punctuation.md
├── SUMMARY.md
├── File IO.md
├── Terminology.md
├── Writing Acceptance Tests.md
├── Installation.md
├── Syntax.md
├── Packages.md
├── File Structure.md
├── Refactoring with Test Driven Development.md
├── Namespacing.md
├── .gitignore
├── Development Tools.md
├── Site Configuration.md
├── Test Driven Development.md
├── Event Cycle.md
├── General Advice.md
├── App Structure.md
├── Console Logging.md
├── Dependencies.md
├── Cookbook Conventions.md
├── The Refactoring Process.md
├── OSI Model Data Layer.md
└── WebStorm IDE.md
/Site Mechanics.md:
--------------------------------------------------------------------------------
1 | # Site Mechanics
2 |
--------------------------------------------------------------------------------
/WebKit Browsers.md:
--------------------------------------------------------------------------------
1 | # WebKit Browsers
2 |
--------------------------------------------------------------------------------
/OSI Model Network Layer.md:
--------------------------------------------------------------------------------
1 | # OSI Model Network Layer
2 |
--------------------------------------------------------------------------------
/OSI Model Physical Layer.md:
--------------------------------------------------------------------------------
1 | # OSI Model Physical Layer
2 |
--------------------------------------------------------------------------------
/OSI Model Data-Link Layer.md:
--------------------------------------------------------------------------------
1 | # OSI Model Data-Link Layer
2 |
--------------------------------------------------------------------------------
/OSI Model Transport Layer.md:
--------------------------------------------------------------------------------
1 | # OSI Model Transport Layer
2 |
--------------------------------------------------------------------------------
/OSI Model Application Layer.md:
--------------------------------------------------------------------------------
1 | # OSI Model Application Layer
2 |
--------------------------------------------------------------------------------
/OSI Model Presentation Layer.md:
--------------------------------------------------------------------------------
1 | # OSI Model Presentation Layer
2 |
--------------------------------------------------------------------------------
/_book/.gitignore:
--------------------------------------------------------------------------------
1 | ################
2 | ##Brackets Gitbook Editing
3 | ################
4 | *.html
5 | *.json
6 |
--------------------------------------------------------------------------------
/Meteor Style Guide.md:
--------------------------------------------------------------------------------
1 | # Meteor Style Guide
2 |
3 | See: https://github.com/meteor/meteor/wiki/Meteor-Style-Guide
4 |
--------------------------------------------------------------------------------
/_book/gitbook/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mcrayne/MeteorCookbookGitbook/HEAD/_book/gitbook/images/favicon.ico
--------------------------------------------------------------------------------
/_book/gitbook/fonts/helvetica/normal.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mcrayne/MeteorCookbookGitbook/HEAD/_book/gitbook/fonts/helvetica/normal.eot
--------------------------------------------------------------------------------
/_book/gitbook/fonts/helvetica/normal.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mcrayne/MeteorCookbookGitbook/HEAD/_book/gitbook/fonts/helvetica/normal.ttf
--------------------------------------------------------------------------------
/_book/gitbook/fonts/helvetica/normal.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mcrayne/MeteorCookbookGitbook/HEAD/_book/gitbook/fonts/helvetica/normal.woff
--------------------------------------------------------------------------------
/_book/gitbook/fonts/helvetica/ultralight.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mcrayne/MeteorCookbookGitbook/HEAD/_book/gitbook/fonts/helvetica/ultralight.eot
--------------------------------------------------------------------------------
/_book/gitbook/fonts/helvetica/ultralight.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mcrayne/MeteorCookbookGitbook/HEAD/_book/gitbook/fonts/helvetica/ultralight.ttf
--------------------------------------------------------------------------------
/_book/gitbook/fonts/helvetica/ultralight.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mcrayne/MeteorCookbookGitbook/HEAD/_book/gitbook/fonts/helvetica/ultralight.woff
--------------------------------------------------------------------------------
/_book/gitbook/fonts/fontawesome/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mcrayne/MeteorCookbookGitbook/HEAD/_book/gitbook/fonts/fontawesome/FontAwesome.otf
--------------------------------------------------------------------------------
/_book/gitbook/fonts/fontawesome/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mcrayne/MeteorCookbookGitbook/HEAD/_book/gitbook/fonts/fontawesome/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/_book/gitbook/fonts/fontawesome/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mcrayne/MeteorCookbookGitbook/HEAD/_book/gitbook/fonts/fontawesome/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/_book/gitbook/fonts/fontawesome/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mcrayne/MeteorCookbookGitbook/HEAD/_book/gitbook/fonts/fontawesome/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/_book/gitbook/jsrepl/sandbox.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | jsREPL Sandbox
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/_book/gitbook/jsrepl/langs/javascript/jsrepl_js.js:
--------------------------------------------------------------------------------
1 | (function(){self.JSREPLEngine=function(){function a(d,b,c,a,e,f){this.result=c;this.error=a;this.sandbox=e;this.inspect=this.sandbox.console.inspect;this.functionClass=this.sandbox.Function;this.sandbox.__eval=this.sandbox.eval;f()}a.prototype.Eval=function(d){var b;try{return b=this.sandbox.__eval(d),this.result(b===void 0?"":this.inspect(b))}catch(a){return this.error(a)}};a.prototype.RawEval=function(a){var b;try{return b=this.sandbox.__eval(a),this.result(b)}catch(c){return this.error(c)}};a.prototype.GetNextLineIndent=
2 | function(a){try{return new this.functionClass(a),false}catch(b){return/[\[\{\(]$/.test(a)?1:0}};return a}()}).call(this);
3 |
--------------------------------------------------------------------------------
/Reserved Words.md:
--------------------------------------------------------------------------------
1 | ## Reserved Keywords
2 |
3 |
4 | Be careful about using the following reserved keywords. Meteor integrates a number of packages and libraries which extend the Javascript reserved keyword list. Between Mongo and the Spark templates, people have reported having problems when using the following keywords in their applications.
5 |
6 | ````
7 | name
8 | length
9 | assets
10 | template
11 | match
12 | stats
13 | content
14 | ````
15 |
16 | And some relevant links for people who would like to know more:
17 |
18 | Template.foo.name
19 | https://github.com/meteor/meteor/issues/703
20 |
21 | collection.insert({ owner: Meteor.userId(), length:3 });
22 | https://github.com/meteor/meteor/issues/594#issuecomment-15441895
23 |
24 | content
25 | https://groups.google.com/forum/#!topic/meteor-talk/N4C6ZRv6zb8
26 |
--------------------------------------------------------------------------------
/_book/gitbook/print.css:
--------------------------------------------------------------------------------
1 | h1,h2{page-break-after:avoid;page-break-before:auto}pre,blockquote{border:1px solid #999;page-break-inside:avoid}img{max-width:100%!important;page-break-inside:avoid}section{page-break-after:always}section#cover{padding:3cm 0;text-align:center}section#cover h1{font-size:1.5cm}section#summary{text-align:center}section#summary ul{font-size:.5cm;line-height:1.8em;padding:0;margin:0;list-style:none}section#summary>ul>li{margin-bottom:1cm}section#summary>ul>li>a{font-size:.6cm}section article{margin:1.5cm}section article.new-chapter{page-break-after:always;font-size:.6cm;text-align:center;padding:3cm 0;border-top:1px solid #ccc}@media print{section article.new-chapter{border:0}}section article .exercise{margin:1cm 0;padding:.4cm;page-break-inside:avoid;border:3px solid #ddd}section article .exercise .exercise-header{margin-bottom:.4cm;padding-bottom:.2cm;border-bottom:1px solid #ddd}
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ##Meteor Cookbook
2 |
3 | Welcome to the Meteor Cookbook; a FAQ and tutorial culled and currated from over 12 months of emails and discussions from the [Meteor Talk](https://groups.google.com/forum/#!forum/meteor-talk) google group and my experiences rolling out packages and apps.
4 |
5 | These documents are intended for the intermediate user learning Meteor, who is accustomed to
6 |
7 | - object-oriented frameworks and languages, such as Java and C#, and
8 | - relational databases and data structures derived from SQL table schemas.
9 |
10 | The focus is on helping the user grow accustomed to functional programming using document oriented databases.
11 |
12 | The original work for this can be found on [Abigail Watson's](https://github.com/awatson1978) Github [repo](https://github.com/awatson1978/meteor-cookbook). Abigail is the author of the content, I have reorganized this content to fit easily into the GitBook format.
13 |
--------------------------------------------------------------------------------
/Quickstart.md:
--------------------------------------------------------------------------------
1 | ## Meteor Quickstart Installation
2 | **Q: Why can't I run start my Meteor app?**
3 |
4 | This quickstart is written for Mac OSX, and is a bit more verbose than other installation instructions. It should hopefully cover a few edge cases, such as setting your path, which can cause an installation to go awry.
5 |
6 | ````sh
7 | # install meteor
8 | curl https://install.meteor.com | sh
9 |
10 | # check it's installed correctly
11 | meteor --version
12 |
13 | # install node and npm
14 | curl http://npmjs.org/install.sh | sh
15 |
16 | # check npm is installed correctly
17 | npm -version
18 |
19 | # find your npm path
20 | which npm
21 |
22 | # make sure npm is in your path
23 | sudo nano ~/.profile
24 | export PATH=$PATH:/usr/local/bin
25 |
26 | # install meteorite
27 | npm install -g meteorite
28 |
29 | # and if you have problems with permissions
30 | sudo -H npm install -g meteorite
31 |
32 | # check mrt is installed correctly
33 | mrt --version
34 |
35 | # find your mrt path
36 | which mrt
37 | locate mrt
38 |
39 | # make sure meteorite is in your path
40 | sudo nano ~/.profile
41 | export PATH=$PATH:/usr/local/share/npm/bin
42 |
43 | # check mrt is installed correctly
44 | mrt --version
45 | ````
46 |
--------------------------------------------------------------------------------
/Video IO.md:
--------------------------------------------------------------------------------
1 | ## Video.IO
2 |
3 | So, Video Input/Output can mean a couple different things. And they both revolve around the concept of [Double Buffering](http://en.wikipedia.org/wiki/Multiple_buffering). Take an embedded YouTube video, as an example. There's the video stream which is served by YouTube and has a specific URL. But then, the browser will combine that video with the page elements from the rest of the webpage, add some Chrome such as the URL bar, tabs, and window controls, and render a new video stream. It's **that** second video stream that eventually gets rendered to your computer screen.
4 |
5 |
6 | ### Video Stream Buffers
7 | There's also the OpenTok framework, which a few different groups have used to make video solutions with.
8 | http://tokbox.com/opentok
9 |
10 |
11 | ### Browser Video Buffer
12 | Watch these videos for the future of Meteor video.io. Specifically, Newcomb talks about getAnimationFrame() functions as being the secret to getting 60fps DOM refresh rates.
13 |
14 | http://www.youtube.com/watch?v=83MX4wsoMzU
15 | https://www.youtube.com/watch?v=br1NhXeVD6Y
16 | https://www.youtube.com/watch?v=ixASZtHYGKY
17 | https://www.youtube.com/watch?v=zpebYhm8f2o
18 | https://www.youtube.com/watch?v=OhfI2wFNKFQ
19 |
--------------------------------------------------------------------------------
/Punctuation.md:
--------------------------------------------------------------------------------
1 | ## Grammar
2 |
3 | **Semicolons**
4 | Obviously, everybody has their own opinions about grammar, and the Javascript specification (ECMA5 whatever) says that semicolons are optional. Fair enough. But here's a reason to use semicolons: eventmaps.
5 |
6 | ````js
7 | // eventmap will fail
8 | Template.topicsPage.events({
9 | 'click .button':function(){
10 | console.count('initialize-rooms') // note the missing semicolon
11 | }
12 | })
13 |
14 | // eventmap will run correctly
15 | Template.topicsPage.events({
16 | 'click .button':function(){
17 | console.count('initialize-rooms');
18 | }
19 | })
20 |
21 | ````
22 |
23 | **Variable and Function Names**
24 | Speaking of global contexts, when you bring variables into the global scope, err on the side of verbose names. A rule-of-thumb I use is any varible in the local scope should be at least 6 characters long.
25 |
26 | ````js
27 | // bad! creates unreadable code
28 | var f = 0;
29 |
30 | // still too short
31 | var foo = 0;
32 |
33 | // much better!
34 | fooCount = 0;
35 |
36 | // ideal
37 | currentFooIndex = 0;
38 | ````
39 |
40 | The reason behind wanting to use long variable names has to do with the entropic information density of longer strings, which leads to less name collissions. This is particularly useful when refactoring. Sometimes you'll want to do a global Find And Replace on just 'foo' elements, or just 'count' elements, or just 'current' elements, etc. Having long names will help in refactoring, and prevent name collisions. Short, concise names are prone to causing name collisions. Also this rule-of-thumb about name lengths applies to function names too.
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/SUMMARY.md:
--------------------------------------------------------------------------------
1 | # Summary
2 |
3 | * [Cookbook Conventions](Cookbook Conventions.md)
4 | * [General Advice](General Advice.md)
5 | * [Meteor Style Guide](Meteor Style Guide.md)
6 | * [Terminology](Terminology.md)
7 | * [Syntax](Syntax.md)
8 | * [Punctuation](Punctuation.md)
9 | * [Reserved Words](Reserved Words.md)
10 | * [Installation](Installation.md)
11 | * [Quickstart](Quickstart.md)
12 | * [Development Tools](Development Tools.md)
13 | * [WebStorm IDE](WebStorm IDE.md)
14 | * [Test Driven Development](Test Driven Development.md)
15 | * [The Refactoring Process](The Refactoring Process.md)
16 | * [Refactoring with Test Driven Development](Refactoring with Test Driven Development.md)
17 | * [Writing Acceptance Tests](Writing Acceptance Tests.md)
18 | * [Site Mechanics](Site Mechanics.md)
19 | * [File Structure](File Structure.md)
20 | * [Dependencies](Dependencies.md)
21 | * [App Structure](App Structure.md)
22 | * [Event Cycle](Event Cycle.md)
23 | * [Namespacing](Namespacing.md)
24 | * [Packages](Packages.md)
25 | * [Site Configuration](Site Configuration.md)
26 | * [OSI Model Physical Layer](OSI Model Physical Layer.md)
27 | * [OSI Model Data-Link Layer](OSI Model Data-Link Layer.md)
28 | * [Console Logging](Console Logging.md)
29 | * [WebKit Browsers](WebKit Browsers.md)
30 | * [File IO](File IO.md)
31 | * [Video IO](Video IO.md)
32 | * [OSI Model Network Layer](OSI Model Network Layer.md)
33 | * [OSI Model Transport Layer](OSI Model Transport Layer.md)
34 | * [OSI Model Data Layer](OSI Model Data Layer.md)
35 | * [OSI Model Presentation Layer](OSI Model Presentation Layer.md)
36 | * [OSI Model Application Layer](OSI Model Application Layer.md)
37 |
38 |
--------------------------------------------------------------------------------
/File IO.md:
--------------------------------------------------------------------------------
1 | ## File Input/Output
2 | For when you need to read and parse a file on the server disk drive. Useful for persistent data-drops and initialization files. Be careful, as this solution doens't scale horizontally. So be sure that you're using a shared-nothing architecture.
3 |
4 | ````js
5 | // Asynchronous Method.
6 | Meteor.startup(function () {
7 | console.log('starting up');
8 |
9 | var fs = Npm.require('fs');
10 | fs.readFile('file.json', 'utf8', function (err, data) {
11 | if (err) {
12 | console.log('Error: ' + err);
13 | return;
14 | }
15 |
16 | data = JSON.parse(data);
17 | console.log(data);
18 | });
19 | });
20 |
21 |
22 | // Synchronous Method.
23 | Meteor.startup(function () {
24 | var fs = Npm.require('fs');
25 | var data = fs.readFileSync('public/datafile/flare.json', 'utf8');
26 |
27 | if (Icd10.find().count() === 0) {
28 | Icd10.insert({
29 | date: new Date(),
30 | data: JSON.parse(data)
31 | });
32 | }
33 | });
34 | ````
35 |
36 | ## BindEnvironment Example
37 |
38 | Sometimes you need to run some expensive functions while reading from Disk or Network. If you find yourself running into IO problems, and suspect you're having fibers or sync/async problems, try using Meteor.bindEnvironment.
39 | ````js
40 | Meteor.methods({
41 | convertFileToRecord: function(postId) {
42 | if(postId) {
43 | expensiveObject.ioIntensiveFunction(null, Meteor.bindEnvironment(function(result) {
44 | Posts.update({_id: postId}, {$set: {text: result}});
45 | console.log(result);
46 | return result;
47 | }, function(err) {
48 | console.error(err.message);
49 | return err.message;
50 | }));
51 | }else{
52 | return 'no postId';
53 | }
54 | }
55 | });
56 | ````
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Terminology.md:
--------------------------------------------------------------------------------
1 | ## Terminology
2 | **Q: How do I use DDP instead of a REST API with an ORM? Is that ACID compliant?**
3 |
4 | Luckily, Meteor has been fairly good about not using too many acronyms. But there are a few concept which you might not have run across, depending on your background, and how you came to Meteor. Here are a few relevant acronyms which people ask about from time to time...
5 |
6 | **ACID - Atomicity, Consistency, Isolation, Durability**
7 | Generally speaking, when Meteor folks talk about ACID, they're talking about the fact that Mongo doesn't support traditional database transactions; they're not talking about the Acid2 browser compatibility tests.
8 |
9 | **DDP - Distributed Data Protocol**
10 | This is simply the protocol that enables the Meteor.publish() and Meteor.subscribe() methods. It does all the heavy lifting of data communications between the server and client.
11 | http://meteor.com/blog/2012/03/21/introducing-ddp
12 |
13 | **DDS - Data Distribution Service**
14 | A data distribution protocol that has nothing to do with Meteor. It just happens to be named very similarly to DDP.
15 | http://en.wikipedia.org/wiki/Data_distribution_service
16 |
17 | **MDG - Meteor Development Group**
18 | Nickname for the wonderful folks who brought us Meteor.
19 |
20 | **ORM - Object Relation Mapper**
21 | Something that the Meteor community doesn't like, related to SQL databases. Most SQL table structures are designed with a Don't Repeat Yourself (DRY) principle, and create tables that isolate data so it's only entered into the database a single time. This process is called normalization, and results in data tables that don't represent the data objects that are typically used in the application itself. Thus, a layer is added above the database, which translates the normalized data into usable data objects for the application. This mapping layer is the cause of countless problems, and is something Meteor has been architected without.
22 | http://www.codinghorror.com/blog/2006/06/object-relational-mapping-is-the-vietnam-of-computer-science.html
23 | http://blogs.tedneward.com/PermaLink,guid,33e0e84c-1a82-4362-bb15-eb18a1a1d91f.aspx
24 | http://nedbatchelder.com/blog/200606/the_vietnam_of_computer_science.html
25 |
26 | **REST - Representation State Transfer**
27 | When people talk about REST interfaces, they're talking about GET, POST, PUT, and DELETE commands that web browsers use to request data from a server.
28 | https://en.wikipedia.org/wiki/Representational_state_transfer
29 | http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Writing Acceptance Tests.md:
--------------------------------------------------------------------------------
1 | ## Writing Acceptance Tests
2 |
3 | #### Business Use Cases and Regulatory Requirements
4 | It's very convenient to begin writing your acceptance tests by looking at the business use cases and regulatory obligations. Behavior Driven Develop (BDD) is very convenient for this. The following example shows the process of converting a Business Feature into a use case and testing scenario.
5 |
6 | ````feature
7 | Feature: Player score can be increased manually
8 |
9 | As a score keeper in some hyperthetical game
10 | I want to manually give a player five points
11 | So that I can publicly display a up-to-date scoreboard
12 |
13 | Scenario: Give 5 points to a player
14 | Given I authenticate
15 | And "Grace Hopper" has a score of 10
16 | When I give "Grace Hopper" 5 points
17 | Then "Grace Hopper" has a score of 15
18 | ````
19 |
20 |
21 | #### Converting Use Cases into Tests
22 | Once you have your features, use cases, and scearios defined, begin translating them into acceptance tests, using CoffeeScript, jQuery, and Behavior Driven Development libraries, such as Chai.
23 |
24 | ````feature
25 | Feature: Player score can be increased manually
26 |
27 | As a score keeper in some hyperthetical game
28 | I want to manually give a player five points
29 | So that I can publicly display a up-to-date scoreboard
30 |
31 | Scenario: Give 5 points to a player
32 | Given I can connect to page "http://leaderboard.meteor.com"
33 | And "Grace Hopper" has a score of 10
34 | When $("#niftyWidgetButton").click()
35 | foo = $("#niftyWidgetText").val()
36 | Then foo.should.have.value(20)
37 | ````
38 |
39 | #### Acceptance Tests Have 3 Essential Key Features
40 | Be aware that most all acceptance testing can be boiled down to three essential features: querying a resource, reading data, and writing data. When it comes to browsers and webpages, these three features basically boil down to the following:
41 |
42 | 1. Load a webpage or application view
43 | 2. Inspect user interface elements (i.e. DOM)
44 | 3. Trigger an event / simulate a user interaction
45 |
46 |
47 | Which, when translated to JQuery (and a bit of Chai), look something like this:
48 | ````js
49 | $(window).open("http://leaderboard.meteor.com");
50 | $('#niftyWidgetButton').click();
51 | $('#niftyWidgetText').val().should.have.value(20);
52 | ````
53 |
54 | Sometimes, you'll want to adjust the timing of your tests, which is easily done by setting timeouts (in milliseconds).
55 | ````js
56 | $(window).open("http://leaderboard.meteor.com");
57 | setTimeout(function(){
58 | $('#niftyWidgetButton').click();
59 | }, 200);
60 | setTimeout(function(){
61 | $('#niftyWidgetText').val().should.have.value(20);
62 | }, 500);
63 | ````
64 |
--------------------------------------------------------------------------------
/Installation.md:
--------------------------------------------------------------------------------
1 |
2 | ## Installation & Uninstallation
3 |
4 | **Q: Is there a Homebrew installer for Mac OSX?**
5 | Unofficially, yes. It can be found here:
6 | https://gist.github.com/4317935
7 |
8 | ````
9 | brew install https://gist.github.com/raw/4317935/05084353d3cd50acad7e88e01c3f6463b42c0ed3/meteor.rb
10 | ````
11 |
12 | **Q: Is there an MSI installer for Windows?**
13 | Unofficially, yes. The last released version is 0.6.4.1. It can be found here:
14 | http://win.meteor.com/
15 |
16 | **Q: When will Windows version become a first class citizen?**
17 | Not in the immediate future, as it's slated to be included after the 1.0 release. In the meantime, it's recommended to use a virtual machine for development. You can read the roadmap and relevant disscussions here:
18 | https://trello.com/card/official-windows-support/508721606e02bb9d570016ae/11
19 | https://github.com/meteor/meteor/issues/867
20 |
21 | **Q: Can Meteor run on Rasberry Pi?**
22 | Daaah... maybe? People seem to be working on it, but not much success yet.
23 | http://www.badgersblog.co.uk/2012/12/nodejs-raspberry-pi-tutorial-1.html
24 | https://groups.google.com/forum/#!msg/meteor-talk/CcXzU14EHH8/3wvB-d1RfaAJ
25 |
26 |
27 | **Q: How do I determine what version of Meteor is installed?**
28 |
29 | Use the ``--version`` flag! It's standard between Npm, Meteor, and Meteorite.
30 | ````sh
31 | npm --version
32 | meteor --version
33 | mrt --version
34 | ````
35 |
36 | **Q: How do I run a specific version of Meteor?**
37 |
38 | Use the ``--release`` flag!
39 | ````js
40 | // for specifying meteor deployment target
41 | meteor update --release 0.6.5
42 |
43 | // for deployment
44 | meteor bundle --release 0.6.5
45 | ````
46 |
47 |
48 | **Q: Should I install Npm with Node Version Manager?**
49 | That's really up to you. However, in my experience, it's been a bit more trouble than it's been worth.
50 |
51 | ````sh
52 | # to check what version of NVM is installed
53 | nvm ls
54 | ````
55 |
56 | **Q: How do I install and use a development branch of Meteor?**
57 | There are two ways, depending if you're using meteor, or meteorite. If using meteor:
58 |
59 | ````
60 | cd
61 | mkdir meteor.branchname
62 | cd meteor.branchname
63 | git clone https://github.com/username/meteor.git
64 | cd
65 | ~/meteor.branchname/meteor/meteor
66 | ````
67 |
68 | And, if you're using mrt:
69 | ````
70 | {
71 | "meteor": {
72 | "meteor.branch": "branchname",
73 | "git": "https://github.com/username/meteor.git"
74 | }
75 | }
76 | ````
77 | **Q: How do I uninstall Meteor?**
78 | No need to run scripts. Just delete directories like so:
79 | ````js
80 | // the older location, pre 0.6.0
81 | sudo rm /usr/local/bin/meteor
82 |
83 | // the newer location, post 0.6.0
84 | sudo rm -rf ~/.meteor
85 | ````
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/Syntax.md:
--------------------------------------------------------------------------------
1 | ## Syntax
2 | **- the arrangement of words and phrases to create well-formed sentences in a language.**
3 |
4 | Language syntax doesn't have to be hard. But somehow it often is. Meteor makes language syntax a breeze, if you're willing to use a few particular patterns.
5 |
6 | ####Semantic HTML in Meteor
7 | Keep in mind that Meteor introduces the ```` tag, and supports [HTML5](http://www.w3schools.com/html/html5_semantic_elements.asp), which includes all of the following structural tags.
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | These should all be valid tags in your application. The more you use them, the cleaner and more concise your application will be.
33 |
34 | But, eventually, you'll want to start extending those tags with classes. How you go about doing that can dramatically affect how well your program runs, and how easy it is to implement new features. Suffice it to say that it drastically helps to keep your code as semantic as possible. Ideally, you'll find yourself writing code similar to the following, or better.
35 |
36 | ````html
37 |
38 |
39 |
40 |
41 |
*{{ _id }}*
42 |
{{ userName }}
43 |
48 |
49 |
50 |
51 | ````
52 |
53 | If you can structure your css/less classes in this manner, you'll be able to offload commonly used functionality to hardware accelerated code, manage it with dependencies and includes/imports, and keep your application syntax super easy to read and maintain.
54 |
55 |
56 | #### Semantic Libraries
57 | At the very least, consider a semantic UI library of some sort, such as Bootstrap 3 or Zurb Foundation (they're the oldest, and have been around the longest). All the examples in the Meteor Cookbook use Bootstrap 3. However, in the future, we're considering moving to something even more semantic, such as Semantic UI.
58 |
59 | [Bootstrap3](http://getbootstrap.com/)
60 |
61 | [SemanticUI](http://semantic-ui.com/)
62 |
63 |
--------------------------------------------------------------------------------
/Packages.md:
--------------------------------------------------------------------------------
1 | ## PACKAGES
2 |
3 | **Q: How do I install packages without Atmosphere?**
4 |
5 | Simple! Just add a smart.json file in the root of your project, and add the package in as a smart.json using the syntax described in the following code sample.
6 | https://atmospherejs.com/docs/publishing
7 | ````json
8 | {
9 | "meteor": {
10 | "branch": "master"
11 | },
12 | "packages": {
13 | "audio-click": {
14 | "git": "https://github.com/awatson1978/audio-click.git"
15 | },
16 | "fonts-barcode": {
17 | "git": "https://github.com/awatson1978/fonts-barcode.git"
18 | },
19 | "hipaa-audit-log": {
20 | "git": "https://github.com/awatson1978/hipaa-audit-log.git"
21 | },
22 | "reactive-overlays": {
23 | "git": "https://github.com/awatson1978/reactive-overlays.git"
24 | },
25 | "accounts-famous-dead-people": {
26 | "git": "https://github.com/awatson1978/accounts-famous-dead-people.git"
27 | },
28 | "device-detection": {},
29 | "cordova-phonegap": {},
30 | "keybindings": {}
31 | }
32 | }
33 | ````
34 |
35 |
36 | **Q: How do I create a package for distribution?**
37 | So, there isn't an official documented API for creating packages, as far as I'm aware. The best we can do is sort of document all of the api calls we've seen in the wild. The following example illustrates all the different syntax we've seen in creating packages.
38 |
39 |
40 | ````js
41 | // package.js
42 | // should go into the /meteor-project/packages/sample_package directory
43 |
44 | Package.describe({
45 | // define a message to describe the package
46 | summary: "This is a sample package that doesn't actually do anything.",
47 |
48 | // for internal dependency packages, set the internal flag true
49 | internal: false
50 | });
51 |
52 | // If you're bundling an NPM package, be sure to reference the package as a dependency
53 | Npm.depends({sample_package: "0.2.6", bar: '1.2.3'});
54 |
55 | Package.on_use(function (api) {
56 |
57 | var path = Npm.require('path');
58 |
59 | // sample_package.js
60 | Foo = Npm.require('sample_package');
61 |
62 | // export the object
63 | api.export('Foo');
64 |
65 | api.add_files(path.join('audio', 'click1.wav'), 'client');
66 |
67 | // define dependencies using api.use
68 | api.use('package_name', 'directory/to/install/into');
69 |
70 | // add files to specific locations using api.add_files
71 | api.add_files('library_name.js', 'directory/to/install/into');
72 |
73 | // example: add multiple files to a location using an array
74 | api.add_files(['first_library.js', 'second_library.js'], 'client');
75 |
76 | // example: add file to multiple locations using an array
77 | api.add_files('other_library_name.js', ['client', 'server']);
78 | });
79 |
80 | Package.on_test(function (api) {
81 |
82 | // define dependencies using api.use
83 | api.use('package_name');
84 |
85 | // add files to specific locations using api.add_files
86 | api.add_files('library_name.js', 'directory/to/install/into');
87 | });
88 | ````
89 |
90 | Once all that is done, you should have a Foo object which you can now use in your application, like so:
91 |
92 | ````js
93 | // and now use the function like so:
94 | Foo.function();
95 | ````
96 |
97 |
98 |
--------------------------------------------------------------------------------
/File Structure.md:
--------------------------------------------------------------------------------
1 | ## Application File Structure
2 | **Where should I put my files?**
3 |
4 |
5 | The first thing you need to know in structuring your apps is that the Meteor bundler has some directories that it is hardcoded to look for. At a very basic level, the following directories are sort of baked into Meteor bundler, and is where you should begin with structuring larger applications.
6 |
7 | ```js
8 | client/ // client application code
9 | client/compatibility/ // legacy 3rd party javascript libraries
10 | lib/ // any common code for client/server.
11 | packages/ // place for all your atmosphere packages
12 | private/ // static files that only the server knows about
13 | public/ // static files that are available to the client
14 | server/ // server code
15 | tests/ // unit test files (won't be loaded on client or server)
16 |
17 | ```
18 |
19 | After you create those directories in your application folder, the next step is to create some structure for your MVC model, add subscriptions and publications, and build out the rest of your application. How to do that depends on what kind of application you're designing... ie. a static web page, a mobile application, a thick-client game, a thin-client applet, and so forth. I find that most of my applications are starting to use the following structure, which uses HTML/CSS/JS as my Model/View/Controller.
20 |
21 | ```js
22 | .scrap // keep a .scrap or .temp directory for scrap files
23 |
24 | client/main.js // the main application javascript
25 | client/main.html // the main application html
26 | client/subscriptions.js // application subscriptions
27 | client/routes.js // application routes
28 |
29 | client/compatibility/ // legacy 3rd party javascript libraries
30 |
31 | client/templates/ // html files (document object model)
32 | client/stylesheets/ // css/less/styl files (view)
33 | client/controllers/ // js files (controllers)
34 |
35 | server/publications.js // Meteor.publish definitions
36 | server/environment.js // configuration of server side packages
37 | server/methods.js // cMeteor.method() definitions
38 | server/initializations/ // code for initializing collections
39 |
40 | lib/ // any common code for client/server.
41 | lib/schemas.js // schema validations and the like
42 | lib/collections.js // collection definitions and allow/deny rules
43 |
44 | packages/ // place for all your atmosphere packages
45 |
46 | public/ // static files that are served directly.
47 | public/images // will serve images as: '/images/foo.jpg'
48 |
49 | tests/ // unit test files (won't be loaded on client or server)
50 |
51 | ```
52 |
--------------------------------------------------------------------------------
/Refactoring with Test Driven Development.md:
--------------------------------------------------------------------------------
1 | ## Refactoring with Test Driven Development
2 | Refactoring test during test-driven-development is essentially the same as normal refactoring. We're just moving code around between files and directories.
3 |
4 |
5 |
6 | #### A) Initial Steps
7 | In both cases, we begin with a simple ``meteor create`` command, and then proceed to refactor to server/client architecture.
8 |
9 |
10 | ````js
11 | // meteor create helloWorld
12 | helloWorld/
13 | helloWorld.html
14 | helloWorld.css
15 | helloWorld.js
16 |
17 | // refactor to server/client architecture
18 | helloWorld/
19 | client/
20 | helloWorld.js
21 | helloWorld.html
22 | helloWorld.css
23 | server/
24 | methods.js
25 | ````
26 |
27 |
28 | #### B1) Tests In Same Repository (RTD, TinyTest, Mocha-Web)
29 | The one major difference between regular coding, and coding for test-or-behavior-driven-development (TDD/BDD), is that we don't want to have our tests actually be served up in production. We want to separate out our tests from production code. So, we need to create a separate directory for our tests.
30 |
31 | ````js
32 | // initial repository
33 | helloWorld/
34 | client/
35 | helloWorld.js
36 | helloWorld.html
37 | helloWorld.css
38 | server/
39 | methods.js
40 | tests/
41 | helloTest.js
42 | ````
43 |
44 | #### B2) Tests In Separate Repository (TestHarness, Safety Harness)
45 | However, we could also separate out our tests by putting them in an entirely different repository, and running them as a separate application altogether.
46 | ````js
47 | // initial repository
48 | helloWorld/
49 | client/
50 | helloWorld.js
51 | helloWorld.html
52 | helloWorld.css
53 | server/
54 | methods.js
55 |
56 | // testharness repository
57 | helloTests/
58 | helloTests.js
59 | ````
60 |
61 |
62 |
63 |
64 | #### Z1) Advanced Tests Within the Repository (RTD, TinyTest, Mocha-Web)
65 | Our decision will affect how we later structure our code. After a bit of time, we go to advanced topics, like stubbing and dependency injections.
66 |
67 | ````js
68 | // initial repository
69 | helloWorld/
70 | client/
71 | helloWorld/
72 | helloWorld.html
73 | helloWorld.js
74 | helloWorld.css
75 | niftyGizmo/
76 | niftyGizmo.html
77 | niftyGizmo.css
78 | niftyGizmo.js
79 | packages/
80 | server/
81 | methods.js
82 | tests/
83 | helloTestjs.js
84 | niftyGizmoTests.js
85 | /gizmo
86 | niftyGizmoStub.js
87 | niftyGizmoDependencyInjections.js
88 | ````
89 |
90 | #### Z2) Advanced Tests In Separate Repository (TestHarness, Safety Harness)
91 | And we have the choice of having all those stubs and mock objects in our main application, or in a separate application.
92 | ````js
93 | // initial repository
94 | helloWorld/
95 | client/
96 | helloWorld/
97 | helloWorld.html
98 | helloWorld.js
99 | helloWorld.css
100 | niftyGizmo/
101 | niftyGizmo.html
102 | niftyGizmo.css
103 | niftyGizmo.js
104 | packages/
105 | server/
106 | methods.js
107 |
108 | // testharness repository
109 | helloTestjs/
110 | helloTestjs.js
111 | niftyGizmoTests.js
112 | niftyGizmo/
113 | niftyGizmoStub.js
114 | niftyGizmoDependencyInjections.js
115 | ````
116 |
117 |
--------------------------------------------------------------------------------
/Namespacing.md:
--------------------------------------------------------------------------------
1 | ## Namespacing
2 | **Q: How do I do namespacing in Meteor?**
3 |
4 | There are four general approaches to creating namespaces in Meteor apps... the file system, package dependencies, CSS class namespacing, and naming conventions.
5 |
6 |
7 | **File System**
8 | The most important is to simply use the filesystem as a namespace. Feel free to organize files in folders however makes sense for your app, and use multi dotted names, or camelCase names, and go to town in creating ad-hoc namespaces. Meteor's bundler and minifier will combine all your files, and users and clients will never need to know how your internal files are organized. Feel free to rename files and directories as often as it makes sense to keep things organized.
9 | ````sh
10 | /client/templates/page.home.html
11 | /client/templates/page.profile.html
12 | /client/templates/page.graph.html
13 | /client/templates/page.error.pagenotfound.html
14 | /client/templates/page.error.unknownbrowser.html
15 | /client/templates/sidebar.inspection.html
16 | /client/templates/sidebar.navigation.html
17 | ````
18 |
19 |
20 | **NPM Package Namespacing (Controller)**
21 | However, if you need to expose a namespace, or import a namespace, you'll probably need to use Javascript objects and the Npm namespacing system. There are two steps in this process. The first is to expose a namespace via a Package. That is done with a ``package.js`` description file, which looks like this:
22 |
23 | ````js
24 | // package.js
25 | Package.describe({
26 | summary: "This is a sample package that exposes the Foo namespace."
27 | });
28 |
29 | // If you're bundling an NPM package, be sure to reference the package as a dependency
30 | Npm.depends({sample_package: "0.2.6", bar: '1.2.3'});
31 |
32 | Package.on_use(function (api) {
33 | // we set a package global variable with some value
34 | // in this case a JSON object
35 | Foo = {label: "foo object", value: "foo"};
36 |
37 | // alternatively, we can reference an Npm package
38 | Foo = Npm.require('sample_package');
39 |
40 | // and we then export the Foo variable
41 | api.export('Foo');
42 | });
43 | ````
44 | In particular, if you're trying to access Npm namespaces, the ``Npm.depends()``, ``Npm.require()``, and ``Npm.export()`` commands define all the syntax you need.
45 |
46 |
47 | **LESS Class Namespacing (View)**
48 | The third most common approach to namespacing is to use LESS to create CSS class hierarchies and namespaces. In the following example, the ``@import`` syntax defines a namespace hierarchy between LESS files; and the nested CSS classes define a hierarchical namespace in a tree format.
49 | ````less
50 | @import "../mixins.less";
51 |
52 | #homePage{
53 | background-color: white;
54 | header{
55 | background-color: gray;
56 | }
57 | .panel{
58 | .panel-heading{
59 | background-color: lightblue;
60 | }
61 | }
62 | footer{
63 | background-color: gray;
64 | }
65 | }
66 | ````
67 |
68 |
69 | **HTML Template Naming Conventions**
70 | Lastly, you can create namespaces by simply creating and using naming convetions throughout your application. For instance, you might create a template naming convetion, using camelCase, which matches with the id of the first in each template.
71 | ````html
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 | ````
80 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Eclipse
3 | #################
4 |
5 | *.pydevproject
6 | .project
7 | .metadata
8 | bin/
9 | tmp/
10 | *.tmp
11 | *.bak
12 | *.swp
13 | *~.nib
14 | local.properties
15 | .classpath
16 | .settings/
17 | .loadpath
18 |
19 | # External tool builders
20 | .externalToolBuilders/
21 |
22 | # Locally stored "Eclipse launch configurations"
23 | *.launch
24 |
25 | # CDT-specific
26 | .cproject
27 |
28 | # PDT-specific
29 | .buildpath
30 |
31 |
32 | #################
33 | ## Visual Studio
34 | #################
35 |
36 | ## Ignore Visual Studio temporary files, build results, and
37 | ## files generated by popular Visual Studio add-ons.
38 |
39 | # User-specific files
40 | *.suo
41 | *.user
42 | *.sln.docstates
43 |
44 | # Build results
45 |
46 | [Dd]ebug/
47 | [Rr]elease/
48 | x64/
49 | build/
50 | [Bb]in/
51 | [Oo]bj/
52 |
53 | # MSTest test Results
54 | [Tt]est[Rr]esult*/
55 | [Bb]uild[Ll]og.*
56 |
57 | *_i.c
58 | *_p.c
59 | *.ilk
60 | *.meta
61 | *.obj
62 | *.pch
63 | *.pdb
64 | *.pgc
65 | *.pgd
66 | *.rsp
67 | *.sbr
68 | *.tlb
69 | *.tli
70 | *.tlh
71 | *.tmp
72 | *.tmp_proj
73 | *.log
74 | *.vspscc
75 | *.vssscc
76 | .builds
77 | *.pidb
78 | *.log
79 | *.scc
80 |
81 | # Visual C++ cache files
82 | ipch/
83 | *.aps
84 | *.ncb
85 | *.opensdf
86 | *.sdf
87 | *.cachefile
88 |
89 | # Visual Studio profiler
90 | *.psess
91 | *.vsp
92 | *.vspx
93 |
94 | # Guidance Automation Toolkit
95 | *.gpState
96 |
97 | # ReSharper is a .NET coding add-in
98 | _ReSharper*/
99 | *.[Rr]e[Ss]harper
100 |
101 | # TeamCity is a build add-in
102 | _TeamCity*
103 |
104 | # DotCover is a Code Coverage Tool
105 | *.dotCover
106 |
107 | # NCrunch
108 | *.ncrunch*
109 | .*crunch*.local.xml
110 |
111 | # Installshield output folder
112 | [Ee]xpress/
113 |
114 | # DocProject is a documentation generator add-in
115 | DocProject/buildhelp/
116 | DocProject/Help/*.HxT
117 | DocProject/Help/*.HxC
118 | DocProject/Help/*.hhc
119 | DocProject/Help/*.hhk
120 | DocProject/Help/*.hhp
121 | DocProject/Help/Html2
122 | DocProject/Help/html
123 |
124 | # Click-Once directory
125 | publish/
126 |
127 | # Publish Web Output
128 | *.Publish.xml
129 | *.pubxml
130 |
131 | # NuGet Packages Directory
132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
133 | #packages/
134 |
135 | # Windows Azure Build Output
136 | csx
137 | *.build.csdef
138 |
139 | # Windows Store app package directory
140 | AppPackages/
141 |
142 | # Others
143 | sql/
144 | *.Cache
145 | ClientBin/
146 | [Ss]tyle[Cc]op.*
147 | ~$*
148 | *~
149 | *.dbmdl
150 | *.[Pp]ublish.xml
151 | *.pfx
152 | *.publishsettings
153 |
154 | # RIA/Silverlight projects
155 | Generated_Code/
156 |
157 | # Backup & report files from converting an old project file to a newer
158 | # Visual Studio version. Backup files are not needed, because we have git ;-)
159 | _UpgradeReport_Files/
160 | Backup*/
161 | UpgradeLog*.XML
162 | UpgradeLog*.htm
163 |
164 | # SQL Server files
165 | App_Data/*.mdf
166 | App_Data/*.ldf
167 |
168 | #############
169 | ## Windows detritus
170 | #############
171 |
172 | # Windows image file caches
173 | Thumbs.db
174 | ehthumbs.db
175 |
176 | # Folder config file
177 | Desktop.ini
178 |
179 | # Recycle Bin used on file shares
180 | $RECYCLE.BIN/
181 |
182 | # Mac crap
183 | .DS_Store
184 |
185 |
186 | #############
187 | ## Python
188 | #############
189 |
190 | *.py[co]
191 |
192 | # Packages
193 | *.egg
194 | *.egg-info
195 | dist/
196 | build/
197 | eggs/
198 | parts/
199 | var/
200 | sdist/
201 | develop-eggs/
202 | .installed.cfg
203 |
204 | # Installer logs
205 | pip-log.txt
206 |
207 | # Unit test / coverage reports
208 | .coverage
209 | .tox
210 |
211 | #Translations
212 | *.mo
213 |
214 | #Mr Developer
215 | .mr.developer.cfg
216 |
--------------------------------------------------------------------------------
/Development Tools.md:
--------------------------------------------------------------------------------
1 | ## Development Tools
2 | **Q: What are best practices for setting up my development environment?**
3 | Well, you're going to need to select an Integrated Development Environment (IDE), configure it so it works with Meteor, and set up debugging and profiling utilities. See below.
4 |
5 | [WebStorm](http://www.jetbrains.com/webstorm/) - The most full featured IDE currently available for Meteor.
6 | [Sublime](http://www.sublimetext.com/) -For something more light-weight and quick, try Sublime.
7 | [Nitrous.io](https://www.nitrous.io/) - The best and only Cloud Development tool worth worrying about.
8 |
9 | **Q: My editor keeps crashing! Help!**
10 | Add the myapp/.meteor directory to your ignore list. Meteor takes your application and goes through a process called bundling, where it prepares to host it as a node.js application. It uses the .meteor directory as a temp directory, and will try to rebundle whenever there are changes to your code. If your editor is watching that directory, it can cause your editor to lock up with the constant indexing and bundling.
11 |
12 | ````js
13 | // Webstore > Preferences > Directories > Excluded Directories
14 | .meteor
15 | ````
16 |
17 | **Q: Any recommendations on Browser Debugging?**
18 |
19 | [Chrome - Window Resizer](https://chrome.google.com/webstore/detail/window-resizer/kkelicaakdanhinjdeammmilcgefonfh) or
20 | [Firefox - Firebug](https://getfirebug.com/)
21 |
22 |
23 | **Q: Any recommendations on pair-programming?**
24 |
25 | [Screenhero](http://screenhero.com/download.html?src=btn) or
26 | [MadEye](https://madeye.io/#getStarted)
27 |
28 |
29 |
30 |
31 | **Q: How do I debug node.js itself?**
32 | ````
33 | npm install -g node-inspector
34 |
35 | export NODE_OPTIONS='--debug'
36 | sudo mrt run
37 | sudo node-inspector &
38 |
39 | http://0.0.0.0:8080/debug?port=5858
40 | ````
41 |
42 |
43 | **Q: Help! I'm behind a proxy! How can I install/run Meteor behind a reverse proxy?**
44 | This is a networking issue related to your operating system and local network topology, something that the Meteor Development Group doesn't really have any control over. Some people have had success updating their bash environment variables, and running the installer with curl, like so:
45 | ````js
46 | // make sure your shell knows about your proxy
47 | export http_proxy=http://your.proxy.server:port/
48 |
49 | // install meteor manually
50 | curl https://install.meteor.com | sh
51 | ````
52 |
53 | Also, watch follow this issue:
54 | https://github.com/meteor/meteor/pull/920
55 |
56 |
57 |
58 | #### Mobile Device Simulators
59 | [Window Resizer (Chrome)](https://chrome.google.com/webstore/detail/window-resizer/kkelicaakdanhinjdeammmilcgefonfh)
60 |
61 | #### Database Tools
62 | [MacOSX Mongo Preference Page](http://blog.mongodb.org/post/28925264384/macosx-preferences-pane-for-mongodb)
63 | [Robo Mongo](http://robomongo.org/) - A sweet, sweet database management tool. Highly recommended.
64 | [MongoHub](http://mongohub.todayclose.com/) - Another Mongo GUI, similar to RoboMongo.
65 | [Mongo3](http://mongo3.com/) - It's in Ruby, but it will let you visualize replication sets.
66 |
67 |
68 |
69 |
70 | #### REST Clients
71 | [Dev HTTP Client](https://chrome.google.com/webstore/detail/dev-http-client/aejoelaoggembcahagimdiliamlcdmfm)
72 | [REST Client](https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm/)
73 |
74 |
75 |
76 | #### Debuggers
77 | [Firebug (Firefox)](https://getfirebug.com/)
78 | [Node-Inspector](https://github.com/node-inspector/node-inspector)
79 |
80 | http://howtonode.org/debugging-with-node-inspector
81 | ````
82 | npm install -g node-inspector
83 |
84 | export NODE_OPTIONS='--debug'
85 | sudo mrt run
86 | sudo node-inspector &
87 |
88 | http://0.0.0.0:8080/debug?port=5858
89 | ````
90 |
91 | #### Code Analysis
92 |
93 | [Meteor JSHint](https://github.com/raix/Meteor-jshintrc)
94 |
95 | ````sh
96 | npm install jshint -g
97 | jshint .
98 | ````
99 |
--------------------------------------------------------------------------------
/Site Configuration.md:
--------------------------------------------------------------------------------
1 | ## Site Configuration
2 | A pattern for creating persistent site configuration.
3 |
4 | ### /client
5 |
6 | ````js
7 | // client/app.subscriptions.js
8 | Session.setDefault('settingsLoaded', false);
9 | Meteor.subscribe('settings', function(){
10 | Session.set('settingsLoaded',true);
11 | Session.set('systemConfigs', Settings.find().fetch()[0]);
12 | });
13 |
14 | // client/controllers/app.navbars.js
15 | Template.navbarHeader.navbarTitle = function(){
16 | if(Session.get('settingsLoaded')){
17 | return Session.get('systemConfigs').name;
18 | }else{
19 | return 'Site not ready...';
20 | }
21 | };
22 | ````
23 |
24 | ````html
25 |
26 |
27 |
32 |
33 | ````
34 |
35 |
36 | ### /
37 | This is isomorphic code that needs to be run in the app root, outside of the /client or /server directories.
38 | ````js
39 | // data.js or model.js file
40 |
41 | Settings = new Meteor.Collection("settings");
42 |
43 | Settings.allow({
44 | insert: function(){
45 | return true;
46 | },
47 | update: function () {
48 | return true;
49 | },
50 | remove: function(){
51 | return true;
52 | }
53 | });
54 | ````
55 |
56 |
57 | ### /server
58 |
59 | ````js
60 | // server/initialize.settings.js
61 | Meteor.startup(function () {
62 | if (Settings.find().count() === 0) {
63 | console.info('no settings in database! creating a configuration file.');
64 |
65 | var configurationId = null;
66 |
67 | // crate our administrator
68 | configurationId = Settings.insert({
69 | keyword: 'sysadmin',
70 | name: 'MySite',
71 | tagline: 'Witty tagline for site...',
72 | installed: false,
73 | live: false,
74 | maintenance: false,
75 | bootCount: 0
76 | });
77 | console.info('Configuration file created: ' + configurationId);
78 | }
79 | });
80 |
81 | // server/publications.js
82 | Meteor.publish("settings", function () {
83 | try{
84 | return Settings.find({keyword: 'sysadmin'}, {fields: {
85 | 'name': true,
86 | 'logo': true,
87 | 'tagline': true,
88 | 'installed': true,
89 | 'live': true,
90 | 'maintenance': true,
91 | 'bootCount': true
92 | }});
93 | }catch(error){
94 | console.log(error);
95 | }
96 | });
97 | ````
98 |
99 | ## Running Code At Startup
100 |
101 | #### Using persistent records in the database.
102 | ````js
103 | // server/startup.js
104 | Meteor.startup(function () {
105 | configurationSettings = Settings.find().fetch()[0];
106 | newBootCount = configurationSettings.bootCount + 1;
107 | Settings.update(configurationSettings._id, {$set: { bootCount: newBootCount }});
108 |
109 | if(configurationSettings.live){
110 | console.log('Success! Youre running a live site!');
111 | }else{
112 | console.log('Success! Youre running the site for the first time! Its not live yet, however.');
113 | console.log('Please go to admin panel, and configure the site.');
114 | }
115 | });
116 | Meteor.methods({
117 | setSiteLive: function(){
118 | configurationSettings = Settings.find().fetch()[0];
119 | Settings.update(configurationSettings._id, {$set: { live: true }});
120 | }
121 | });
122 |
123 | ````
124 |
125 | #### Working Around Hot-Code Reloads in Development
126 |
127 | ````js
128 | Meteor.startup(function () {
129 | configurationSettings = Settings.find().fetch()[0];
130 | var now = moment();
131 |
132 | if(now.diff(configurationSettings.keepAlive, 'minutes') > 1){
133 | // do complicated stuff you want run on console startup
134 | // but not during hot code reloads
135 | }
136 |
137 | // update the keepAlive once a minute
138 | setInterval(function(){
139 | Settings.update(configurationSettings._id, {$set: { keepAlive: moment() }});
140 | }, 1000)
141 | });
142 | ````
143 |
144 |
--------------------------------------------------------------------------------
/Test Driven Development.md:
--------------------------------------------------------------------------------
1 | # Test Driven Development
2 |
3 | For an introduction to different types of tests (unit, integration, functional, acceptance, regression, smoke tests), see these StackOverflow questions:
4 |
5 | [unit/integration/functional/acceptance](http://stackoverflow.com/questions/4904096/whats-the-difference-between-unit-functional-acceptance-and-integration-test)
6 | [integration/smoke/regression](http://stackoverflow.com/questions/520064/what-is-unit-test-integration-test-smoke-test-regression-test?lq=1)
7 |
8 | ## Frameworks
9 |
10 | So, the bad news is that the test driven development in Meteor is still somewhat in its infancy. The good news is that it's starting to mature, with a number of different approaches being investigated. So, maybe it's more of a toddler than an infant.
11 |
12 | Regardless, if you'd like a comprehensive rundown of the options, keep tabs on the following feature comparison table:
13 | http://safety-harness.meteor.com/comparison
14 |
15 | #### [Tinytest](https://github.com/meteor/meteor/tree/devel/packages/tinytest)
16 |
17 | Meteor's [undocumented](https://www.meteor.com/blog/2013/04/04/meteor-060-brand-new-distribution-system-app-packages-npm-integration) but built-in basic unit testing for writing packages, with some [helpers](https://github.com/meteor/meteor/tree/devel/packages/test-helpers). You can test your app that way too if you package it as a Meteor package, which amounts to adding a `package.js file`, adding a reference to ``tinytest``, and then runnning ``meteor test-packages`` from the command line.
18 |
19 | * [video tutorial on Eventedmind](https://www.eventedmind.com/tracks/feed-archive/meteor-testing-packages-with-tinytest) and [accompanying example](https://github.com/EventedMind/meteor-file) + [example of using the undocumented helpers for client testing](http://inconsistency.in/post/52547787175/flash-messages-package-and-testing-events-on-meteor).
20 | * [Tinytest integration with Travis CI](https://github.com/arunoda/travis-ci-meteor-packages)
21 |
22 | #### Mocha-Web
23 |
24 | Basic unit test runner and HTML reporter, that can be installed as a package.
25 | [Atmosphere](https://atmosphere.meteor.com/package/mocha-web) / [GitHub](https://github.com/mad-eye/meteor-mocha-web)
26 |
27 | #### [RTD](http://rtd.xolv.io) With Selenium, Mocha, Jasmine, and Istanbul
28 | In-depth unit testing and acceptance testing; relies on a command line interface, and requires the app code to live in an `app` directory. [Inpsired by](http://blog.madeye.io/2013/02/testing-meteor-here-at-madeye-were-big.html?showComment=1364314050448#c7796997551340499047) Mocha-Web.
29 |
30 | * https://github.com/xolvio/meteor-rtd-example-project
31 | * http://blog.xolv.io/2013/04/unit-testing-with-meteor.html
32 | * CoinsManager - [large-ish code base using RTD](https://github.com/CoinsManager/CoinsManager)
33 |
34 | RTD [plans to integrate Laika](https://github.com/xolvio/rtd/issues/63).
35 |
36 | #### [Laika](http://arunoda.github.io/laika/)
37 | Integration testing using a command line interface, with a [somewhat convoluted API](https://github.com/arunoda/laika/issues/97). Handy for engineering extensions to Meteor itself. [Doesn't provide code coverage](https://github.com/xolvio/rtd/issues/22#issuecomment-20442959).
38 |
39 | * Creating a Meteor app + [Laika tutorial](http://mherman.org/blog/2014/01/29/meteor-dot-js-in-action-create-an-app-test-with-laika/)
40 |
41 | ### Safety Harness
42 | Acceptance testing framework with HTML reporter.
43 | http://safety-harness.meteor.com/
44 |
45 | #### More
46 |
47 | * "Testing" section on [Best learning resources for Meteor.js](http://yauh.de/articles/376/best-learning-resources-for-meteorjs)
48 | * [Meteor test-driven development](http://stackoverflow.com/questions/12987525/meteor-test-driven-development) on StackOverflow
49 |
50 | ------------------------------------------------------------------
51 | ## Load Testing
52 |
53 | Using PhantomJS:
54 | https://gist.github.com/awatson1978/5139909
55 |
56 | Load Testing on AWS:
57 | https://groups.google.com/forum/?fromgroups=#!searchin/meteor-talk/load$20test/meteor-talk/BJXA1FRuTzU/M2e9pCH4es0J
58 |
--------------------------------------------------------------------------------
/_book/gitbook/jsrepl/engines/javascript-default.js:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright Joyent, Inc. and other Node contributors.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a
6 | copy of this software and associated documentation files (the
7 | "Software"), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to permit
10 | persons to whom the Software is furnished to do so, subject to the
11 | following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included
14 | in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
19 | NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
20 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 | USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
24 | Original at: https://github.com/joyent/node/blob/master/lib/util.js
25 | */
26 | (function(){function o(c){return c instanceof Array||Array.isArray(c)||c&&c!==Object.prototype&&o(c.__proto__)}function p(c){return c instanceof RegExp||typeof c==="function"&&c.constructor.name==="RegExp"&&c.compile&&c.test&&c.exec&&(""+c).match(/^\/.*\/[gim]{0,3}$/)}var q=80,l=function(c,h,b,f){function m(a,c){switch(typeof a){case "undefined":return d("undefined","undefined");case "string":var b="'"+JSON.stringify(a).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return d(b,"string");
27 | case "number":return d(""+a,"number");case "boolean":return d(""+a,"boolean")}if(a===null)return d("null","null");var f=Object.keys(a),i=h?Object.getOwnPropertyNames(a):f;if(typeof a==="function"&&i.length===0)return p(a)?d(""+a,"regexp"):d("[Function"+(a.name?": "+a.name:"")+"]","special");if(a instanceof Date&&i.length===0)return d(a.toUTCString(),"date");var j,l;o(a)?(l="Array",b=["[","]"]):(l="Object",b=["{","}"]);typeof a==="function"?(j=a.name?": "+a.name:"",j=p(a)?" "+a:" [Function"+j+"]"):
28 | j="";a instanceof Date&&(j=" "+a.toUTCString());if(i.length===0)return b[0]+j+b[1];if(c<0)return p(a)?d(""+a,"regexp"):d("[Object]","special");k.push(a);i=i.map(function(b){var e,g;a.__lookupGetter__&&(a.__lookupGetter__(b)?g=a.__lookupSetter__(b)?d("[Getter/Setter]","special"):d("[Getter]","special"):a.__lookupSetter__(b)&&(g=d("[Setter]","special")));f.indexOf(b)<0&&(e="["+b+"]");g||(k.indexOf(a[b])<0?(g=c===null?m(a[b]):m(a[b],c-1),g.indexOf("\n")>-1&&(g=o(a)?g.split("\n").map(function(a){return" "+
29 | a}).join("\n").substr(2):"\n"+g.split("\n").map(function(a){return" "+a}).join("\n"))):g=d("[Circular]","special"));if(typeof e==="undefined"){if(l==="Array"&&b.match(/^\d+$/))return g;e=JSON.stringify(""+b);e.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(e=e.substr(1,e.length-2),e=d(e,"name")):(e=e.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),e=d(e,"string"))}return e+": "+g});k.pop();var n=0;return i=i.reduce(function(a,b){n++;b.indexOf("\n")>=0&&n++;return a+b.length+1},0)>q?b[0]+
30 | (j===""?"":j+"\n ")+" "+i.join(",\n ")+" "+b[1]:b[0]+j+" "+i.join(", ")+" "+b[1]}var k=[],d=function(a,b){var c={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},d={special:"cyan",number:"blue","boolean":"yellow",undefined:"grey","null":"bold",string:"green",date:"magenta",regexp:"red"}[b];return d?"\u001b["+c[d][0]+"m"+a+"\u001b["+c[d][1]+"m":a};f||(d=function(a){return a});
31 | return m(c,typeof b==="undefined"?2:b)},r=/%[sdj%]/g,s=function(c){if(typeof c!=="string"){for(var h=[],b=0;b=m)return c;switch(c){case "%s":return String(f[b++]);case "%d":return Number(f[b++]);case "%j":return JSON.stringify(f[b++]);case "%%":return"%";default:return c}}),k=f[b];b
41 |
42 | hello
43 |
44 |
45 | ````
46 |
47 | And add a template function to update on a dynamic Session variable.
48 | ````
49 | Template.foo.current_theme_name = function(){
50 | if(Session.get('current_theme_name') == 'black'){
51 | return "theme1";
52 | }else{
53 | return "theme2";
54 | }
55 | }
56 | ````
57 |
58 | Then add some LESS magic, using nested CSS classes and a custom namespacing:
59 | ````
60 | theme1 {
61 | t1 {background-color: black}
62 | }
63 | theme2 {
64 | t1 {background-color: red}
65 | }
66 | ````
67 |
68 |
69 | And wrap it all up with some controls to toggle the dynamic session variable.
70 | ````
71 | Template.bar.events({
72 | 'click .button-black: function(){
73 | Session.set('current_theme_name', 'black');
74 | },
75 | 'click .button-red: function(){
76 | Session.set('current_theme_name', 'red');
77 | }
78 | })
79 | ````
80 |
81 |
82 |
83 | ------------------------------------------------------------------
84 | ### Miscellaneous Notes
85 |
86 | Also, while talking about dependencies and 'how to use meteor', I'll mention this... the Reactive Templates are really awesome, but as I mentioned... they bubble. Sometimes that bubbling is fast, sometimes it's slow. Moreover, it will break many 3rd party libraries.
87 |
88 | Countless discussions have already occurred with people trying to add Isotope.js, List.js, and similar libraries, which implement various 3rd party functionality. Time and time again, people try to introduce an external library like Isotope.js or List.js, because it's class oriented and has a two important areas of functionality that they're interested in... the first is for list management functionalities... sorting, searching, filtering, and the like. The second being for a specific user interface. A grid layout. A swipe function. Pagination. etc.
89 |
90 | Meteor and mongo will take care of the first portion... the sorting, searching, filtering. And it will do it at it's own speed. Usually blazingly fast, sometimes slowly, as things bubble through the templates. However, you might still want to implement a bit of swipe functionality, or a grid layout and such. Now, you may be accustomed to using javascript to implement those features. The bubbling templates will break that approach, and cause things to get re-rendered. You'll get flickering. Instead, those features like grids and movement of elements want to be moved into CSS, where their state will persist through re-renders without flickering. More importantly, all the hardware accelerated goodness is in the CSS, so if you want to offload processing from the core, and move it onto the GPU, you're going to need to use CSS. That's important for mobile platforms, of course. And it's the only way you'll get good animations is with the CSS, not through Javascript.
91 |
92 | To bring things round back to dependencies, be sure to run 'meteor add less'. If you haven't used a CSS precompiler, get ready to have a birthday present! In particular, Meteor now supports the less @import command. So, for any code that needs hardware acceleration, move it into your CSS, and use the @import command to manage dependencies. In fact, you may want to set up some namespacing for syntax that gets reused, like so:
93 |
94 | ````
95 | \client\stylesheets\syntax.custom.less
96 | \client\stylesheets\syntax.fonts.less
97 | \client\stylesheets\syntax.themes.less
98 | \client\stylesheets\syntax.base.less
99 | ````
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/Console Logging.md:
--------------------------------------------------------------------------------
1 | ## Console Logging
2 |
3 | If you're from a DevOps, Operations, or SysAdmin background, this is probably one of the first sections of the Meteor Cookbook that you looked into. If you're from any other background, you may be surprised to find just how many tools are available for logging. Many people consider log files to be one of the most important part of a running application, and I've seen few successful applications put into production that didn't have some type of logging available.
4 |
5 | As far as Meteor goes, there are many, many options available. Particularly if you dive into the [Npm repositories](https://npmjs.org/search?q=logging). But one of the aims of the Meteor Cookbook is to use pure Meteor, when possible, and to advocate the using of the native tools. Before looking to add extra packages and tools, lets start trying to learn the tools we already have.
6 |
7 | ### Server Side Logging Tools
8 | The first step to logging is simply to run Meteor from the shell, and you'll get the server logs in the command console.
9 |
10 | ````
11 | sudo meteor
12 | ````
13 | The next step is to pipe the contents of ``std_out`` and ``std_err`` to a logfile, like so:
14 |
15 | ````sh
16 | meteor > my_app_log.log 2> my_app_err.log
17 | ````
18 |
19 | If you've gotten to the point where you're running things in production, or want your application running continuously, you can set up your logs by running [Ubuntu's upstart command](http://upstart.ubuntu.com/) or [OSX System Starter](https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man8/SystemStarter.8.html). An Ubuntu upstart script which generates log files from a Meteor app in production looks like this:
20 |
21 | ````sh
22 | ## /etc/init/helloworld.conf
23 | description "hello world"
24 | author "awatson1978"
25 |
26 | # Automatically Run on Startup
27 | start on started mountall
28 | stop on shutdown
29 |
30 | # Automatically Respawn:
31 | respawn
32 | respawn limit 99 5
33 |
34 | script
35 | export HOME="/root"
36 | export MONGO_URL='mongodb://helloworld.mongohq.com:27017/meteor'
37 | export ROOT_URL='http://helloworld.meteor.com'
38 | export PORT='80'
39 |
40 | exec /usr/local/bin/node /var/www/helloworld/main.js >> /var/log/helloworld.log 2>&1
41 | end script
42 | ````
43 |
44 | ### Client Side Logging Tools
45 |
46 | Once you have your server side logging in place, it's time to hop over to the client side. If you haven't explored the console API, be prepared for a treat. There's actually all sorts of things that you can do with the built in Console API that's native to every Chrome and Safari installation. So much so, in fact, that you may find yourself not needing Winston or other logging frameworks.
47 |
48 | The first thing you'll want to do is install client side logging and developer tools. Chrome and Safari both ship with them, but Firefox requires the Firebug extension.
49 |
50 | **Firebug Extension**
51 | https://addons.mozilla.org/en-US/firefox/addon/firebug/
52 |
53 | Then, you'll want to check out the Console API documentation. The following two documents are invaluable resources for learning console logging.
54 |
55 | **Chrome Developer Tools**
56 | https://developers.google.com/chrome-developer-tools/docs/console
57 |
58 | **Firebug (Client)**
59 | http://getfirebug.com/logging
60 |
61 |
62 | ### Advanced Server Logging Tools
63 |
64 | So, once you have both your server-side logging running, and your client side development tools, you can start looking at Meteor specific extensions like the Meteor Chrome DevTools Extension. This lets you actually observe server logging in the client! Because the database is everywhere. As is logging.
65 |
66 | **Chrome DevTools Extension (Server)**
67 | https://github.com/gandev-de/meteor-server-console
68 |
69 |
70 | 
71 |
72 |
73 |
74 | ### Application Patterns
75 |
76 | Once those pieces are in place, you're totally ready to start logging events in your application. In practice, there are a half-dozen commands that are particularly useful. Here are three quick examples illustrating very common logging patterns in Meteor.
77 |
78 | ````js
79 | // EXAMPLE 1: Logging an error if the data is not available
80 | Template.landingPage.postsList = function(){
81 | try{
82 | return Posts.find();
83 | }catch(error){
84 | //color code the error (red)
85 | console.error(error);
86 | }
87 | }
88 |
89 | // EXAMPLE 2: Inspecting objects in a Handlebar template helper
90 | Template.landingPage.getId = function(){
91 | // using a group block to illustrate function scoping
92 | console.group('coolFunction');
93 |
94 | // inspect the current data object that landingPage is using
95 | console.log(this);
96 |
97 | // inspect a specific field of the locally scoped data object
98 | console.log(JSON.stringify(this._id);
99 |
100 | // close the function scope
101 | console.groupEnd();
102 | return this._id;
103 | }
104 |
105 | // EXAMPLE 3: Logging events and user interactions
106 | Template.landingPage.events({
107 | 'click .selectItemButton':function(){
108 | // color code and count the user interaction (blue)
109 | console.count('click .selectItemButton');
110 | }
111 | });
112 | ````
113 |
114 |
115 | ### Winston
116 | Lastly, if you need something more powerful than the default logging options, you might want to look at a tool like Winston. Go to [Atmosphere](https://atmosphere.meteor.com), and simply search for ``Winston`` to find the latest packages available. Be warned, however - [Winston](https://github.com/flatiron/winston) is a sophisticated product, and while it exposes a lot of functionality, it will also add a layer of complexity to your application.
117 |
--------------------------------------------------------------------------------
/Dependencies.md:
--------------------------------------------------------------------------------
1 | ### Core Dependencies
2 | **Q: Is jQuery a core package?**
3 | Sortof. It's a dependency of Spark, and is included in pretty much all core applications. In the new [Blaze UI, jQuery is used for event handling](https://github.com/meteor/meteor/wiki/Using-Blaze#events-use-jquery). Assume it's a core package.
4 |
5 | **Q: I'm looking in myapp/.meteor/packages, and I don't see jQuery listed. Why does my app act like it's loading jQuery?**
6 | Because it's a dependency of Spark. It's a hidden dependency. `myapp/.meteor/packages` is not a definitive list of dependencies. Just the most immediate dependencies.
7 |
8 | ### Dependency Load Ordering
9 |
10 | Something that really trips people up a lot with Meteor is load ordering and dependencies, particularly if they're accustomed to sequential or imperative style programming (i.e. coming from object-oriented languages and frameworks). When it comes to the ordering and sequence of events, there are two phases. First, there's the bundling of resource. During bundling, as Meteor prepares your application for deployment, it gathers up all your resources and files, and puts them into a bundle according to rules on how **it** thinks things should be ordered. So, the first step to getting load ordering right, is to learn to adjust your file directories and naming schemas to fit with the Meteor bundler.
11 |
12 | The simple rule of thumb is that the bundler includes files in the deepest directories first (see following example). You'll note that this bundling order has specifically influenced our previous discussion on 'where should we put files?'
13 |
14 | ````js
15 | // the bundling process output is such that libraries in the deepest directories will be loaded first
16 | /client/lib/deepest/folder/library.js
17 | /client/lib/deeper/library.js
18 | /client/lib/library.js
19 |
20 | // and libraries in the root directory will be loaded last
21 | /client/library.js
22 |
23 | // meteor then bundles and deploys
24 | ````
25 |
26 | ### 3rd Party Libraries
27 |
28 | **Q: How do I add dependencies?**
29 | If you haven't run across Meteorite and Atmosphere and the mrt command utility, do some research on those terms. In the /usr/loca/meteor/packages directory, you'll find all the source code for the packages themselves, and take a gander at the package.js files. Those, in conjunction with the 'meteor add package-name' syntax is how Meteor handles much of the dependency type stuff. Of course, the dependency management requires that a package is built in the first place.
30 | https://atmospherejs.com/
31 |
32 | **Q: How do I get a 3rd-party-library.js to work with Meteor?**
33 |
34 | Installing a 3rd party library doesn't have to be hard. If you're having problems, it's probably because the reactive templates are overwriting the objects you created. There are a few ways to deal with this:
35 |
36 | 1. Move your code out of reactive templates. Autorun() is a good event hook for creating objects in.
37 |
38 | ```js
39 | Deps.autorun(function(){
40 | // the timeline object is outside the scope of any reactive templates
41 | timeline = new Timeline();
42 | });
43 | ```
44 |
45 |
46 | 2. check to see if your object already exists
47 | ```js
48 | Template.templateWithConstantRegion.rendered = function(){
49 | // we simply add feature detection to see if the object already exists
50 | self.node = self.find("#timelineObject");
51 | if (! self.handle) {
52 | // don't get worked up about this Deps.autorun()
53 | // it's an option addition to this pattern
54 | self.handle = Deps.autorun(function(){
55 | Timeline();
56 | });
57 | };
58 | };
59 |
60 | // don't forget to complete the pattern by tearing down the object properly
61 | Template.templateWithConstantRegion.destroyed = function () {
62 | this.handle && this.handle.stop();
63 | };
64 | ```
65 |
66 | 3. use a ``#constant`` region or a ``Template.frontPage.preserve()`` callback
67 | ```html
68 |
69 |
70 | {{#constant}}
71 |
72 | {{/contant}}
73 |
74 |
75 | ```
76 |
77 |
78 | 4. You'll also want to check for `var` keywords in your library. Unlike most other Javascript frameworks, Meteor uses the 'var' keyword in a very specific way to restrict the scope of a variable to a single file. So, many libraries will use the 'var' keyword to simply define a variable to the global scope; but Meteor will interpret the 'var' to mean a variable specific to the local file. This causes problems sometimes.
79 |
80 | ````js
81 | // variable restricted to local file
82 | var foo = 42;
83 |
84 | // variable shared between files
85 | foo = 42;
86 |
87 | // bad; function restricted to local scope
88 | // source of lots of frustration and broken applications
89 | var createStoryJS = function (){ ... }
90 |
91 | // less bad; not explicitely restricted because of the 'var' keyword
92 | // but still restricted to local scope because of synxtax
93 | // still breaks many things
94 | function createStoryJS(){ ... }
95 |
96 | // good; function can be shared between files
97 | createStoryJS = function (){ ... }
98 | ````
99 |
100 | Note: I'm being judgemental here, and saying certain approaches are 'good' and 'bad', which implies certain ways of coding things. If you're used to using ``private`` and ``public`` keywords, you'll note that the ``var`` keyword acts like ``private``, and can be useful for encapsulation and preventing internal variables from being shared with outside scopes. That's a good thing. Proper encapsulation and scoping should be encouraged. But for people debugging applications and trying to integrate 3rd party libraries, the default usage of the ``var`` keyword breaks a lot of things, and the bottom line is that they generally need to bring some of the private variables into a more global context.
101 |
--------------------------------------------------------------------------------
/Cookbook Conventions.md:
--------------------------------------------------------------------------------
1 | ## Cookbook Conventions
2 |
3 |
4 | Hello, and welcome to the Meteor Cookbook.
5 |
6 | Before diving into this cookbook, please be aware of the following two conventions, which are used throughout these tutorials and examples.
7 |
8 |
9 | #### Browsers and Operating Systems
10 | Generally speaking, the Cookbook caters to a Mac development environment, and WebKit browsers. The official Meteor position is that Meteor is going to support Windows and SQL databases in version 1.1 or later. The Meteor Cookbook is focused on Meteor 1.0, then.
11 |
12 |
13 | #### The OSI Model
14 |
15 | First, it's generally structured around the Open Systems Interconnection (OSI) Model ((ISO/IEC 7498-1)).
16 | http://en.wikipedia.org/wiki/OSI_model
17 |
18 | This model is typically used to describe network communications, and how packets of data travel from one machine to the next. It describes how a client request to the server travels down the protocol stack, through the database, getting assigned TCP/IP headers, onto the wire (ethernet or wi-fi, etc), to the other machine, and back up the network stack to the server application. That's how 90% of people understand the OSI model.
19 |
20 | 
21 |
22 | However, if you've worked with the OSI model **a lot**, you'll know that it can be used for a lot more. In particular, it can also be used to model haptics, physical devices, and human-computer interfaces. Because, in the end, physical devices like mice and printers are basically just other machines. Very dumb ones. But the principles of network communications still apply. Your mouse is connected to your computer by a wire, and while it doesn't use the TCP/IP protocol, the {x,y} coordinates are still getting mapped to wire protocol. And you can use the OSI model to describe that mapping.
23 |
24 | So, be forewarned: the Meteor Cookbook adopts a rather generous interpretation of the OSI model to describe client side devices, device drivers, haptics, and the like. And rather than placing Mice and other client-side devices in the Application Layer, they're in the Physical and DataLink layer. It's more of a mesh networking approach, in keeping with today's modern wireless input devices.
25 |
26 |
27 | #### Model-View-Controller
28 |
29 | Second, the Meteor Cookbook makes an opinionated choice about how to treat MVC, and tends towards a thick-click and desktop models of how MVC is structured. In particular, it avoids server-side Ruby and Angular MVC patterns, which treat a View as a collection of HTML and Javascript.
30 |
31 | A little background to put this into context. In the 1970s, Xerox PARC developed the first mouse interface and first GUI. They used a Model-View-Controller paradigm, which was copied throughout most of the 1980s by Apple, SGI, Sun, and all the other computer tech companies of the era. MVC was fairly well understood during those days.
32 |
33 | 
34 |
35 | Then, in the 1990s, the Web came onto the scene, and people started building server-client applications. This caused a big schism in how people understood the MVC model. The client-side developers continued to apply the same MVC models from before, which is how Web Browsers wound up ubiquitously using HTML, CSS, and JS to render pages.
36 |
37 | 
38 |
39 | However, server developers tend not to focus so much on how a page renders. By and large, there was a division of labor that occured, with back-end server developers worrying more about performance, databases, workflow, and so forth. The division of labor happened such that they began to view anything related to CSS as being a 'graphics design' issue. And, being removed from the View portion of the MVC model, they began reusing the 'View' in MVC to mean something slightly different.
40 |
41 | It should be noted that the server-side folks wills say that it's the client-side folks who've got it wrong. And they'll point to Angular and Ruby and say "look how successful these projects are". And "are you really questioning Google's MVC design?" And the answer is... well, yeah. Anybody who thinks that CSS isn't part of the View would be well served to revisit Knuth's Art of Computer Programming and the code for TeX and LaTeX, because Knuth has some things to say about font rendering.
42 |
43 | That being said, one could make the case that the Ruby/Angular MVC pattern is now the default MVC pattern for web apps. And that the HTML/CSS/JS approach is more of a Model-Presentation-Control pattern (MPC), as per the OSI 7 Layer model. At which point we can split hairs about naming conventions and terminology.
44 |
45 | Getting back to Meteor, the reason this is worth discussing is that Meteor has made the rather huge architectural decision to have both the client **and** the server written in the same language. Principle 1: Pure Javascript. It's huge. It's elegant. It's an oasis of sanity. It makes a person unbelievably more productive.
46 |
47 | Yet, despite all those good things, it requires mashing these two different domains together - server side development and client-side development. Isomorphic javascript requires that the Meteor community reconciles the server-side MVC patterns used by the Rubyists, Node.js folks, and Angular folks, with the client-side thick-client MVC patterns used by WinForm, .NET, Unity, and Flash developers.
48 |
49 | This is a discussion that had yet to begin in earnest. Right now, it's a bit of a wild-west, with people exploring different patterns and designs. CoffeeScript vs JavaScript. Client-Side MVC vs Server-Side MVC.
50 |
51 | Meteor-Cookbook tends towards a Client-Side MVC approach. It's opinionated. And there's a lot of reason for it. Color coding. Clarity of code. Domain specific languages. Domain specific tools. But it's not the only approach to MVC patterns.
52 |
53 | So, yeah... just be aware of all that as you use this cookbook.
54 |
55 | #### Miscellaneous Notes & Links
56 |
57 | Some extra discussion on MVC vs PAC patterns...
58 | http://www.garfieldtech.com/blog/mvc-vs-pac
59 |
--------------------------------------------------------------------------------
/The Refactoring Process.md:
--------------------------------------------------------------------------------
1 | ## Refactoring Process
2 | The following is a brief outline of the process of refactoring. If you're an experienced programmer, this will be second-nature to you already. If you're only recently finding yourself writting larger programs that need refactoring, I hope this little reference gives you an overview of what refactoring feels like.
3 |
4 |
5 | #### A) meteor create helloWorld
6 | Create your app by running ``meteor create helloWorld`` at the command prompt.
7 | ````
8 | helloWorld/
9 | helloWorld.html
10 | helloWorld.css
11 | helloWorld.js
12 | ````
13 |
14 |
15 | #### B) Refactor to Server/Client
16 | Add server/client functionality, by create a ``/client`` and ``/server`` directory, and moving the contents of ``Meteor.isClient()`` into the ``/client`` directory, and the contents of ``Meteor.isServer()`` into the ``/server`` directory.
17 | ````
18 | helloWorld/
19 | client/
20 | helloWorld.js
21 | helloWorld.html
22 | helloWorld.css
23 | server/
24 | methods.js
25 | ````
26 |
27 | #### C) Separate our Model, View, and Controller into separate folders
28 | This step is optional, but as your app is growing, it's likely that at some point you're going to need to define your Models, Views, and Controllers. And unless you're very experienced, have done many wireframes, and have a very clear idea of what you want your app to do, it's likely that it's not going to be exactly clear how to divide up code responsibility into different files and modules.
29 |
30 | Now then, there's lots of approaches to doing MVC, but it's important to mention that there are two common patterns you should be aware of: server-side MVC, and client-side MVC.
31 |
32 | ````js
33 | // server-side MVC pattern, was popularized by frameworks like Ruby, Angular, and Ember
34 | helloWorld/ // the encapsulating folder is considered the View
35 | helloWorld.html // the HTML is consdered the Model/View
36 | helloWorld.js // the Javascript is the Model/Controller
37 | // helloWorld.css // the CSS is generlaly ignored as 'just styling'
38 |
39 | // client-side MVC pattern was popularized by traditional desktop apps, and is similar to .Net and Flash
40 | helloWorld/ // the encapsulating folder is considered the Scene or Workflow Component
41 | helloWorld.html // the HTML is the Model
42 | helloWorld.js // the Javascript is the Controller
43 | helloWorld.css // the CSS is the View
44 |
45 | ````
46 |
47 | In my experience, I find that at this early stage, I often don't know how I want to organize my code, so it's easiest to group things according to file type.
48 |
49 | ````
50 | helloWorld/
51 | client/
52 | html/
53 | helloWorld.html
54 | js
55 | helloWorld.js
56 | css
57 | helloWorld.css
58 | server/
59 | methods.js
60 | ````
61 | And usually, I go a step further, and rename the directories to Model, View, Controller, using a client-side MVC pattern.
62 |
63 | ````
64 | helloWorld/
65 | client/
66 | model/
67 | helloWorld.html
68 | controller
69 | helloWorld.js
70 | view
71 | helloWorld.css
72 | server/
73 | methods.js
74 | ````
75 |
76 | #### D) Add new Widgets and Gizmos
77 | At some point, new libraries and files are added to the project. Until some clear workflow or scenes are established, it's often helpful to simply group by file types.
78 |
79 | ````
80 | helloWorld/
81 | client/
82 | model/
83 | helloWorld.html
84 | coolWidget.html
85 | niftyGizmo.html
86 | controller
87 | helloWorld.js
88 | coolWidget.js
89 | niftyGizmo.js
90 | view
91 | helloWorld.css
92 | coolWidget.css
93 | niftyGizmo.css
94 | server/
95 | methods.js
96 | ````
97 |
98 | #### E) Reorganize According to Workflow or Features
99 | At some point, you'll find that a scene or piece of workflow is coming together well, and you'll want to extract it and modularize it. A ``workflows`` directory that coincides with the ``packages`` directory is useful to have around. In the following example, we've refactored the ``coolWidget`` files into their own directory.
100 | ````
101 | helloWorld/
102 | client/
103 | model/
104 | helloWorld.html
105 | niftyGizmo.html
106 | controller/
107 | helloWorld.js
108 | niftyGizmo.js
109 | view/
110 | helloWorld.css
111 | niftyGizmo.css
112 | workflows/
113 | coolWidget/
114 | coolWidget.html
115 | coolWidget.js
116 | coolWidget.css
117 | packages/
118 | server/
119 | methods.js
120 | ````
121 |
122 | This can continue until everything has been refactored.
123 | ````
124 | helloWorld/
125 | client/
126 | model/
127 | controller/
128 | view/
129 | workflows/
130 | helloWorld/
131 | helloWorld.html
132 | helloWorld.js
133 | helloWorld.css
134 | coolWidget/
135 | coolWidget.html
136 | coolWidget.js
137 | coolWidget.css
138 | niftyGizmo/
139 | niftyGizmo.html
140 | niftyGizmo.js
141 | niftyGizmo.css
142 | packages/
143 | server/
144 | methods.js
145 | ````
146 |
147 | #### F) Extract and Modularize a Feature
148 | The next step, of course, is to extract a workflow scene or widget into a package. This simply involves moving files between folders.
149 | ````
150 | helloWorld/
151 | client/
152 | helloWorld/
153 | helloWorld.html
154 | helloWorld.js
155 | helloWorld.css
156 | niftyGizmo/
157 | niftyGizmo.html
158 | niftyGizmo.css
159 | niftyGizmo.js
160 | packages/
161 | coolWidget/
162 | coolWidget.html
163 | coolWidget.js
164 | coolWidget.css
165 | server/
166 | methods.js
167 | ````
168 |
169 | #### G) Prepare it for Publications
170 | And then adding the necessary ``package.js`` and ``smart.json`` files to publish it.
171 | ````
172 | helloWorld/
173 | client/
174 | helloWorld/
175 | helloWorld.html
176 | helloWorld.js
177 | helloWorld.css
178 | niftyGizmo/
179 | niftyGizmo.html
180 | niftyGizmo.css
181 | niftyGizmo.js
182 | packages/
183 | coolWidget/
184 | coolWidget.html
185 | coolWidget.js
186 | coolWidget.css
187 | package.js
188 | smart.json
189 | server/
190 | methods.js
191 | ````
192 |
193 | #### H) Publish the Feature
194 | At which point, a unit of functionality has been modularized and refactored out of our application into it's own package. Notice how the basic MVC structure of the package mirrors the structure of the Meteor app after we ran ``meteor create helloWorld``.
195 | ````
196 | coolWidget/
197 | coolWidget.html
198 | coolWidget.js
199 | coolWidget.css
200 | package.js
201 | smart.json
202 | ````
203 |
204 |
205 | #### I) Code is Now Cleaner and More Modular
206 | And when we go back to our app, our overall code is cleaner and more concise, and easy to maintain and reason about.
207 | ````
208 | helloWorld/
209 | client/
210 | helloWorld/
211 | helloWorld.html
212 | helloWorld.js
213 | helloWorld.css
214 | niftyGizmo/
215 | niftyGizmo.html
216 | niftyGizmo.css
217 | niftyGizmo.js
218 | packages/
219 | coolWidget/
220 | server/
221 | methods.js
222 | ````
223 |
224 |
--------------------------------------------------------------------------------
/OSI Model Data Layer.md:
--------------------------------------------------------------------------------
1 | ------------------------------------------------------------------
2 | ## DATABASES
3 |
4 | **Q: Does Meteor support SQL?**
5 | No.
6 |
7 | **Q: When will Meteor support SQL?**
8 | Hopefully not any time soon, even though it's on the roadmap. It's a mistake for Meteor to natively support SQL.
9 |
10 | **Q: Why is that? Why doesn't Meteor support SQL, the most common database on the internet?**
11 | The problem with introducing other databases, such as SQL and such, are the database management layers between the database and serving up the javascript objects ready to be used. Other than trivial single-table database examples, supporting SQL will require an ORM to map tables together during JOINS and to produce the necessary javascript objects for the templates. Which sort of completely defeats the purpose of using Mongo in the first place. Nobody on the core Dev team wants those headaches of supporting an SQL/ORM layer, and it breaks the philosophy of javascript-everywhere. But don't take my word for it. Here are some nice articles on ORMs and the perception that they are the 'Vietnam War' of computer science. Meteor is specifically architected to avoid ORM headaches.
12 |
13 | http://www.codinghorror.com/blog/2006/06/object-relational-mapping-is-the-vietnam-of-computer-science.html
14 | http://blogs.tedneward.com/PermaLink,guid,33e0e84c-1a82-4362-bb15-eb18a1a1d91f.aspx
15 | http://nedbatchelder.com/blog/200606/the_vietnam_of_computer_science.html
16 |
17 | **Q: Well, how am I suppose to use the data in my SQL database then?**
18 | Through REST interfaces. We put the ORM __outside__ of Meteor, as part of the interface. So, the trick is to move your data from your SQL database into Meteor's Mongo database, and have Mongo act as an object store.
19 |
20 | http://stackoverflow.com/questions/10452431/how-do-you-make-a-rest-api-and-upload-files-in-meteor/13871399#13871399
21 | http://coenraets.org/blog/2012/10/creating-a-rest-api-using-node-js-express-and-mongodb/
22 | https://groups.google.com/forum/#!searchin/meteor-talk/Re$3A$20Using$20meteor$20as$20JSON$20sink/meteor-talk/M7h-GbKNS88/9v1WxlwtL2kJ
23 |
24 | Populating the underlying Mongo collections via REST calls is pretty straight forward, and uses Meteor to it's fullest potential. Between different projects, I've verified using REST to insert and update documents into Mongo collections, and then Meteor to reactively update to underlying inserts and changes into the database. Dror is right that the publication hooks are important to take care of. Not difficult for simple new documents inserted into collections; but requires a bit more finess when updating fields of existing documents.
25 |
26 | http://docs.mongodb.org/ecosystem/tools/http-interfaces/
27 | http://stackoverflow.com/questions/7386740/does-mongodb-has-a-native-rest-interface
28 | http://coenraets.org/blog/2012/10/creating-a-rest-api-using-node-js-express-and-mongodb/
29 |
30 | The reactive templates use a number of features that have to be addressed before alternate databases can be supported, the most important being native javascript objects in the data model. Essentially, Mongo isn't just a 'document oriented database', it's also an object-oriented database, able to persistently store arbitrarily large javascript objects. The reactive templates are wired up so as to use those javascript objects as-is, without any translation or modification. This makes Meteor easy to program, very fast, very robust, and a data model to die for.
31 |
32 | **Q: Okay, you got a plan. How do I get started with translating SQL syntax into Mongo syntax?**
33 | Start with the following links. They'll get you up to speed quickly.
34 |
35 | http://www.querymongo.com/
36 | http://docs.mongodb.org/manual/reference/sql-comparison/
37 | http://rickosborne.org/download/SQL-to-MongoDB.pdf
38 |
39 | **Q: Does Meteor support graph databases (Titan, Neo4J, etc)?**
40 | Nope. It's basically the same issue as supporting SQL databases. There would need to be some type of ORM mapping layer, which would totally gum up the works.
41 |
42 | **Q: When will see support for SQL, Postgress, CouchDB, Redis, etc?**
43 | Of the different databases you mention, CouchDB would probably be the easiest to add full native support for; followed by Redis (which I'm looking forward to seeing support for). Postgres has the same general problems of needing an ORM that other flavors of SQL have to deal with. And, as mentioned above, not only does it introduce an extra layer of ORM, it introduces an entire extra language to support... SQL. One of the entire philosophical goals behind Meteor is to have a single language across client, server, and database. Mongo's interface is written in Javascript. Which streamlines and simplifies development. SQL not so much.
44 |
45 |
46 | **Q: Are there any recommended admin interfaces for MongoDB?**
47 | For internal development use, you may get some milage out of Genghis, even though it's written in Ruby:
48 | http://genghisapp.com/
49 |
50 | You can also use the mongo command to connect to a remote instance on the meteor.com domain.
51 | ````
52 | meteor mongo --url YOURSITE.meteor.com
53 | ````
54 |
55 | But for scalable production use, get yourself to MongoHQ.
56 | http://www.mongohq.com/
57 |
58 | Also, the Mongo Monitoring Service, from 10Gen, the makers of Mongo:
59 | https://mms.10gen.com/user/login
60 |
61 |
62 | **Q: How do you import data into the Mongo database?**
63 |
64 | ````js
65 | // download mongodb from 10gen, and start a stand-along instance
66 | mongod
67 |
68 | // import the json data into a staging database
69 | // jsonArray is a useful command, particularly if you're migrating from SQL
70 | mongoimport -d staging -c assets < data.json --jsonArray
71 |
72 | // navigate to your application
73 | cd myappdir
74 |
75 | // run meteor and initiate it's database
76 | meteor
77 |
78 | // connect to the meteor mongodb
79 | meteor mongo --port 3002
80 |
81 | // copy collections from staging database into meteor database
82 | db.copyDatabase('staging', 'meteor', 'localhost');
83 |
84 | // shut down the staging database
85 | Ctrl-C
86 | ````
87 |
88 | **Q: Where does a Meteor app store its mongodb log files?**
89 | They're not easily accessible. If you run the 'meteor bundle' command, you can generate a tar.gz file, and then run your app manually. Doing that, you should be able to access the mongo logs... probably in the .meteor/db directory.
90 |
91 | If you really need to access mongodb log files, set up a regular mongodb instance, and then connect Meteor to an external mongo instance, by setting the MONGO_URL environment variable:
92 | ````
93 | MONGO_URL='mongodb://user:password@host:port/databasename'
94 | ````
95 |
96 | Once that's done, you should be able to access logs in the usual places...
97 | ````
98 | /var/log/mongodb/server1.log
99 | ````
100 |
101 | Also, people have been mentioning the following MONGO_URL parameters as being useful...
102 | ````js
103 | ?autoReconnect=true
104 | ?replicaSet=meteor
105 | ````
106 |
107 |
108 |
109 | **Q: How do I create a JOIN in Meteor?**
110 | Timeout. You're still thinking in terms of normalizing data, not repeating yourself, and creating a collection for each data table. This is bad juju magic, and will cause bad application design. Take a timeout and do some more research and reading before moving forward with your application.
111 |
112 | **Q: I have a pre-existing SQL database, and simply must have an ORM**
113 | Well, you might want to check out Sails.js. It looks like a very promising framework that has an ORM and is database agnostic.
114 | http://sailsjs.org/#!
115 |
116 |
--------------------------------------------------------------------------------
/_book/gitbook/jsrepl/sandbox.js:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions
8 | are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright
11 | notice, this list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright
14 | notice, this list of conditions and the following disclaimer in the
15 | documentation and/or other materials provided with the distribution.
16 |
17 | 3. The names of its contributors may not be used to endorse or promote
18 | products derived from this software without specific prior written
19 | permission.
20 |
21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 |
33 | Any feedback is very welcome.
34 | http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
35 | email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
36 | */
37 | (function(c){try{c.window=c.window||c}catch(b){}try{c.self=c.self||c}catch(e){}var a;c.addEventListener("message",function(d){for(var d=JSON.parse(d.data),b=a,c=d.type.split("."),e=0;ethis.OUT_EVERY_MS&&(clearTimeout(this.outTimeout),this.flush())},flush:function(){if(this.output_buffer.length)this.post({type:"output",data:this.output_buffer.join("")}),this.outTimeout=0,this.output_buffer=[]},err:function(a){a={type:"error",
41 | data:a.toString()};this.flush();this.post(a)},input:function(a){this.input.write=a;this.flush();this.post({type:"input"})},result:function(a){a={type:"result",data:a};this.flush();this.post(a)},ready:function(){this.post({type:"ready"})},getNextLineIndent:function(a){this.post({type:"indent",data:this.engine.GetNextLineIndent(a)})},progress:function(a){this.post({type:"progress",data:a})},dbInput:function(){this.flush();this.post({type:"db_input"})},serverInput:function(){this.flush();this.post({type:"server_input"})},
42 | bindAll:function(a){for(var b in a)(function(b){var c=a[b];typeof c=="function"&&(a[b]=function(){var b=[].slice.call(arguments);return c.apply(a,b)})})(b)},hide:function(a){try{Object.defineProperty(c,a,{writable:false,enumerable:false,configurable:false,value:c[a]})}catch(b){}},set_input_server:function(a){this.input_server={url:(a.url||"/emscripten/input/")+a.input_id,cors:a.cors||false}}};a.bindAll(a);c.Sandboss=a;a.hide("Sandboss");if(self.openDatabaseSync){var f=self.openDatabaseSync("replit_input",
43 | "1.0","Emscripted input",1024);self.prompt=function(){a.dbInput();var b=null;f.transaction(function(a){b=a});for(var c;!(c=b.executeSql("SELECT * FROM input").rows).length;)for(c=0;c<1E8;c++);b.executeSql("DELETE FROM input");return c.item(0).text};a.hide("prompt")}else if(!a.isFrame)self.prompt=function(){a.serverInput();var b;b=a.input_server.url;var c=new XMLHttpRequest;if(a.input_server.cors)if("withCredentials"in c)c.open("GET",b,false);else if(typeof XDomainRequest!="undefined")c=new XDomainRequest,
44 | c.open("GET",b);else throw Error("Your browser doesn' support CORS");else c.open("GET",b,false);b=c;b.send(null);return b.status===200?b.responseText:"ERROR: ON NON-WEBKIT BROWSERS CONNECTION TO THE SERVER IS NEEDED FOR INPUT"}})(this);
45 | (function(){var c=function(b){b==void 0&&(b=Date.now());this.N=624;this.M=397;this.MATRIX_A=2567483615;this.UPPER_MASK=2147483648;this.LOWER_MASK=2147483647;this.mt=Array(this.N);this.mti=this.N+1;this.init_genrand(b)};c.prototype.init_genrand=function(b){this.mt[0]=b>>>0;for(this.mti=1;this.mti>>30,this.mt[this.mti]=(((b&4294901760)>>>16)*1812433253<<16)+(b&65535)*1812433253+this.mti,this.mt[this.mti]>>>=0};c.prototype.init_by_array=function(b,
46 | c){var a,f,d;this.init_genrand(19650218);a=1;f=0;for(d=this.N>c?this.N:c;d;d--){var h=this.mt[a-1]^this.mt[a-1]>>>30;this.mt[a]=(this.mt[a]^(((h&4294901760)>>>16)*1664525<<16)+(h&65535)*1664525)+b[f]+f;this.mt[a]>>>=0;a++;f++;a>=this.N&&(this.mt[0]=this.mt[this.N-1],a=1);f>=c&&(f=0)}for(d=this.N-1;d;d--)h=this.mt[a-1]^this.mt[a-1]>>>30,this.mt[a]=(this.mt[a]^(((h&4294901760)>>>16)*1566083941<<16)+(h&65535)*1566083941)-a,this.mt[a]>>>=0,a++,a>=this.N&&(this.mt[0]=this.mt[this.N-1],a=1);this.mt[0]=
47 | 2147483648};c.prototype.genrand_int32=function(){var b,c=[0,this.MATRIX_A];if(this.mti>=this.N){var a;this.mti==this.N+1&&this.init_genrand(5489);for(a=0;a>>1^c[b&1];for(;a>>1^c[b&1];b=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK;this.mt[this.N-1]=this.mt[this.M-1]^
48 | b>>>1^c[b&1];this.mti=0}b=this.mt[this.mti++];b^=b>>>11;b^=b<<7&2636928640;b^=b<<15&4022730752;b^=b>>>18;return b>>>0};c.prototype.genrand_int31=function(){return this.genrand_int32()>>>1};c.prototype.genrand_real1=function(){return this.genrand_int32()*(1/4294967295)};c.prototype.random=function(){return this.genrand_int32()*(1/4294967296)};c.prototype.genrand_real3=function(){return(this.genrand_int32()+0.5)*(1/4294967296)};c.prototype.genrand_res53=function(){var b=this.genrand_int32()>>>5,c=this.genrand_int32()>>>
49 | 6;return(b*67108864+c)*1.1102230246251565E-16};(function(){Math._random=Math.random;var b=new c(42);Math.random=function(){return b.random()};Math.seed=function(e){b=new c(e)}})()})();if(!Date.now)Date.now=function(){return+new Date};if(!Object.keys)Object.keys=function(c){if(c!==Object(c))throw new TypeError("Object.keys called on non-object");var b=[],e;for(e in c)Object.prototype.hasOwnProperty.call(c,e)&&b.push(e);return b};if(!Object.getOwnPropertyNames)Object.getOwnPropertyNames=Object.keys;
50 | if(!Object.create)Object.create=function(c){function b(){}b.prototype=c;return new b};if(!Array.isArray)Array.isArray=function(c){return{}.toString.call(c)=="[object Array]"};
51 | if(!Function.prototype.bind)Function.prototype.bind=function(c){if(typeof this!=="function")throw new TypeError("Function.prototype.bind - what is trying to be fBound is not callable");var b=Array.prototype.slice.call(arguments,1),e=this,a=function(){},f=function(){try{return e.apply(this instanceof a?this:c||window,b.concat(Array.prototype.slice.call(arguments)))}catch(d){return e.apply(c||window,b.concat(Array.prototype.slice.call(arguments)))}};a.prototype=this.prototype;f.prototype=new a;return f};
52 | if(!Object.freeze)Object.freeze=function(c){return c.___frozen___=true};if(!Object.isFrozen)Object.isFrozen=function(c){return Boolean(c.___frozen___)};
53 |
--------------------------------------------------------------------------------
/WebStorm IDE.md:
--------------------------------------------------------------------------------
1 | ## WebStorm IDE
2 |
3 |
4 |
5 | ### Links, Installation
6 | Recommend version of WebStorm is currently 7.0.
7 | http://www.jetbrains.com/webstorm/
8 | http://www.jetbrains.com/webstorm/download/download_thanks.jsp
9 |
10 |
11 | ### Download the Settings.jar File
12 | There's now a pre-compiled settings file which you can download and import directly into WebStorm, rather than following all the instructions in this document. It may be slightly out of date vs. this document, though.
13 | https://github.com/awatson1978/webstorm-settings
14 |
15 | ### Implementing Meteor Styleguide
16 | https://github.com/meteor/meteor/wiki/Meteor-Style-Guide
17 |
18 |
19 | ### MVC Color Coding
20 | Run ``meteor add less`` at the command line to include the LESS precompiler. Then use ``.less`` files instead of ``.css`` files. Presto. Your application should color code Model (Green), View (Blue), and Controller (Red) files.
21 |
22 |
23 |
24 | ### Settings > Code Style > Javascript
25 | As per the Meteor style guide.
26 | https://github.com/meteor/meteor/wiki/Meteor-Style-Guide
27 |
28 | ````
29 | // Tabs and Indents
30 | Tab Size: 2
31 | Indent: 2
32 | Continuation indent: 2
33 |
34 | // Spaces (select all options **except** the following)
35 | Unary operators
36 | Function call parentheses
37 | Function declaration parentheses
38 | 'if' parentheses
39 | 'for' parentheses
40 | 'while' parantheses
41 | 'switch' parantheses
42 | 'catch' parantheses
43 |
44 | ````
45 |
46 | ### Settings > Directories > Excluded
47 |
48 | You want to exclude the ``.meteor`` file so that the Meteor build process doesn't crash your IDE. This applies to most any IDE you use, and isn't specific to WebStorm.
49 | ````
50 | .idea
51 | .meteor
52 | ````
53 |
54 |
55 | ### Settings > File and Code Templates
56 |
57 | I find it very convenient to create a Less file template, using some default media styles to help with responsive mobile application design.
58 |
59 | **Meteor - Mobile View**
60 | ````css
61 | #guestPage{
62 | .foo{
63 | background-color: red;
64 | }
65 | .foo:hover{
66 | text-decoration: underlined;
67 | }
68 |
69 | }
70 |
71 | // landscape orientation
72 | @media only screen and (min-width: 768px) {
73 | #guestPage{
74 | .foo{
75 | background-color: blue;
76 | }
77 | }
78 | }
79 |
80 | // portrait orientation
81 | @media only screen and (max-width: 768px) {
82 | #guestPage{
83 | .foo{
84 | background-color: blue;
85 | }
86 | }
87 | }
88 | @media only screen and (max-width: 480px) {
89 | #guestPage{
90 | .foo{
91 | background-color: blue;
92 | }
93 | }
94 | }
95 | ````
96 |
97 |
98 | **Meteor - Basic Page Model**
99 | ````html
100 |
101 |
106 |
107 | ````
108 |
109 | **Meteor - List Page Controller**
110 | ````js
111 | Template.fooPage.events({
112 | 'click .btn':function(){
113 | console.count('click .btn);
114 | alert('click .btn!);
115 | }
116 | })
117 | Template.fooList.fooList = function(){
118 | return Foo.find();
119 | }
120 | ````
121 |
122 | **Meteor - List Page Model**
123 | ````html
124 |
125 |
126 |
127 |
128 | {{each fooList}}
129 | {{> fooListItem }}
130 | {{/each}}
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 | {{_id}}
140 |
141 |
142 |
143 | ````
144 |
145 | ### Settings > General
146 | "Save files on frame deactivation" and "Save files automatically" - you want this turned **off**. It conflicts with Meteor's build process, and basically duplicates functionality found in Meteor. Bundling and live editing will basically conflict with each other.
147 |
148 | In older versions, thse could be found under Preferences > Live Edit.
149 |
150 | ### Settings > Editor > Editor Tabs
151 | Enable "Mark modified tabs with asterisk"
152 |
153 |
154 | ### Settings > Javascript > Code Quality Tools > JSLint
155 |
156 | ````
157 | + Enable
158 | + Tolerate TODO comments
159 | Indentation 2
160 | ````
161 |
162 | If [JSLint is too annoyingly strict](http://stackoverflow.com/questions/6803305/should-i-use-jslint-or-jshint-javascript-validation), enable JSHint instead.
163 |
164 |
165 | ### Settings > Javascript > Node.js
166 | ````
167 | chai
168 | demeteorizer
169 | fs-tools
170 | istanbul
171 | laika
172 | meteorite
173 | mocha
174 | phantomjs
175 | selenium-webdriver
176 | ````
177 |
178 |
179 | ### Settings > Version Control > Github
180 |
181 | ````
182 | Host: github.com
183 | Login: yourusername
184 | Password: yourpassword
185 | ````
186 |
187 |
188 | ### Settings > Editor
189 | Editor preferences are going to vary wildly, particularly if you're accustomed to old school editors like Vim or Emacs. However, if you'd like WebStorm to behave like a typical text editor, I'd recommend setting the following items. In particular, allow placement of the caret after the end of line can be particularly confusing and frustrating.
190 | ````
191 | - Honor 'CamelHumps'
192 | + Zoom with Cmd + Mousewheel
193 | + Use soft wraps in editor
194 | - Allow placement of caret after end of line
195 | + Allowplacement of caret inside of tabs
196 | ````
197 |
198 | ### Preferences > Editor > Appearance
199 | Showing line numbers is obviously a personal preference, but it helps immeasurably in debugging stack traces. If you're not using line numbers, you're very likely either a n00b or a guru. Ask yourself if you're a n00b, a guru, or an intermediate programmer, and set accordingly.
200 | ````
201 | + Show line numbers
202 | ````
203 |
204 | ### Settings > Editor > Color & Fonts > Javascript
205 | Another personal preference, but if you're into reducing eye strain, coding in low-light levels, anord saving energy, try changing to ``Darcula``.
206 |
207 |
208 |
209 | ### Settings > Live Templates
210 |
211 | try/catch block
212 | ````js
213 | try{
214 | $SELECTION$
215 | }catch(error){
216 | console.log(error);
217 | }
218 | $END$
219 | ````
220 |
221 | self.once
222 | ````js
223 | self = this;
224 | if(! self.once) {
225 | $SELECTED$
226 | $END$
227 | }
228 | self.once = true;
229 | ````
230 |
231 | if/else block
232 | ````js
233 | if($END$){
234 | $SELECTION$
235 | }else{
236 |
237 | }
238 | ````
239 |
240 | console.group
241 | ````js
242 | console.group('$END$');
243 | $SELECTION$
244 | console.endGroup();
245 | ````
246 |
247 |
248 |
249 | bootstrap panel - basic
250 | ````js
251 |
252 |
253 | $END$
254 |
255 | $SELECTION$
256 |
257 | ````
258 |
259 |
260 | bootstrap panel - complete
261 | ````js
262 |
263 |
264 | $END$
265 |
266 | $SELECTION$
267 |
269 |
270 | ````
271 |
272 | bootstrap panel - minimal
273 | ````js
274 |
275 | $SELECTION$
276 |
277 | $END$
278 | ````
279 |
280 | new page template
281 | ````js
282 |
283 |
284 | $SELECTION$
285 |
286 |
287 | ````
288 |
289 |
290 |
291 | ### Settings > Plugins
292 |
293 | If you can't find plugins via the Settings -> Plugins -> Browse Repositories dialog, you can go to http://plugins.jetbrains.com, find the desired plugin, download it, then unpack the .zip into WebStorm's `plugins` directory.
294 |
295 | Some useful plugins:
296 |
297 | * [Mongo Plugin](https://github.com/dboissier/mongo4idea)
298 | * [Unicode Browser](http://plugins.jetbrains.com/plugin/6186)
299 | * [Code History Mining](http://plugins.jetbrains.com/plugin/7273)
300 | * [Dummy Text Generator](http://plugins.jetbrains.com/plugin/7216)
301 | * [CodeGlance](http://plugins.jetbrains.com/plugin/7275) - minimap similar to the one in Sublime
302 | * [Code Outline 2](http://plugins.jetbrains.com/plugin/6274)
303 | * [Handlebars/Mustache](http://plugins.jetbrains.com/plugin/6884)
304 | * [CamelCase](http://plugins.jetbrains.com/plugin/7160)
305 | * [Git Flow Integration](http://plugins.jetbrains.com/plugin/7315)
306 | * [SyncEdit 2](http://plugins.jetbrains.com/plugin/7147) - expanded word refactoring
307 |
308 | Some plugins enabled by default that don't apply to meteor development and you can disable to improve performance:
309 |
310 | * Database Support (doesn't support MongDB; use the [Mongo Plugin](https://github.com/dboissier/mongo4idea) instead)
311 | * ASP
312 | * CVS
313 | * Drupal
314 | * Framework MVC Structure
315 | * Google App Engine Support for PHP
316 | * hg4idea
317 | * Java Server Pages
318 | * PHP
319 | * SQL support
320 | * Subversion Integration
321 | * YAML
322 |
323 |
324 | ### Debugging
325 |
326 | See [How to debug Meteor apps with WebStorm](http://stackoverflow.com/questions/14751080/how-can-i-debug-my-meteor-app-using-the-webstorm-ide).
327 |
--------------------------------------------------------------------------------
/_book/gitbook/jsrepl/jsrepl.js:
--------------------------------------------------------------------------------
1 | window.__BAKED_JSREPL_BUILD__ = true;
2 | (function(){var l,j,k,m,p,n,q,r,o=[].slice,i=function(h,a){return function(){return h.apply(a,arguments)}},u={}.hasOwnProperty,s=function(h,a){function c(){this.constructor=h}for(var b in a)u.call(a,b)&&(h[b]=a[b]);c.prototype=a.prototype;h.prototype=new c;h.__super__=a.prototype;return h};j=document.getElementById("jsrepl-script");if(j!=null)l=j.src.split("/").slice(0,-1).join("/"),p=""+l+"/sandbox.html";else throw Error('JSREPL script element cannot be found. Make sure you have the ID "jsrepl-script" on it.');
3 | m=function(){function h(){var a;a=function(c){return function(){c.head=document.getElementsByTagName("head")[0];return c.body=document.getElementsByTagName("body")[0]}}(this);a();this.loadfns=[a];window.onload=function(c){return function(){var b,a,d,e,g;e=c.loadfns;g=[];for(a=0,d=e.length;a-1?g.push(f.splice(b,1)):g.push(void 0)):g.push(this.listeners[b]=[]));return g};h.prototype.fire=function(a,c){var b,f,d,e,c=this.makeArray(c);
6 | f=this.listeners[a];if(f!=null){c.push(a);var g;g=[];for(d=0,e=f.length;d
2 |
3 |
4 |
5 | This is a custom SVG webfont generated by Font Squirrel.
6 | Designer : Linotype Design Studio
7 | Foundry URL : http://www.Linotype.com/
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
--------------------------------------------------------------------------------