Skip to content
This repository has been archived by the owner on Aug 30, 2021. It is now read-only.

Commit

Permalink
feat (title): Dynamic Title: Improve SEO
Browse files Browse the repository at this point in the history
  • Loading branch information
itelo committed Feb 10, 2016
1 parent e24fd27 commit 49f6a83
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 41 deletions.
14 changes: 11 additions & 3 deletions modules/articles/client/config/articles.client.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
url: '',
templateUrl: 'modules/articles/client/views/list-articles.client.view.html',
controller: 'ArticlesListController',
controllerAs: 'vm'
controllerAs: 'vm',
data: {
pageTitle: 'Articles List'
}
})
.state('articles.create', {
url: '/create',
Expand All @@ -29,7 +32,8 @@
articleResolve: newArticle
},
data: {
roles: ['user', 'admin']
roles: ['user', 'admin'],
pageTitle : 'Articles Create'
}
})
.state('articles.edit', {
Expand All @@ -41,7 +45,8 @@
articleResolve: getArticle
},
data: {
roles: ['user', 'admin']
roles: ['user', 'admin'],
pageTitle: 'Edit Article {{ articleResolve.title }}'
}
})
.state('articles.view', {
Expand All @@ -51,6 +56,9 @@
controllerAs: 'vm',
resolve: {
articleResolve: getArticle
},
data:{
pageTitle: 'Article {{ articleResolve.title }}'
}
});
}
Expand Down
3 changes: 2 additions & 1 deletion modules/chat/client/config/chat.client.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
controller: 'ChatController',
controllerAs: 'vm',
data: {
roles: ['user', 'admin']
roles: ['user', 'admin'],
pageTitle: 'Chat'
}
});
}
Expand Down
53 changes: 28 additions & 25 deletions modules/core/client/config/core.client.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,33 @@ angular.module('core').config(['$stateProvider', '$urlRouterProvider',

// Home state routing
$stateProvider
.state('home', {
url: '/',
templateUrl: 'modules/core/client/views/home.client.view.html'
})
.state('not-found', {
url: '/not-found',
templateUrl: 'modules/core/client/views/404.client.view.html',
data: {
ignoreState: true
}
})
.state('bad-request', {
url: '/bad-request',
templateUrl: 'modules/core/client/views/400.client.view.html',
data: {
ignoreState: true
}
})
.state('forbidden', {
url: '/forbidden',
templateUrl: 'modules/core/client/views/403.client.view.html',
data: {
ignoreState: true
}
});
.state('home', {
url: '/',
templateUrl: 'modules/core/client/views/home.client.view.html'
})
.state('not-found', {
url: '/not-found',
templateUrl: 'modules/core/client/views/404.client.view.html',
data: {
ignoreState: true,
pageTitle: 'Not-Found'
}
})
.state('bad-request', {
url: '/bad-request',
templateUrl: 'modules/core/client/views/400.client.view.html',
data: {
ignoreState: true,
pageTitle: 'Bad-Request'
}
})
.state('forbidden', {
url: '/forbidden',
templateUrl: 'modules/core/client/views/403.client.view.html',
data: {
ignoreState: true,
pageTitle: 'Forbidden'
}
});
}
]);
40 changes: 40 additions & 0 deletions modules/core/client/directives/page-title.client.directives.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
(function () {
'use strict';

angular.module('core')
.directive('pageTitle', pageTitle);

pageTitle.$inject = ['$rootScope', '$timeout', '$interpolate', '$state'];

function pageTitle($rootScope, $timeout, $interpolate, $state) {
var directive = {
retrict: 'A',
link: link
};

return directive;

function link(scope, element) {
$rootScope.$on('$stateChangeSuccess', listener);

function listener(event, toState) {
var title = (getTitle($state.$current));
$timeout(function () {
element.text(title);
}, 0, false);
}

function getTitle(currentState) {
var applicationCoreTitle = 'MEAN.js';
var workingState = currentState;
if (currentState.data) {
workingState = (typeof workingState.locals !== 'undefined') ? workingState.locals.globals : workingState;
var stateTitle = $interpolate(currentState.data.pageTitle)(workingState);
return applicationCoreTitle + ' - ' + stateTitle;
} else {
return applicationCoreTitle;
}
}
}
}
})();
2 changes: 1 addition & 1 deletion modules/core/server/views/layout.server.view.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1">
<base href="/">
<title>{{title}}</title>
<title page-title></title>
<meta name="description" content="{{description}}">
<meta name="fragment" content="!">

