diff --git a/README.md b/README.md index 3bb0d15..6cf16d8 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,13 @@ meteor-breadcrumb-plugin ======================== -This package will provide a easy way to add a breadcrumb with enough flexibility to your project. +This package will provide a easy way to add a breadcrumb with some flexibility to your project. -# Try the [demo](http://meteor-breadcrumb-plugin-basic-example.meteor.com) which can be found on [github](https://github.com/monbro/meteor-breadcrumb-plugin/tree/master/examples/basic) +# Demo and Examples + +## Simple [demo](http://meteor-breadcrumb-plugin-simple-example.meteor.com), on [github](https://github.com/monbro/meteor-breadcrumb-plugin/tree/master/examples/simple) + +## Advanced [demo](http://meteor-breadcrumb-plugin-advanced-example.meteor.com), on [github](https://github.com/monbro/meteor-breadcrumb-plugin/tree/master/examples/advanced) # Dependencies @@ -13,7 +17,7 @@ This package will provide a easy way to add a breadcrumb with enough flexibility # Compatibility * works out of the box with bootstrap3 -* use the pre existing template or use your own +* use the pre existing breadcrumb template or use your own easily # Installation @@ -23,11 +27,16 @@ Use `meteor add monbro:iron-router-breadcrumb` to add the package to your meteor * You need to add two parameters to your iron routes which are `parent` and `title` -## 1. Example Iron Route with multiple levels +## 1. Example iron route with multiple levels ### In this example the Breadcrumb would look or the url `/dashboard/analytics/books` like: `Dashboard / Analytics / Category Books` ``` +// Configure a default title (optional) +Router.configure({ + defaultBreadcrumbTitle: 'My Site' +}); + // Level 0 Router.route('/', { name: 'dashboard', @@ -52,7 +61,7 @@ Router.route('/dashboard/analytics/books', { }); ``` -## 2. Example Dynamic Iron Route +## 2. Example dynamic iron route ### In this example the Breadcrumb would look for the url `/post/hello-world` like: `Home / Blogpost Hello-World` @@ -71,7 +80,49 @@ Router.route('/post/:_name', { }); ``` -## Example custom template for navigation +## 3. Example using a function for the title + +### In this example the Breadcrumb would look for the url `/post/hello-world` like: `Home / Blogpost Hello-World` + +``` +Router.route('/', { + name: 'home', + template: 'home', + title: 'Home' +}); + +Router.route('/post/:_name', { + name: 'post', + parent: 'home', // this should be the name variable of the parent route + template: 'singleBlogPost', + data: { + firstname: 'Gandalf', + lastname: 'the Grey' + }, + title: function() { + // using a function to generate the title dynamically + var data = this.data(); + console.log('Our data object for this route:'); + console.log(data); + console.log(''); + console.log('all given parameters for this route:'); + console.log(this.params); + return 'Dynamic Title for '+data.firstname+' for post: '+this.params['_name']; + } +}); + +// a more simple example +Router.route('/function-title', { + name: 'function.title', + parent: 'home', + template: 'functiontitle', + title: function() { + return 'By-Function-Retuned'; + } +}); +``` + +## 4. Example using a custom template for the breadcrumb ### Please note, that you dont have to use a custom template with the name `breadcrumb`, you can use the existing one out of the box by simply using `{{> breadcrumb}}` to include the preexisting template (which looks exact like the following example) anywhere in your own templates. @@ -85,7 +136,7 @@ Router.route('/post/:_name', { ``` -## Example access of the breadcrumb in Javascript +## 5. Example on how to access the breadcrumb object on the client ``` if (Meteor.is_client) { @@ -93,4 +144,4 @@ if (Meteor.is_client) { console.log(Breadcrumb.getAll()); // you can access the breadcrumb objects in a template helper as well } } -``` \ No newline at end of file +``` diff --git a/examples/basic/.meteor/.finished-upgraders b/examples/advanced/.meteor/.finished-upgraders similarity index 100% rename from examples/basic/.meteor/.finished-upgraders rename to examples/advanced/.meteor/.finished-upgraders diff --git a/examples/basic/.meteor/.gitignore b/examples/advanced/.meteor/.gitignore similarity index 100% rename from examples/basic/.meteor/.gitignore rename to examples/advanced/.meteor/.gitignore diff --git a/examples/basic/.meteor/.id b/examples/advanced/.meteor/.id similarity index 100% rename from examples/basic/.meteor/.id rename to examples/advanced/.meteor/.id diff --git a/examples/basic/.meteor/cordova-plugins b/examples/advanced/.meteor/cordova-plugins similarity index 100% rename from examples/basic/.meteor/cordova-plugins rename to examples/advanced/.meteor/cordova-plugins diff --git a/examples/basic/.meteor/packages b/examples/advanced/.meteor/packages similarity index 92% rename from examples/basic/.meteor/packages rename to examples/advanced/.meteor/packages index 76f157f..33012bf 100644 --- a/examples/basic/.meteor/packages +++ b/examples/advanced/.meteor/packages @@ -4,6 +4,6 @@ # but you can also edit it by hand. meteor-platform +twbs:bootstrap iron:router monbro:iron-router-breadcrumb -mizzao:bootstrap-3 \ No newline at end of file diff --git a/examples/basic/.meteor/platforms b/examples/advanced/.meteor/platforms similarity index 100% rename from examples/basic/.meteor/platforms rename to examples/advanced/.meteor/platforms diff --git a/examples/basic/.meteor/release b/examples/advanced/.meteor/release similarity index 100% rename from examples/basic/.meteor/release rename to examples/advanced/.meteor/release diff --git a/examples/advanced/.meteor/versions b/examples/advanced/.meteor/versions new file mode 100644 index 0000000..06ee2d4 --- /dev/null +++ b/examples/advanced/.meteor/versions @@ -0,0 +1,56 @@ +autoupdate@1.2.1 +base64@1.0.3 +binary-heap@1.0.3 +blaze@2.1.2 +blaze-tools@1.0.3 +boilerplate-generator@1.0.3 +callback-hook@1.0.3 +check@1.0.5 +ddp@1.1.0 +deps@1.0.7 +ejson@1.0.6 +fastclick@1.0.3 +geojson-utils@1.0.3 +html-tools@1.0.4 +htmljs@1.0.4 +http@1.1.0 +id-map@1.0.3 +iron:controller@1.0.8 +iron:core@1.0.8 +iron:dynamic-template@1.0.8 +iron:layout@1.0.8 +iron:location@1.0.9 +iron:middleware-stack@1.0.9 +iron:router@1.0.9 +iron:url@1.0.9 +jquery@1.11.3_2 +json@1.0.3 +launch-screen@1.0.2 +livedata@1.0.13 +logging@1.0.7 +meteor@1.1.6 +meteor-platform@1.2.2 +minifiers@1.1.5 +minimongo@1.0.8 +mobile-status-bar@1.0.3 +monbro:iron-router-breadcrumb@1.0.8 +mongo@1.1.0 +observe-sequence@1.0.6 +ordered-dict@1.0.3 +random@1.0.3 +reactive-dict@1.1.0 +reactive-var@1.0.5 +reload@1.1.3 +retry@1.0.3 +routepolicy@1.0.5 +session@1.1.0 +spacebars@1.0.6 +spacebars-compiler@1.0.6 +templating@1.1.1 +tracker@1.0.7 +twbs:bootstrap@3.3.5 +ui@1.0.6 +underscore@1.0.3 +url@1.0.4 +webapp@1.2.0 +webapp-hashing@1.0.3 diff --git a/examples/advanced/meteor.css b/examples/advanced/meteor.css new file mode 100644 index 0000000..b9647f7 --- /dev/null +++ b/examples/advanced/meteor.css @@ -0,0 +1,4 @@ +/* CSS declarations go here */ +body { + margin: 40px auto; +} \ No newline at end of file diff --git a/examples/advanced/meteor.html b/examples/advanced/meteor.html new file mode 100644 index 0000000..d3b2a06 --- /dev/null +++ b/examples/advanced/meteor.html @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + diff --git a/examples/advanced/meteor.js b/examples/advanced/meteor.js new file mode 100644 index 0000000..09e5c4b --- /dev/null +++ b/examples/advanced/meteor.js @@ -0,0 +1,92 @@ +/** + * example configuration for the beadcrumb package + */ + +// default values for the breadcrumb package are stored in the router configuration object as well +Router.configure({ + layoutTemplate: 'layout', + defaultBreadcrumbTitle: 'My Default Title' +}); + +// Level 0 +Router.route('/', { + name: 'dashboard', + template: 'dashboard', + title: 'Dashboard', + data: {name: 'Gandalf'} +}); + +Router.route('/analytics', { + name: 'analytics', + parent: 'dashboard', + template: 'analytics', + title: 'Analytics' +}); + +Router.route('/analytics/books', { + name: 'analytics.books', + parent: 'analytics', + template: 'analyticsBooks', + title: 'Category Books' +}); + +Router.route('/tags', { + name: 'tags', + parent: 'dashboard', + template: 'tags', + title: 'Taglist' +}); + +Router.route('/tag/:_name', { + name: 'tag', + parent: 'tags', + template: 'tagDetail', + title: 'Detailpage for :_name', + data: function () { + return this.params; + }, +}); + +Router.route('/default-title', { + name: 'default.title', + parent: 'dashboard', + template: 'defaulttitle' +}); + +Router.route('/function-title/:_someparam', { + name: 'function.title', + parent: 'dashboard', + template: 'functiontitle', + data: { + firstname: 'Gandalf', + lastname: 'the Grey' + }, + title: function() { + var data = this.data(); + console.log('Our data object for this route:'); + console.log(data); + console.log(''); + console.log('all given parameters for this route:'); + console.log(this.params); + return 'Dynamic Title for '+data.firstname+' for route details: '+this.params['_someparam']; + } +}); + +/** + * example page specific stuff below here, just for demonstration purpose + * you do not need this to make the breadcrumb package work + */ + +// register a iron router template helper to check if the route is active +UI.registerHelper('isActiveRoute', function(routeName) { + var currentRoute = Router.current(); + return currentRoute && routeName === currentRoute.route.getName() ? 'active' : ''; +}); + + // init tooltips for the example page +if (Meteor.isClient) { + Template.layout.rendered = function() { + $('[data-toggle="tooltip"]').tooltip({'trigger':'manual'}); + $('[data-toggle="tooltip"]').tooltip('show'); + }; +} \ No newline at end of file diff --git a/examples/simple/.meteor/.finished-upgraders b/examples/simple/.meteor/.finished-upgraders new file mode 100755 index 0000000..8a76103 --- /dev/null +++ b/examples/simple/.meteor/.finished-upgraders @@ -0,0 +1,8 @@ +# This file contains information which helps Meteor properly upgrade your +# app when you run 'meteor update'. You should check it into version control +# with your project. + +notices-for-0.9.0 +notices-for-0.9.1 +0.9.4-platform-file +notices-for-facebook-graph-api-2 diff --git a/examples/simple/.meteor/.gitignore b/examples/simple/.meteor/.gitignore new file mode 100755 index 0000000..4083037 --- /dev/null +++ b/examples/simple/.meteor/.gitignore @@ -0,0 +1 @@ +local diff --git a/examples/simple/.meteor/.id b/examples/simple/.meteor/.id new file mode 100755 index 0000000..8c77495 --- /dev/null +++ b/examples/simple/.meteor/.id @@ -0,0 +1,7 @@ +# This file contains a token that is unique to your project. +# Check it into your repository along with the rest of this directory. +# It can be used for purposes such as: +# - ensuring you don't accidentally deploy one app on top of another +# - providing package authors with aggregated statistics + +16e61x41u2eo8xds80ox diff --git a/examples/simple/.meteor/cordova-plugins b/examples/simple/.meteor/cordova-plugins new file mode 100755 index 0000000..8b13789 --- /dev/null +++ b/examples/simple/.meteor/cordova-plugins @@ -0,0 +1 @@ + diff --git a/examples/simple/.meteor/packages b/examples/simple/.meteor/packages new file mode 100755 index 0000000..3cf19fa --- /dev/null +++ b/examples/simple/.meteor/packages @@ -0,0 +1,10 @@ +# Meteor packages used by this project, one per line. +# +# 'meteor add' and 'meteor remove' will edit this file for you, +# but you can also edit it by hand. + +meteor-platform +iron:router +monbro:iron-router-breadcrumb +mizzao:bootstrap-3 + diff --git a/examples/simple/.meteor/platforms b/examples/simple/.meteor/platforms new file mode 100755 index 0000000..efeba1b --- /dev/null +++ b/examples/simple/.meteor/platforms @@ -0,0 +1,2 @@ +server +browser diff --git a/examples/simple/.meteor/release b/examples/simple/.meteor/release new file mode 100644 index 0000000..315c635 --- /dev/null +++ b/examples/simple/.meteor/release @@ -0,0 +1 @@ +METEOR@1.1.0.3 diff --git a/examples/basic/.meteor/versions b/examples/simple/.meteor/versions similarity index 100% rename from examples/basic/.meteor/versions rename to examples/simple/.meteor/versions diff --git a/examples/basic/meteor.css b/examples/simple/meteor.css old mode 100644 new mode 100755 similarity index 100% rename from examples/basic/meteor.css rename to examples/simple/meteor.css diff --git a/examples/basic/meteor.html b/examples/simple/meteor.html old mode 100644 new mode 100755 similarity index 100% rename from examples/basic/meteor.html rename to examples/simple/meteor.html diff --git a/examples/basic/meteor.js b/examples/simple/meteor.js old mode 100644 new mode 100755 similarity index 100% rename from examples/basic/meteor.js rename to examples/simple/meteor.js diff --git a/lib/breadcrumb.js b/lib/breadcrumb.js index 4ed8f20..0c9d4e0 100644 --- a/lib/breadcrumb.js +++ b/lib/breadcrumb.js @@ -2,83 +2,82 @@ var privateVar; String.prototype.capitalize = function() { - return this.replace(/(?:^|\s)\S/g, function(a) { return a.toUpperCase(); }); + return this.replace(/(?:^|\s)\S/g, function(a) { return a.toUpperCase(); }); }; var enrichRouteObject = function(path, isCurrent) { - // replace all parameters in the title - var title = Router.routes[path].options.title; - if ('function' === typeof title) - title = Router.routes[path].options.title(); - var params = Router.current().params; - if(title) { - for (var i in params) { - title = title.replace( - new RegExp((':'+i).replace(/\+/g, "\\+"), "g"), params[i]); - } - if (!Router.routes[path].options.noCaps) - title = title.capitalize(); - } else { - title = 'This page has no title'; - + // replace all parameters in the title + var routeOptions = Router.routes[path] && Router.routes[path].options; + var title = (routeOptions && routeOptions.hasOwnProperty('title')) ? routeOptions.title : Router.options.defaultBreadcrumbTitle; + if ('function' === typeof title) + title = _.bind(title, Router.current())(); + var params = Router.current().params; + if (title) { + for (var i in params) { + title = title && title.replace( + new RegExp((':'+i).replace(/\+/g, "\\+"), "g"), params[i]); } + if (!Router.routes[path].options.noCaps) + title = title && title.capitalize(); + } else { + title = null; - if(isCurrent) { - cssClasses = 'active'; - } else { - cssClasses = ''; - } + } - return { - 'path': path, - 'params': params, - 'title': title, - 'cssClasses': cssClasses, - 'url': Router.routes[path].path(Router.current().params), - 'route': Router.routes[path] - } + if(isCurrent) { + cssClasses = 'active'; + } else { + cssClasses = ''; + } + + if (title) return { + 'path': path, + 'params': params, + 'title': title, + 'cssClasses': cssClasses, + 'url': Router.routes[path].path(Router.current().params), + 'route': Router.routes[path] + } } var getAllParents = function() { - if(Router.current().route) { - var current = Router.current().route.getName(); - var parent = Router.current().route.options.parent; - if(parent) { - return getParentParent([enrichRouteObject(current,true),enrichRouteObject(parent)]); + if(Router.current().route) { + var current = Router.current().route.getName(); + var parent = Router.current().route.options.hasOwnProperty('parent') ? Router.current().route.options.parent : Router.options.parent; + if ('function' === typeof parent) + parent = _.bind(parent, Router.current())() - // console.log(Router.routes[parent].path()); // working to the URL rendered for current path - // console.log(Router.routes['discover.region'].path({'_name':'east'})); // working to the URL rendered for current path - // console.log(Router.routes); // will list all routes - } else { - return [enrichRouteObject(current)]; - } + if(parent) { + return getParentParent([enrichRouteObject(current,true),enrichRouteObject(parent)]); } else { - // no routes have been specified - return []; + return [enrichRouteObject(current)]; } + } else { + // no routes have been specified + return []; + } } // parents must be always an array var getParentParent = function(parents) { - // console.log(parents); - if(newParent = Router.routes[parents[parents.length-1].path].options.parent) { - parents.push(enrichRouteObject(newParent)) - return getParentParent(parents); - } else { - return parents; - } + var lastParent = parents[parents.length-1]; + if(newParent = (lastParent && Router.routes[lastParent.path].options.parent)) { + if ('function' === typeof newParent) + newParent = _.bind(newParent, Router.current())() + parents.push(enrichRouteObject(newParent)) + return getParentParent(parents); + } else { + return parents; + } } Breadcrumb = { - hello: function() { - return 'hello'; - }, getAll: function() { - return getAllParents().reverse(); + return _.compact(getAllParents()).reverse(); } }; UI.registerHelper('Breadcrumb', function(template) { return Breadcrumb.getAll(); -}); \ No newline at end of file +}); diff --git a/package.js b/package.js index b45bede..1d743da 100644 --- a/package.js +++ b/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'monbro:iron-router-breadcrumb', summary: 'This package will provide a easy way to add a breadcrumb to Iron.Router with enough flexibility.', - version: '1.0.7', + version: '1.0.8', git: 'https://github.com/monbro/meteor-breadcrumb-plugin/' }); @@ -17,6 +17,7 @@ function configurePackage(api) { 'blaze@2.0.0', 'templating@1.0.5', 'ui', + 'underscore', 'meteor' ] );