aboutsummaryrefslogtreecommitdiffstats
path: root/docs/config
diff options
context:
space:
mode:
Diffstat (limited to 'docs/config')
-rw-r--r--docs/config/ignore.words701
-rw-r--r--docs/config/index.js29
-rw-r--r--docs/config/processors/index-page.js42
-rw-r--r--docs/config/processors/keywords.js91
-rw-r--r--docs/config/processors/pages-data.js200
-rw-r--r--docs/config/processors/versions-data.js42
-rw-r--r--docs/config/tag-defs/tutorial-step.js9
-rw-r--r--docs/config/templates/indexPage.template.html217
-rw-r--r--docs/config/templates/pages-data.template.js4
-rw-r--r--docs/config/templates/tutorial.template.html1
-rw-r--r--docs/config/templates/versions-data.template.js4
11 files changed, 1340 insertions, 0 deletions
diff --git a/docs/config/ignore.words b/docs/config/ignore.words
new file mode 100644
index 00000000..82b9f2fc
--- /dev/null
+++ b/docs/config/ignore.words
@@ -0,0 +1,701 @@
+a
+able
+about
+above
+abst
+accordance
+according
+accordingly
+across
+act
+actually
+added
+adj
+adopted
+affected
+affecting
+affects
+after
+afterwards
+again
+against
+ah
+all
+almost
+alone
+along
+already
+also
+although
+always
+am
+among
+amongst
+an
+and
+announce
+another
+any
+anybody
+anyhow
+anymore
+anyone
+anything
+anyway
+anyways
+anywhere
+apparently
+approximately
+are
+aren
+arent
+arise
+around
+as
+aside
+ask
+asking
+at
+auth
+available
+away
+awfully
+b
+back
+be
+became
+because
+become
+becomes
+becoming
+been
+before
+beforehand
+begin
+beginning
+beginnings
+begins
+behind
+being
+believe
+below
+beside
+besides
+between
+beyond
+biol
+both
+brief
+briefly
+but
+by
+c
+ca
+came
+can
+cannot
+can't
+cant
+cause
+causes
+certain
+certainly
+co
+com
+come
+comes
+contain
+containing
+contains
+could
+couldnt
+d
+date
+did
+didn't
+didnt
+different
+do
+does
+doesn't
+doesnt
+doing
+done
+don't
+dont
+down
+downwards
+due
+during
+e
+each
+ed
+edu
+effect
+eg
+eight
+eighty
+either
+else
+elsewhere
+end
+ending
+enough
+especially
+et
+et-al
+etc
+even
+ever
+every
+everybody
+everyone
+everything
+everywhere
+ex
+except
+f
+far
+few
+ff
+fifth
+first
+five
+fix
+followed
+following
+follows
+for
+former
+formerly
+forth
+found
+four
+from
+further
+furthermore
+g
+gave
+get
+gets
+getting
+give
+given
+gives
+giving
+go
+goes
+gone
+got
+gotten
+h
+had
+happens
+hardly
+has
+hasn't
+hasnt
+have
+haven't
+havent
+having
+he
+hed
+hence
+her
+here
+hereafter
+hereby
+herein
+heres
+hereupon
+hers
+herself
+hes
+hi
+hid
+him
+himself
+his
+hither
+home
+how
+howbeit
+however
+hundred
+i
+id
+ie
+if
+i'll
+ill
+im
+immediate
+immediately
+importance
+important
+in
+inc
+indeed
+index
+information
+instead
+into
+invention
+inward
+is
+isn't
+isnt
+it
+itd
+it'll
+itll
+its
+itself
+i've
+ive
+j
+just
+k
+keep
+keeps
+kept
+keys
+kg
+km
+know
+known
+knows
+l
+largely
+last
+lately
+later
+latter
+latterly
+least
+less
+lest
+let
+lets
+like
+liked
+likely
+line
+little
+'ll
+'ll
+look
+looking
+looks
+ltd
+m
+made
+mainly
+make
+makes
+many
+may
+maybe
+me
+mean
+means
+meantime
+meanwhile
+merely
+mg
+might
+million
+miss
+ml
+more
+moreover
+most
+mostly
+mr
+mrs
+much
+mug
+must
+my
+myself
+n
+na
+name
+namely
+nay
+nd
+near
+nearly
+necessarily
+necessary
+need
+needs
+neither
+never
+nevertheless
+new
+next
+nine
+ninety
+no
+nobody
+non
+none
+nonetheless
+noone
+nor
+normally
+nos
+not
+noted
+nothing
+now
+nowhere
+o
+obtain
+obtained
+obviously
+of
+off
+often
+oh
+ok
+okay
+old
+omitted
+on
+once
+one
+ones
+only
+onto
+or
+ord
+other
+others
+otherwise
+ought
+our
+ours
+ourselves
+out
+outside
+over
+overall
+owing
+own
+p
+page
+pages
+part
+particular
+particularly
+past
+per
+perhaps
+placed
+please
+plus
+poorly
+possible
+possibly
+potentially
+pp
+predominantly
+present
+previously
+primarily
+probably
+promptly
+proud
+provides
+put
+q
+que
+quickly
+quite
+qv
+r
+ran
+rather
+rd
+re
+readily
+really
+recent
+recently
+ref
+refs
+regarding
+regardless
+regards
+related
+relatively
+research
+respectively
+resulted
+resulting
+results
+right
+run
+s
+said
+same
+saw
+say
+saying
+says
+sec
+section
+see
+seeing
+seem
+seemed
+seeming
+seems
+seen
+self
+selves
+sent
+seven
+several
+shall
+she
+shed
+she'll
+shell
+shes
+should
+shouldn't
+shouldnt
+show
+showed
+shown
+showns
+shows
+significant
+significantly
+similar
+similarly
+since
+six
+slightly
+so
+some
+somebody
+somehow
+someone
+somethan
+something
+sometime
+sometimes
+somewhat
+somewhere
+soon
+sorry
+specifically
+specified
+specify
+specifying
+state
+states
+still
+stop
+strongly
+sub
+substantially
+successfully
+such
+sufficiently
+suggest
+sup
+sure
+t
+take
+taken
+taking
+tell
+tends
+th
+than
+thank
+thanks
+thanx
+that
+that'll
+thatll
+thats
+that've
+thatve
+the
+their
+theirs
+them
+themselves
+then
+thence
+there
+thereafter
+thereby
+thered
+therefore
+therein
+there'll
+therell
+thereof
+therere
+theres
+thereto
+thereupon
+there've
+thereve
+these
+they
+theyd
+they'll
+theyll
+theyre
+they've
+theyve
+think
+this
+those
+thou
+though
+thoughh
+thousand
+throug
+through
+throughout
+thru
+thus
+til
+tip
+to
+together
+too
+took
+toward
+towards
+tried
+tries
+truly
+try
+trying
+ts
+twice
+two
+u
+un
+under
+unfortunately
+unless
+unlike
+unlikely
+until
+unto
+up
+upon
+ups
+us
+use
+used
+useful
+usefully
+usefulness
+uses
+using
+usually
+v
+value
+various
+'ve
+'ve
+very
+via
+viz
+vol
+vols
+vs
+w
+want
+wants
+was
+wasn't
+wasnt
+way
+we
+wed
+welcome
+we'll
+well
+went
+were
+weren't
+werent
+we've
+weve
+what
+whatever
+what'll
+whatll
+whats
+when
+whence
+whenever
+where
+whereafter
+whereas
+whereby
+wherein
+wheres
+whereupon
+wherever
+whether
+which
+while
+whim
+whither
+who
+whod
+whoever
+whole
+who'll
+wholl
+whom
+whomever
+whos
+whose
+why
+widely
+will
+willing
+wish
+with
+within
+without
+won't
+wont
+words
+would
+wouldn't
+wouldnt
+www
+x
+y
+yes
+yet
+you
+youd
+you'll
+youll
+your
+youre
+yours
+yourself
+yourselves
+you've
+youve
+z
+zero
diff --git a/docs/config/index.js b/docs/config/index.js
new file mode 100644
index 00000000..ae905889
--- /dev/null
+++ b/docs/config/index.js
@@ -0,0 +1,29 @@
+var _ = require('lodash');
+var path = require('canonical-path');
+var packagePath = __dirname;
+
+var angularjsPackage = require('dgeni-packages/ngdoc');
+
+module.exports = function(config) {
+
+ config = angularjsPackage(config);
+
+ config.append('processing.processors', [
+ require('./processors/keywords'),
+ require('./processors/versions-data'),
+ require('./processors/pages-data'),
+ require('./processors/index-page')
+ ]);
+
+ config.append('processing.tagDefinitions', [
+ require('./tag-defs/tutorial-step')
+ ]);
+
+ config.set('processing.search.ignoreWordsFile', path.resolve(packagePath, 'ignore.words'));
+
+ config.prepend('rendering.templateFolders', [
+ path.resolve(packagePath, 'templates')
+ ]);
+
+ return config;
+};
diff --git a/docs/config/processors/index-page.js b/docs/config/processors/index-page.js
new file mode 100644
index 00000000..3ba1ac73
--- /dev/null
+++ b/docs/config/processors/index-page.js
@@ -0,0 +1,42 @@
+var _ = require('lodash');
+var log = require('winston');
+var path = require('canonical-path');
+var deployment;
+
+module.exports = {
+ name: 'index-page',
+ runAfter: ['adding-extra-docs'],
+ runBefore: ['extra-docs-added'],
+ description: 'This processor creates docs that will be rendered as the index page for the app',
+ init: function(config) {
+ deployment = config.deployment;
+ if ( !deployment || !deployment.environments ) {
+ throw new Errro('No deployment environments found in the config.');
+ }
+ },
+ process: function(docs) {
+
+ // Collect up all the areas in the docs
+ var areas = {};
+ _.forEach(docs, function(doc) {
+ if ( doc.area ) {
+ areas[doc.area] = doc.area;
+ }
+ });
+ areas = _.keys(areas);
+
+ _.forEach(deployment.environments, function(environment) {
+
+ var indexDoc = _.defaults({
+ docType: 'indexPage',
+ areas: areas
+ }, environment);
+
+ indexDoc.id = 'index' + (environment.name === 'default' ? '' : '-' + environment.name);
+ // Use .. to put it at the root of the build
+ indexDoc.outputPath = indexDoc.id + '.html';
+
+ docs.push(indexDoc);
+ });
+ }
+}; \ No newline at end of file
diff --git a/docs/config/processors/keywords.js b/docs/config/processors/keywords.js
new file mode 100644
index 00000000..6f7e9c21
--- /dev/null
+++ b/docs/config/processors/keywords.js
@@ -0,0 +1,91 @@
+var _ = require('lodash');
+var log = require('winston');
+var fs = require('fs');
+var path = require('canonical-path');
+
+// Keywords to ignore
+var wordsToIgnore = [];
+var propertiesToIgnore;
+var areasToSearch;
+
+// Keywords start with "ng:" or one of $, _ or a letter
+var KEYWORD_REGEX = /^((ng:|[\$_a-z])[\w\-_]+)/;
+
+module.exports = {
+ name: 'keywords',
+ runAfter: ['docs-processed'],
+ runBefore: ['adding-extra-docs'],
+ description: 'This processor extracts all the keywords from the document',
+ init: function(config) {
+
+ // Load up the keywords to ignore, if specified in the config
+ if ( config.processing.search && config.processing.search.ignoreWordsFile ) {
+
+ var ignoreWordsPath = path.resolve(config.basePath, config.processing.search.ignoreWordsFile);
+ wordsToIgnore = fs.readFileSync(ignoreWordsPath, 'utf8').toString().split(/[,\s\n\r]+/gm);
+
+ log.debug('Loaded ignore words from "' + ignoreWordsPath + '"');
+ log.silly(wordsToIgnore);
+
+ }
+
+ areasToSearch = _.indexBy(config.get('processing.search.areasToSearch', ['api', 'guide', 'misc', 'error', 'tutorial']));
+
+ propertiesToIgnore = _.indexBy(config.get('processing.search.propertiesToIgnore', []));
+ log.debug('Properties to ignore', propertiesToIgnore);
+
+ },
+ process: function(docs) {
+
+ var ignoreWordsMap = _.indexBy(wordsToIgnore);
+
+ // If the title contains a name starting with ng, e.g. "ngController", then add the module name
+ // without the ng to the title text, e.g. "controller".
+ function extractTitleWords(title) {
+ var match = /ng([A-Z]\w*)/.exec(title);
+ if ( match ) {
+ title = title + ' ' + match[1].toLowerCase();
+ }
+ return title;
+ }
+
+ function extractWords(text, words, keywordMap) {
+
+ var tokens = text.toLowerCase().split(/[\.\s,`'"#]+/mg);
+ _.forEach(tokens, function(token){
+ var match = token.match(KEYWORD_REGEX);
+ if (match){
+ key = match[1];
+ if ( !keywordMap[key]) {
+ keywordMap[key] = true;
+ words.push(key);
+ }
+ }
+ });
+ }
+
+
+ // We are only interested in docs that live in the right area
+ docs = _.filter(docs, function(doc) { return areasToSearch[doc.area]; });
+
+ _.forEach(docs, function(doc) {
+
+ var words = [];
+ var keywordMap = _.clone(ignoreWordsMap);
+
+ // Search each top level property of the document for search terms
+ _.forEach(doc, function(value, key) {
+ if ( _.isString(value) && !propertiesToIgnore[key] ) {
+ extractWords(value, words, keywordMap);
+ }
+ });
+
+ doc.searchTerms = {
+ titleWords: extractTitleWords(doc.name),
+ keywords: _.sortBy(words).join(' ')
+ };
+
+ });
+
+ }
+}; \ No newline at end of file
diff --git a/docs/config/processors/pages-data.js b/docs/config/processors/pages-data.js
new file mode 100644
index 00000000..47896db5
--- /dev/null
+++ b/docs/config/processors/pages-data.js
@@ -0,0 +1,200 @@
+var _ = require('lodash');
+var path = require('canonical-path');
+var log = require('winston');
+
+var AREA_NAMES = {
+ api: 'API',
+ guide: 'Developer Guide',
+ misc: 'Miscellaneous',
+ tutorial: 'Tutorial',
+ error: 'Error Reference'
+};
+
+function getNavGroup(navGroupPages, groupName, pageSorter, pageMapper) {
+
+ var navItems = _(navGroupPages)
+ .sortBy(pageSorter)
+ .map(pageMapper)
+ .value();
+
+ return {
+ name: groupName,
+ type: 'group',
+ navItems: navItems
+ };
+}
+
+
+var navGroupMappers = {
+ api: function(areaPages, areaName) {
+ var navGroups = _(areaPages)
+ .filter('module') // We are not interested in docs that are not in a module
+
+ .groupBy('module')
+
+ .map(function(modulePages, moduleName) {
+ console.log('moduleName', moduleName);
+ var navItems = [];
+ var modulePage;
+
+ _(modulePages)
+
+ .groupBy('docType')
+
+ .tap(function(docTypes) {
+ console.log(_.keys(docTypes));
+ // Extract the module page from the collection
+ modulePage = docTypes.module[0];
+ delete docTypes.module;
+ })
+
+ .forEach(function(sectionPages, sectionName) {
+
+ if ( sectionPages.length > 0 ) {
+ // Push a navItem for this section
+ navItems.push({
+ name: sectionName,
+ type: 'section',
+ href: path.dirname(sectionPages[0].path)
+ });
+
+ // Push the rest of the sectionPages for this section
+ _.forEach(sectionPages, function(sectionPage) {
+
+ navItems.push({
+ name: sectionPage.name,
+ href: sectionPage.path,
+ type: sectionPage.docType
+ });
+
+ });
+ }
+ });
+ return {
+ name: moduleName,
+ href: modulePage.path,
+ type: 'group',
+ navItems: navItems
+ };
+ })
+ .value();
+ return navGroups;
+ },
+ tutorial: function(pages, areaName) {
+ return [getNavGroup(pages, areaName, 'step', function(page) {
+ return {
+ name: page.name,
+ step: page.step,
+ href: page.path,
+ type: 'tutorial'
+ };
+ })];
+ },
+ error: function(pages, areaName) {
+ return [getNavGroup(pages, areaName, 'path', function(page) {
+ return {
+ name: page.name,
+ href: page.path,
+ type: 'error'
+ };
+ })];
+ },
+ pages: function(pages, areaName) {
+ return [getNavGroup(pages, areaName, 'path', function(page) {
+ return {
+ name: page.name,
+ href: page.path,
+ type: 'page'
+ };
+ })];
+ }
+};
+
+var outputFolder;
+
+module.exports = {
+ name: 'pages-data',
+ description: 'This plugin will create a new doc that will be rendered as an angularjs module ' +
+ 'which will contain meta information about the pages and navigation',
+ runAfter: ['adding-extra-docs', 'component-groups-generate'],
+ runBefore: ['extra-docs-added'],
+ init: function(config) {
+ outputFolder = config.rendering.outputFolder;
+ },
+ process: function(docs) {
+
+ _(docs)
+ .filter(function(doc) { return doc.area === 'api'; })
+ .filter(function(doc) { return doc.docType === 'module'; })
+ .map(function(doc) { return _.pick(doc, ['id', 'module', 'docType', 'area']); })
+ .tap(function(docs) {
+ console.log(docs);
+ });
+
+
+ // We are only interested in docs that are in a area and not landing pages
+ var navPages = _.filter(docs, function(page) {
+ return page.area && page.docType != 'landingPage';
+ });
+
+ // Generate an object collection of pages that is grouped by area e.g.
+ // - area "api"
+ // - group "ng"
+ // - section "directive"
+ // - ngApp
+ // - ngBind
+ // - section "global"
+ // - angular.element
+ // - angular.bootstrap
+ // - section "service"
+ // - $compile
+ // - group "ngRoute"
+ // - section "directive"
+ // - ngView
+ // - section "service"
+ // - $route
+ //
+ var areas = {};
+ _(navPages)
+ .groupBy('area')
+ .forEach(function(pages, areaName) {
+ var navGroupMapper = navGroupMappers[areaName] || navGroupMappers['pages'];
+ var areaTitle = AREA_NAMES[areaName];
+
+ areas[areaName] = {
+ id: areaName,
+ name: areaTitle,
+ navGroups: navGroupMapper(pages, areaTitle)
+ };
+ });
+
+ _.forEach(docs, function(doc) {
+ if ( !doc.path ) {
+ log.warn('Missing path property for ', doc.id);
+ }
+ });
+
+ // Extract a list of basic page information for mapping paths to paritals and for client side searching
+ var pages = _(docs)
+ .map(function(doc) {
+ var page = _.pick(doc, [
+ 'docType', 'id', 'name', 'area', 'outputPath', 'path', 'searchTerms'
+ ]);
+ return page;
+ })
+ .indexBy('path')
+ .value();
+
+
+ var docData = {
+ docType: 'pages-data',
+ id: 'pages-data',
+ template: 'pages-data.template.js',
+ outputPath: 'js/pages-data.js',
+
+ areas: areas,
+ pages: pages
+ };
+ docs.push(docData);
+ }
+};
diff --git a/docs/config/processors/versions-data.js b/docs/config/processors/versions-data.js
new file mode 100644
index 00000000..eb158e79
--- /dev/null
+++ b/docs/config/processors/versions-data.js
@@ -0,0 +1,42 @@
+var _ = require('lodash');
+
+var version;
+var versions;
+
+module.exports = {
+ name: 'versions-data',
+ description: 'This plugin will create a new doc that will be rendered as an angularjs module ' +
+ 'which will contain meta information about the versions of angular',
+ runAfter: ['adding-extra-docs', 'pages-data'],
+ runBefore: ['extra-docs-added'],
+ init: function(config) {
+ version = config.source.currentVersion;
+ versions = config.source.previousVersions;
+
+ if ( !version ) {
+ throw new Error('Invalid configuration. Please provide a valid `source.currentVersion` property');
+ }
+ if ( !versions ) {
+ throw new Error('Invalid configuration. Please provide a valid `source.previousVersions` property');
+ }
+ },
+ process: function(docs) {
+
+ var versionDoc = {
+ docType: 'versions-data',
+ id: 'versions-data',
+ template: 'versions-data.template.js',
+ outputPath: 'js/versions-data.js',
+ };
+
+ versionDoc.currentVersion = version;
+
+ versionDoc.versions = _(versions)
+ .filter(function(version) { return version.major > 0; })
+ .push(version)
+ .reverse()
+ .value();
+
+ docs.push(versionDoc);
+ }
+}; \ No newline at end of file
diff --git a/docs/config/tag-defs/tutorial-step.js b/docs/config/tag-defs/tutorial-step.js
new file mode 100644
index 00000000..4ebe9d6a
--- /dev/null
+++ b/docs/config/tag-defs/tutorial-step.js
@@ -0,0 +1,9 @@
+module.exports = {
+ name: 'step',
+ transformFn: function(doc, tag) {
+ if ( doc.docType !== 'tutorial' ) {
+ throw new Error('Invalid tag, step. You should only use this tag on tutorial docs');
+ }
+ return parseInt(tag.description,10);
+ }
+};
diff --git a/docs/config/templates/indexPage.template.html b/docs/config/templates/indexPage.template.html
new file mode 100644
index 00000000..6366d020
--- /dev/null
+++ b/docs/config/templates/indexPage.template.html
@@ -0,0 +1,217 @@
+<!doctype html>
+<html lang="en" ng-app="docsApp" ng-controller="DocsController">
+<head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="Description"
+ content="AngularJS is what HTML would have been, had it been designed for building web-apps.
+ Declarative templates with data-binding, MVC, dependency injection and great
+ testability story all implemented with pure client-side JavaScript!">
+ <meta name="fragment" content="!">
+ <title ng-bind-template="AngularJS: {{ currentArea.name }}: {{ currentPage.name || 'Error: Page not found'}}">AngularJS</title>
+
+ <script type="text/javascript">
+ // dynamically add base tag as well as css and javascript files.
+ // we can't add css/js the usual way, because some browsers (FF) eagerly prefetch resources
+ // before the base attribute is added, causing 404 and terribly slow loading of the docs app.
+ (function() {
+ var indexFile = (location.pathname.match(/\/(index[^\.]*\.html)/) || ['', ''])[1],
+ rUrl = /(#!\/|api|guide|misc|tutorial|error|index[^\.]*\.html).*$/,
+ baseUrl = location.href.replace(rUrl, indexFile),
+ production = location.hostname === 'docs.angularjs.org',
+ headEl = document.getElementsByTagName('head')[0],
+ sync = true;
+
+ addTag('base', {href: baseUrl});
+
+
+ {% for stylesheet in doc.stylesheets %}addTag('link', {rel: 'stylesheet', href: '{$ stylesheet $}', type: 'text/css'});
+ {% endfor %}
+
+ {% for script in doc.scripts %}addTag('script', {src: '{$ script $}' }, sync);
+ {% endfor %}
+
+ function addTag(name, attributes, sync) {
+ var el = document.createElement(name),
+ attrName;
+
+ for (attrName in attributes) {
+ el.setAttribute(attrName, attributes[attrName]);
+ }
+
+ sync ? document.write(outerHTML(el)) : headEl.appendChild(el);
+ }
+
+ function outerHTML(node){
+ // if IE, Chrome take the internal method otherwise build one
+ return node.outerHTML || (
+ function(n){
+ var div = document.createElement('div'), h;
+ div.appendChild(n);
+ h = div.innerHTML;
+ div = null;
+ return h;
+ })(node);
+ }
+ })();
+ </script>
+</head>
+<body>
+ <header class="header">
+ <div class="navbar navbar-inverse navbar-fixed-top" ng-controller="DocsSearchCtrl">
+ <div class="container">
+ <div class="navbar-header">
+ <a class="brand navbar-brand" href="http://angularjs.org">
+ <img class="logo" src="img/angularjs-for-header-only.svg">
+ </a>
+ </div>
+ <div class="row">
+ <ul class="nav navbar-nav col-md-7">
+ <li class="divider-vertical"></li>
+ <li><a href="http://angularjs.org"><i class="icon-home icon-white"></i> Home</a></li>
+ <li class="divider-vertical"></li>
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ <i class="icon-eye-open icon-white"></i> Learn <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li class="disabled"><a href="http://angularjs.org/">Why AngularJS?</a></li>
+ <li><a href="http://www.youtube.com/user/angularjs">Watch</a></li>
+ <li><a href="tutorial">Tutorial</a></li>
+ <li><a href="http://builtwith.angularjs.org/">Case Studies</a></li>
+ <li><a href="https://github.com/angular/angular-seed">Seed App project template</a></li>
+ <li><a href="misc/faq">FAQ</a></li>
+ </ul>
+ </li>
+ <li class="divider-vertical"></li>
+ <li class="dropdown active">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ <i class="icon-book icon-white"></i> Develop <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li><a href="./tutorial/">Tutorial</a></li>
+ <li><a href="./guide/">Developer Guide</a></li>
+ <li><a href="./api/">API Reference</a></li>
+ <li><a href="./error/">Error Reference</a></li>
+ <li><a href="./misc/contribute">Contribute</a></li>
+ <li><a href="http://code.angularjs.org/">Download</a></li>
+ </ul>
+ </li>
+ <li class="divider-vertical"></li>
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ <i class="icon-comment icon-white"></i> Discuss <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li><a href="http://blog.angularjs.org">Blog</a></li>
+ <li><a href="http://groups.google.com/group/angular">Mailing List</a></li>
+ <li><a href="http://webchat.freenode.net/?channels=angularjs&uio=d4">Chat Room</a></li>
+ <li class="divider"></li>
+ <li><a href="https://twitter.com/#!/angularjs">Twitter</a></li>
+ <li><a href="https://plus.google.com/110323587230527980117">Google+</a></li>
+ <li class="divider"></li>
+ <li><a href="https://github.com/angular/angular.js">GitHub</a></li>
+ <li><a href="https://github.com/angular/angular.js/issues">Issue Tracker</a></li>
+ </ul>
+ </li>
+ <li class="divider-vertical"></li>
+ </ul>
+ <form ng-class="{focus:focus}" class="navbar-search col-md-3 docs-search" ng-submit="submit()">
+ <span class="glyphicon glyphicon-search search-icon"></span>
+ <input type="text"
+ name="as_q"
+ class="search-query"
+ placeholder="Click or press / to search"
+ ng-focus="focus=true"
+ ng-blur="focus=false"
+ ng-change="search(q)"
+ ng-model="q"
+ docs-search-input
+ autocomplete="off" />
+ </form>
+ </div>
+ </div>
+ <div class="search-results-container" ng-show="hasResults">
+ <div class="container">
+ <a href="" ng-click="hideResults()" class="search-close">
+ <span class="glyphicon glyphicon-remove search-close-icon"></span>
+ </a>
+ <div class="search-results-frame">
+ <div ng-repeat="(key, value) in results" class="search-results-group" ng-class="colClassName + ' col-group-' + key">
+ <h4 class="search-results-group-heading">{{ key }}</h4>
+ <div class="search-results">
+ <div ng-repeat="item in value" class="search-result">
+ - <a ng-click="hideResults()" ng-href="{{ item.path }}">{{ item.name }}</a>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </header>
+
+<div>
+ <section role="main" class="container main-body">
+ <div class="main-body-grid">
+ <div class="grid-left">
+ <div ng-controller="DocsVersionsCtrl" class="picker version-picker">
+ <select ng-options="v as ('AngularJS ' + v.full) group by (v.isStable?'Stable':'Unstable') for v in docs_versions"
+ ng-model="docs_version"
+ ng-change="jumpToDocsVersion(docs_version)"
+ class="docs-version-jump">
+ </select>
+ </div>
+ <div class="side-navigation">
+ <ul class="nav-list naked-list">
+ <li ng-repeat="navGroup in currentArea.navGroups track by navGroup.name" class="nav-index-group">
+ <a href="{{ navGroup.href }}" ng-class="navClass(navGroup)" class="nav-index-group-heading">{{ navGroup.name }}</a>
+ <ul class="aside-nav">
+ <li ng-repeat="navItem in navGroup.navItems" ng-class="navClass(navItem)" class="nav-index-listing">
+ <a ng-if="navItem.extra.href" ng-class="navClass(navItem.extra)" href="{{navItem.extra.href}}">
+ {{navItem.extra.text}}<i ng-if="navItem.extra.icon" class="icon-{{navItem.extra.icon}}"></i>
+ </a>
+ <a tabindex="2" ng-class="linkClass(navItem)" href="{{navItem.href}}">{{navItem.name}}</a>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </div>
+ </div>
+ <div class="grid-right">
+ <ul class="nav-breadcrumb">
+ <li ng-repeat="crumb in breadcrumb" class="nav-breadcrumb-entry naked-list">
+ <span class="divider"> /</span>
+ <a ng-href="{{crumb.url}}">{{crumb.name}}</a>
+ </li>
+ </ul>
+ <div id="loading" ng-show="loading">Loading...</div>
+ <div ng-hide="loading" ng-include="currentPage.outputPath" autoscroll></div>
+ </div>
+ </div>
+ </section>
+
+ <footer class="footer">
+ <div class="container">
+ <p class="pull-right"><a back-to-top href="#">Back to top</a></p>
+
+ <p>
+ Super-powered by Google ©2010-2014
+ ( <a id="version"
+ ng-href="https://github.com/angular/angular.js/blob/master/CHANGELOG.md#{{versionNumber}}"
+ ng-bind-template="v{{version}}">
+ </a>
+ )
+ </p>
+ <p>
+ Code licensed under the
+ <a href="https://github.com/angular/angular.js/blob/master/LICENSE" target="_blank">The
+ MIT License</a>. Documentation licensed under <a
+ href="http://creativecommons.org/licenses/by/3.0/">CC BY 3.0</a>.
+ </p>
+ </div>
+ </footer>
+</div>
+
+</body>
+</html>
diff --git a/docs/config/templates/pages-data.template.js b/docs/config/templates/pages-data.template.js
new file mode 100644
index 00000000..157f786e
--- /dev/null
+++ b/docs/config/templates/pages-data.template.js
@@ -0,0 +1,4 @@
+// Meta data used by the AngularJS docs app
+angular.module('pagesData', [])
+ .value('NG_PAGES', {$ doc.pages | json $})
+ .value('NG_NAVIGATION', {$ doc.areas | json $});
diff --git a/docs/config/templates/tutorial.template.html b/docs/config/templates/tutorial.template.html
new file mode 100644
index 00000000..14566bbb
--- /dev/null
+++ b/docs/config/templates/tutorial.template.html
@@ -0,0 +1 @@
+{% include 'overview.template.html' %} \ No newline at end of file
diff --git a/docs/config/templates/versions-data.template.js b/docs/config/templates/versions-data.template.js
new file mode 100644
index 00000000..4db31331
--- /dev/null
+++ b/docs/config/templates/versions-data.template.js
@@ -0,0 +1,4 @@
+// Meta data used by the AngularJS docs app
+angular.module('versionsData', [])
+ .value('NG_VERSION', {$ doc.currentVersion | json $})
+ .value('NG_VERSIONS', {$ doc.versions | json $});