Expand Down
11 changes: 10 additions & 1 deletion modules/users/client/config/users-admin.client.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ angular.module('users.admin.routes').config(['$stateProvider',
.state('admin.users', {
url: '/users',
templateUrl: 'modules/users/client/views/admin/list-users.client.view.html',
controller: 'UserListController'
controller: 'UserListController',
data: {
pageTitle: 'Users List'
}
})
.state('admin.user', {
url: '/users/:userId',
Expand All @@ -19,6 +22,9 @@ angular.module('users.admin.routes').config(['$stateProvider',
userId: $stateParams.userId
});
}]
},
data: {
pageTitle: 'Edit {{ userResolve.displayName }}'
}
})
.state('admin.user-edit', {
Expand All @@ -31,6 +37,9 @@ angular.module('users.admin.routes').config(['$stateProvider',
userId: $stateParams.userId
});
}]
},
data: {
pageTitle: 'Edit User {{ userResolve.displayName }}'
}
});
}
Expand Down
50 changes: 40 additions & 10 deletions modules/users/client/config/users.client.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,31 @@ angular.module('users').config(['$stateProvider',
})
.state('settings.profile', {
url: '/profile',
templateUrl: 'modules/users/client/views/settings/edit-profile.client.view.html'
templateUrl: 'modules/users/client/views/settings/edit-profile.client.view.html',
data: {
pageTitle: 'Settings'
}
})
.state('settings.password', {
url: '/password',
templateUrl: 'modules/users/client/views/settings/change-password.client.view.html'
templateUrl: 'modules/users/client/views/settings/change-password.client.view.html',
data: {
pageTitle: 'Settings password'
}
})
.state('settings.accounts', {
url: '/accounts',
templateUrl: 'modules/users/client/views/settings/manage-social-accounts.client.view.html'
templateUrl: 'modules/users/client/views/settings/manage-social-accounts.client.view.html',
data: {
pageTitle: 'Settings accounts'
}
})
.state('settings.picture', {
url: '/picture',
templateUrl: 'modules/users/client/views/settings/change-profile-picture.client.view.html'
templateUrl: 'modules/users/client/views/settings/change-profile-picture.client.view.html',
data: {
pageTitle: 'Settings picture'
}
})
.state('authentication', {
abstract: true,
Expand All @@ -36,11 +48,17 @@ angular.module('users').config(['$stateProvider',
})
.state('authentication.signup', {
url: '/signup',
templateUrl: 'modules/users/client/views/authentication/signup.client.view.html'
templateUrl: 'modules/users/client/views/authentication/signup.client.view.html',
data: {
pageTitle: 'Signup'
}
})
.state('authentication.signin', {
url: '/signin?err',
templateUrl: 'modules/users/client/views/authentication/signin.client.view.html'
templateUrl: 'modules/users/client/views/authentication/signin.client.view.html',
data: {
pageTitle: 'Signin'
}
})
.state('password', {
abstract: true,
Expand All @@ -49,7 +67,10 @@ angular.module('users').config(['$stateProvider',
})
.state('password.forgot', {
url: '/forgot',
templateUrl: 'modules/users/client/views/password/forgot-password.client.view.html'
templateUrl: 'modules/users/client/views/password/forgot-password.client.view.html',
data: {
pageTitle: 'Password forgot'
}
})
.state('password.reset', {
abstract: true,
Expand All @@ -58,15 +79,24 @@ angular.module('users').config(['$stateProvider',
})
.state('password.reset.invalid', {
url: '/invalid',
templateUrl: 'modules/users/client/views/password/reset-password-invalid.client.view.html'
templateUrl: 'modules/users/client/views/password/reset-password-invalid.client.view.html',
data: {
pageTitle: 'Password reset invalid'
}
})
.state('password.reset.success', {
url: '/success',
templateUrl: 'modules/users/client/views/password/reset-password-success.client.view.html'
templateUrl: 'modules/users/client/views/password/reset-password-success.client.view.html',
data: {
pageTitle: 'Password reset success'
}
})
.state('password.reset.form', {
url: '/:token',
templateUrl: 'modules/users/client/views/password/reset-password.client.view.html'
templateUrl: 'modules/users/client/views/password/reset-password.client.view.html',
data: {
pageTitle: 'Password reset form'
}
});
}
]);

3 comments on commit 49f6a83

@trendzetter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change requires you to add a pageTitle to each ui router route when porting existing modules.

Error: text is undefined
$interpolate@http://localhost:3000/lib/angular/angular.js:11739:11
getTitle@http://localhost:3000/modules/core/client/directives/page-title.client.directives.js:32:28

@itelo
Copy link
Contributor Author

@itelo itelo commented on 49f6a83 Feb 16, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in directive page-title,

if (currentState.data)

should be

if (currentState.data.pageTitle)

?

@trendzetter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I will test that tonight. Would make the property optional as was intended in the first place.

Please sign in to comment.