diff --git a/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.ts b/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.ts
new file mode 100644
index 0000000000..2bd56c6930
--- /dev/null
+++ b/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.ts
@@ -0,0 +1,37 @@
+// #docregion
+import { Component } from '@angular/core';
+
+///////// Using Absolute Paths ///////
+
+// #docregion absolute-config
+@Component({
+ selector: 'absolute-path',
+ templateUrl: 'app/some.component.html',
+ styleUrls: ['app/some.component.css']
+})
+// #enddocregion absolute-config
+export class SomeAbsoluteComponent {
+ class = 'absolute';
+ type = 'Absolute template & style URLs';
+ path = 'app/path.component.html';
+}
+
+///////// Using Relative Paths ///////
+
+// #docregion relative-config
+@Component({
+ // #docregion module-id
+ moduleId: module.id,
+ // #enddocregion module-id
+ selector: 'relative-path',
+ templateUrl: 'some.component.html',
+ styleUrls: ['some.component.css']
+})
+// #enddocregion relative-config
+
+export class SomeRelativeComponent {
+ class = 'relative';
+ type = 'Component-relative template & style URLs';
+ path = 'path.component.html';
+
+}
diff --git a/public/docs/_examples/cb-component-relative-paths/ts/example-config.json b/public/docs/_examples/cb-component-relative-paths/ts/example-config.json
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/public/docs/_examples/cb-component-relative-paths/ts/index.html b/public/docs/_examples/cb-component-relative-paths/ts/index.html
new file mode 100644
index 0000000000..cc0d972df2
--- /dev/null
+++ b/public/docs/_examples/cb-component-relative-paths/ts/index.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+ Component-Relative Paths
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Loading app...
+
+
diff --git a/public/docs/_examples/cb-component-relative-paths/ts/plnkr.json b/public/docs/_examples/cb-component-relative-paths/ts/plnkr.json
new file mode 100644
index 0000000000..a4c33bbde3
--- /dev/null
+++ b/public/docs/_examples/cb-component-relative-paths/ts/plnkr.json
@@ -0,0 +1,8 @@
+{
+ "description": "Module-relative Paths",
+ "files": [
+ "!**/*.d.ts",
+ "!**/*.js"
+ ],
+ "tags": [ "cookbook" ]
+}
diff --git a/public/docs/dart/latest/cookbook/_data.json b/public/docs/dart/latest/cookbook/_data.json
index 2c28e02169..9b2545ec5e 100644
--- a/public/docs/dart/latest/cookbook/_data.json
+++ b/public/docs/dart/latest/cookbook/_data.json
@@ -17,6 +17,12 @@
"intro": "Share information between different directives and components"
},
+ "component-relative-paths": {
+ "title": "Component-relative Paths",
+ "intro": "Use relative URLs for component templates and styles.",
+ "hide": true
+ },
+
"dependency-injection": {
"title": "Dependency Injection",
"intro": "Techniques for Dependency Injection",
diff --git a/public/docs/dart/latest/cookbook/component-relative-paths.jade b/public/docs/dart/latest/cookbook/component-relative-paths.jade
new file mode 100644
index 0000000000..6778b6af28
--- /dev/null
+++ b/public/docs/dart/latest/cookbook/component-relative-paths.jade
@@ -0,0 +1 @@
+!= partial("../../../_includes/_ts-temp")
diff --git a/public/docs/js/latest/cookbook/_data.json b/public/docs/js/latest/cookbook/_data.json
index f4f89de38c..2d9ada59f1 100644
--- a/public/docs/js/latest/cookbook/_data.json
+++ b/public/docs/js/latest/cookbook/_data.json
@@ -16,6 +16,11 @@
"intro": "Share information between different directives and components"
},
+ "component-relative-paths": {
+ "title": "Component-relative Paths",
+ "intro": "Use relative URLs for component templates and styles."
+ },
+
"dependency-injection": {
"title": "Dependency Injection",
"intro": "Techniques for Dependency Injection"
diff --git a/public/docs/js/latest/cookbook/component-relative-paths.jade b/public/docs/js/latest/cookbook/component-relative-paths.jade
new file mode 100644
index 0000000000..6778b6af28
--- /dev/null
+++ b/public/docs/js/latest/cookbook/component-relative-paths.jade
@@ -0,0 +1 @@
+!= partial("../../../_includes/_ts-temp")
diff --git a/public/docs/ts/latest/cookbook/_data.json b/public/docs/ts/latest/cookbook/_data.json
index 211e12bfd4..a90160de7b 100644
--- a/public/docs/ts/latest/cookbook/_data.json
+++ b/public/docs/ts/latest/cookbook/_data.json
@@ -16,6 +16,11 @@
"intro": "Share information between different directives and components"
},
+ "component-relative-paths": {
+ "title": "Component-relative Paths",
+ "intro": "Use relative URLs for component templates and styles."
+ },
+
"dependency-injection": {
"title": "Dependency Injection",
"intro": "Techniques for Dependency Injection"
diff --git a/public/docs/ts/latest/cookbook/component-relative-paths.jade b/public/docs/ts/latest/cookbook/component-relative-paths.jade
new file mode 100644
index 0000000000..6266730f92
--- /dev/null
+++ b/public/docs/ts/latest/cookbook/component-relative-paths.jade
@@ -0,0 +1,140 @@
+include ../_util-fns
+
+:marked
+ ## Write *Component-Relative* URLs to component templates and style files
+
+ Our components ofter refer to external template and style files.
+ We identify those files with a URL in the `templateUrl` and `styleUrls` properties of the `@Component` metadata
+ as seen here:
+
++makeExample('cb-component-relative-paths/ts/app/some.component.ts','absolute-config')(format='.')
+:marked
+ By default, we *must* specify the full path back to the application root.
+ We call this an ***absolute path*** because it is *absolute* with respect to the application root.
+
+ There are two problems with an *absolute path*
+
+ 1. We have to remember the full path back to the application root.
+
+ 1. We have to update the URL when we move the component around in the application files structure.
+
+ It would be much easier to write and maintain our application components if we could specify template and style locations
+ *relative* to their component class file.
+
+ *We can!*
+
+.alert.is-important
+ :marked
+ We can if we build our application as `commonjs` modules and load those modules
+ with a suitable package loader such as `systemjs` or `webpack`.
+ Learn why [below](#why-default).
+
+ The Angular 2 CLI uses these technologies and defaults to the
+ *component-relative path* approach described here.
+ CLI users can skip this chapter or read on to understand
+ how it works.
+
+.l-main-section
+:marked
+ ## _Component-Relative_ Paths
+
+ Our goal is to specify template and style URLs *relative* to their component class files,
+ hence the term ***component-relative path***.
+
+ The key to success is following a convention that puts related component files in well-known locations.
+
+ We recommend keeping component template and component-specific style files as *siblings* of their
+ companion component class files.
+ Here we see the three files for `SomeComponent` sitting next to each other in the `app` folder.
+
+.filetree
+ .file app
+ .children
+ .file some.component.css
+ .file some.component.html
+ .file some.component.ts
+ .file ...
+:marked
+ We'll have more files and folders — and greater folder depth — as our application grows.
+ We'll be fine as long as the component files travel together as the inseparable siblings they are.
+
+ ### Set the *moduleId*
+
+ Having adopted this file structure convention, we can specify locations of the template and style files
+ relative to the component class file simply by setting the `moduleId` property of the `@Component` metadata like this
++makeExample('cb-component-relative-paths/ts/app/some.component.ts','module-id')(format='.')
+:marked
+ We strip the `app/` base path from the `templateUrl` and `styleUrls`. The result looks like this:
++makeExample('cb-component-relative-paths/ts/app/some.component.ts','relative-config')(format='.')
+
+.alert.is-helpful
+ :marked
+ Webpack users may prefer [an alternative approach](#webpack) that uses `require`.
+
+.l-main-section
+:marked
+ ## Source
+
+ **We can see the [live example](/resources/live-examples/cb-component-relative-paths/ts/plnkr.html)**
+ and download the source code from there
+ or simply read the pertinent source here.
++makeTabs(
+ `cb-component-relative-paths/ts/app/some.component.ts,
+ cb-component-relative-paths/ts/app/some.component.html,
+ cb-component-relative-paths/ts/app/some.component.css,
+ cb-component-relative-paths/ts/app/app.component.ts`,
+ null,
+ `app/some.component.ts, app/some.html, app/some.component.css, app/app.component.ts`)
+
+a#why-default
+.l-main-section
+:marked
+ ## Appendix: why *component-relative* is not the default
+
+ A *component-relative* path is obviously superior to an *absolute* path.
+ Why did Angular default to the *absolute* path?
+ Why do *we* have to set the `moduleId`? Why can't Angular set it?
+
+ First, let's look at what happens if we use a relative path and omit the `moduleId`.
+
+ `EXCEPTION: Failed to load some.component.html`
+
+ Angular can't find the file so it throws an error.
+
+ Why can't Angular calculate the template and style URLs from the component file's location?
+
+ Because the location of the component can't be determined without the developer's help.
+ Angular apps can be loaded in many ways: from individual files, from SystemJS packages, or
+ from CommonJS packages, to name a few.
+ We might generate modules in any of several formats.
+ We might not be writing modular code at all!
+
+ With this diversity of packaging and module load strategies,
+ it's not possible for Angular to know with certainty where these files reside at runtime.
+
+ The only location Angular can be sure of is the URL of the `index.html` home page, the application root.
+ So by default it resolves template and style paths relative to the URL of `index.html`.
+ That's why we previously wrote our file URLs with an `app/` base path prefix.
+
+ But *if* we follow the recommended guidelines and we write modules in `commonjs` format
+ and we use a module loader that *plays nice*,
+ *then* we — the developers of the application —
+ know that the semi-global `module.id` variable is available and contains
+ the absolute URL of the component class module file.
+
+ That knowledge enables us to tell Angular where the *component* file is
+ by setting the `moduleId`:
++makeExample('cb-component-relative-paths/ts/app/some.component.ts','module-id')(format='.')
+
+a#webpack
+.l-main-section
+:marked
+ ## Webpack: load templates and styles with *require*
+ Webpack developers have an alternative to `moduleId`.
+
+ They can load templates and styles at runtime by setting the component metadata `template` and `style` properties
+ with `require` statements that reference *component-relative* URLS.
+
++makeExample('webpack/ts/src/app/app.component.ts')(format='.')
+:marked
+ See the [Introduction to Webpack](../guide/webpack.html).
diff --git a/public/docs/ts/latest/guide/component-styles.jade b/public/docs/ts/latest/guide/component-styles.jade
index d7975713a6..4d090a2e9c 100644
--- a/public/docs/ts/latest/guide/component-styles.jade
+++ b/public/docs/ts/latest/guide/component-styles.jade
@@ -311,55 +311,9 @@ code-example(format='').
block module-id
:marked
- We'd *prefer* to write this:
-
- +makeExample('component-styles/ts/app/quest-summary.component.ts', 'urls')(format='.')
-
- :marked
- We can't do that by default. Angular can't find the files and throws an error:
-
- `EXCEPTION: Failed to load quest-summary.component.html`
-
- Why can't Angular calculate the HTML and CSS URLs from the component file's location?
-
- Unfortunately, that location is not readily known.
- Angular apps can be loaded in many ways: from individual files, from SystemJS packages, or
- from CommonJS packages, to name a few.
- With this diversity of load strategies, it's not easy to tell at runtime where these files actually reside.
-
- The only location Angular can be sure of is the URL of the `index.html` home page.
- So by default it resolves template and style paths relative to the URL of `index.html`.
- That's why we previously wrote our CSS file URLs with an `app/` base path prefix.
-
- Although this works with any code loading scheme, it is very inconvenient.
- We move file folders around all the time during the evolution of our applications.
- It's no fun patching the style and template URLs when we do.
-
- ### *moduleId*
-
- We can change the way Angular calculates the full URL be setting the component metadata's `moduleId` property.
-
- If we knew the component file's base path, we'd set `moduleId` to that and
- let Angular construct the full URL from this base path plus the CSS and template file names.
-
- Our challenge is to calculate the base path with minimal effort.
- If it's too hard, we shouldn't bother; we should just write the full path to the root and move on.
- Fortunately, *certain* module loaders make it relatively easy to find the base path.
-
- SystemJS (starting in v.0.19.19) sets a *semi-global* variable to the URL of the component file.
- That makes it trivial to set the component metadata `moduleId` property to the component's URL
- and let Angular determine the module-relative paths for style and template URLs from there.
-
- The name of the *semi-global* variable depends upon whether we told TypeScript to transpile to
- 'system' or 'commonjs' format (see the `module` option in the
- [TypeScript compiler documentation](http://www.typescriptlang.org/docs/handbook/compiler-options.html)).
- The variables are `__moduleName` and `module.id` respectively.
-
- Here's an example in which we set the metadata `moduleId` to `module.id`.
+ We can change the way Angular calculates the full URL be setting the component metadata's `moduleId` property to `module.id`.
+makeExample('component-styles/ts/app/quest-summary.component.ts','', 'app/quest-summary.component.ts')
+ :marked
+ Learn more about `moduleId` in the [Component-Relative Paths](../cookbook/component-relative-paths.html) chapter.
- .l-sub-section
- :marked
- With a module bundler like Webpack we are more likely to set the `styles` and `template` properties with the bundler's
- `require` mechanism rather than bother with `styleUrls` and `templateUrl`.
diff --git a/public/docs/ts/latest/tutorial/toh-pt5.jade b/public/docs/ts/latest/tutorial/toh-pt5.jade
index 2a72f68d22..9d7f43629e 100644
--- a/public/docs/ts/latest/tutorial/toh-pt5.jade
+++ b/public/docs/ts/latest/tutorial/toh-pt5.jade
@@ -282,7 +282,9 @@ code-example(format="." language="bash").
+makeExample('toh-5/ts/app/dashboard.component.ts', 'template-url', 'app/dashboard.component.ts (templateUrl)')(format=".")
.l-sub-section
:marked
- We specify the path _all the way back to the application root_. Angular doesn't support module-relative paths.
+ We specify the path _all the way back to the application root_ — `app/` in this case —
+ because Angular doesn't support relative paths _by default_.
+ We _can_ switch to [component-relative paths](../cookbook/component-relative-paths) if we prefer.
:marked
Create that file with these contents:
+makeExample('toh-5/ts/app/dashboard.component.html', null, 'dashboard.component.html')(format=".")