Skip to content
The Meteor Chef edited this page Mar 2, 2015 · 16 revisions
Updated: March 2nd, 2015 (Currently Incomplete)
```

The following is designed as a reference for beginners. The goal of this reference is to showcase patterns for common features in Meteor applications. Keep in mind: **these patterns are _not_ the only way to implement these features**. Rather, these are the patterns that we've used in our own applications that we've found helpful.

1. File Structure
2. Defining Collections
3. Allow/Deny Rules
4. Publications & Subscriptions
5. Routing
   1. Global
   2. Public
   3. Authenticated
   4. Server
   5. Filters
6. Templates
7. Controllers
8. Methods
9. Configuration
10. Common Browser Policy Patterns

### 1. File Structure (In Progress, ignore for now)
While Meteor is incredibly flexible, it's important to adopt a sensible file structure in all of your projects. Below is a recommended file structure, along with a few explanations as to _why_ we find that file structure to be handy. Adopt it in your own projects and fork it to your liking!

```
/client
--- /controllers
------ /authenticated
------ /public
--- /helpers
------ helpers-ui.js
--- /includes
------ _header.html
------ _footer.html
--- /layouts
------ layout-default.html
--- /routes
------ /hooks.js
------ /routes-authenticated.js
------ /routes-public.js
--- /stylesheets
--- /views
------ /authenticated
------ /public
/collections
--- collectionName.js
/server
--- /email
------ /templates
--- /methods
------ /insert
--------- collectionName.js
------ /read
--------- collectionName.js
------ /remove
--------- collectionName.js
------ /update
--------- collectionName.js
------ /utility
--------- third-party-name.js
--- /publications
------ collectionName.js
/public
--- /images
/private
```

#### /client

The `/client` directory is used to store client-side code. This is used instead of using `Meteor.isClient` in `if` statements. Any files in this directory will be exposed to the client.

---

##### /client/controllers
Controllers are the JavaScript code that's paired with each of your templates that live in the `/client/views` directory. Ideally, controllers are further split into two directories: `authenticated` and `public`. Controllers for templates that require a logged in user are stored in the `authenticated` directory, while public-facing templates that _do not_ require a logged in user are stored in the `public` directory. **One file per template is recommended**. A controller is generally made up of a `created` callback, a `rendered` callback, template `helpers`, and an `events` map.

##### /client/helpers
Helpers are JavaScript code that help you do other things. By default, the only file in this folder is `helpers-ui.js` where we store [UI helper](https://github.com/meteor/meteor/wiki/Using-Blaze#handlebars-namespace-deprecated) definitions. It's also recommended to store client-only helper functions (e.g. a file with JavaScript functions for transforming text).

##### /client/includes
Includes are HTML templates that are meant to be _included_ globally: headers, footers, and any other templates that appear throughout the entire application. While not entirely necessary, it helps to prefix include templates with an underscore to denote their partial nature (e.g. `_header.html`).

##### /client/layouts
Layouts are HTML templates that are [meant for use with the `iron:router` package](https://github.com/EventedMind/iron-router/blob/devel/Guide.md#layouts). Layouts are templates that dictate a given structure for a single section of your application or for the entire application.

##### /client/routes
Routes are JavaScript files that define `iron:router` route's for your application. Ideally, routes are broken up into two files: `routes-authenticated.js` and `routes-public.js`. The authenticated file is meant for routes that are only accessible when a user is logged in, while the public file is meant for routes that are accessible when a user is logged out. Additionally, a third file used for controlling which routes are accessible based on various conditions can be stored in `hooks.js`. [Hooks](https://github.com/EventedMind/iron-router/blob/devel/Guide.md#hooks) are functions bound to groups of routes that can decide whether or not a route is accessible.
 
##### /client/stylesheets
##### /client/views
---
#### /server
---

### 2. Defining Collections
### 3. Allow/Deny Rules
### 4. Publications & Subscriptions
### 5. Routing
#### 5.1 Global
#### 5.2 Public
#### 5.3 Authenticated
#### 5.4 Server
#### 5.5 Filters
### 6. Templates
### 7. Controllers
### 9. Methods
### 9. Configuration
As your application grows in size, it's likely that you'll need to include certain configuration items like API keys, connection strings, and other information that's used to "configure" your application. Luckily for us, Meteor includes a simple settings API for doing exactly this. 

Accessible via the `Meteor.settings` method in your app, this function serves as an easy way to provide configuration to your Meteor app on startup. Two steps are required to get it working:

1. Create a file called `settings.json` in the root of your project. This file will contain the various configuration data for your application.
2. When starting Meteor, make sure to use the `--settings` flag, passing the location of your `settings.json` file to Meteor, e.g. `meteor --settings settings.json`. 

After your server starts up, anything that you've defined in `settings.json` will be accessible via `Meteor.settings`. By default, Meteor only exposes what you include in your `settings.json` file on the _server_. This is good because it ensures you won't expose private or sensitive information in your application accidentally. If you _do_ want to expose certain information to the client-side of your application as well (e.g. a public API token), you can do so by nesting settings that you'd like to be public in a `public: {}` object in `settings.json`.
 
Let's take a look at an example `settings.json` file, including settings for both the client _and_ server:

```
{
 "public": {
   "stripe": {
     "publicKey": "abcdefg1234567"
   }
 },
 "private": {
   "stripe": {
     "privateKey": "1234567abcedfg"
   }
 }
}
```

In this example, we've created two objects within our main `settings.json` object: `public` and `private`. Here, only the `public` object is necessary. Again, anything that's _not_ wrapped in the `public` object is automatically limited to the server. Here, we simply separate our various information into `public` and `private` objects for organization sake.

After starting our application using `meteor --settings settings.json`, we can now access the above information in our app. On the client, we can see our public configuration using `Meteor.settings.public` and on the server, we can see our private configuration using `Meteor.settings.private`. Expanding on our example, if I wanted to make use of our private key in a method, I would do something like the following:

```
// In /server/stripe.js

var config = Meteor.settings.private.stripe;
var Stripe = StripeAPI(config.privateKey);

Meteor.methods({
 chargeCard: function(token){
   Stripe.charges.create({
    amount: 400,
    currency: "usd",
    card: token,
    description: "Charge for test@example.com"
   }, function(err, charge) {
    // Handle errors and success state here.
   });
 }
});
```

#### How do I use settings.json in production?
Getting access to `settings.json` in production is done by setting an environment variable called `METEOR_SETTINGS`. If you're using Modulus, you can run the command `modulus env set METEOR_SETTINGS "$(cat settings.json)"` in order to set the `METEOR_SETTINGS` environment variable in your Modulus app.

### 10. Common Browser Policy Patterns
If you keep the `browser-policy` package installed that comes with Base, you'll need to configure a few rules depending on the type of content you have in your application. Because most rules apply to _third-party_ content, we've provided the following list for common settings. **Note**: these are _extremely_ generic and only apply to the _root_ domains for each service. You may need to configure these further, but this should be a helpful start!

```
// Typekit
BrowserPolicy.content.allowOriginForAll('use.typekit.net');
BrowserPolicy.content.allowOriginForAll('p.typekit.net');
BrowserPolicy.content.allowFontDataUrl('use.typekit.net');
BrowserPolicy.content.allowFontDataUrl('p.typekit.net');

// Font Awesome
BrowserPolicy.content.allowOriginForAll('maxcdn.bootstrapcdn.com');

// Stripe
BrowserPolicy.content.allowOriginForAll('*.stripe.com');
BrowserPolicy.framing.restrictToOrigin('checkout.stripe.com');

// Mapbox
BrowserPolicy.content.allowOriginForAll('*.mapbox.com');

// Amazon S3
BrowserPolicy.content.allowOriginForAll('s3.amazonaws.com');
```
Clone this wiki locally