update application and repository views to set <meta> description to improve search results
This commit is contained in:
parent
21ecc2eadd
commit
a9c2ea608d
7 changed files with 65 additions and 52 deletions
|
@ -10,7 +10,7 @@
|
||||||
});
|
});
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
function AppViewCtrl($scope, $routeParams, $location, $timeout, ApiService, UserService, AngularPollChannel, ImageLoaderService, CookieService) {
|
function AppViewCtrl($scope, $routeParams, $rootScope, ApiService, UtilService) {
|
||||||
$scope.namespace = $routeParams.namespace;
|
$scope.namespace = $routeParams.namespace;
|
||||||
$scope.name = $routeParams.name;
|
$scope.name = $routeParams.name;
|
||||||
|
|
||||||
|
@ -29,8 +29,13 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.repositoryResource = ApiService.getRepoAsResource(params).get(function(repo) {
|
$scope.repositoryResource = ApiService.getRepoAsResource(params).get(function(repo) {
|
||||||
|
if (repo != undefined) {
|
||||||
$scope.repository = repo;
|
$scope.repository = repo;
|
||||||
$scope.viewScope.repository = repo;
|
$scope.viewScope.repository = repo;
|
||||||
|
|
||||||
|
// Update the page description for SEO
|
||||||
|
$rootScope.description = UtilService.getFirstMarkdownLineAsString(repo.description);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
});
|
});
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
function RepoViewCtrl($scope, $routeParams, $location, $timeout, ApiService, UserService, AngularPollChannel, ImageLoaderService, CookieService) {
|
function RepoViewCtrl($scope, $routeParams, $rootScope, $timeout, ApiService,
|
||||||
|
UserService, AngularPollChannel, ImageLoaderService, UtilService) {
|
||||||
$scope.namespace = $routeParams.namespace;
|
$scope.namespace = $routeParams.namespace;
|
||||||
$scope.name = $routeParams.name;
|
$scope.name = $routeParams.name;
|
||||||
|
|
||||||
|
@ -59,15 +60,14 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.repositoryResource = ApiService.getRepoAsResource(params).get(function(repo) {
|
$scope.repositoryResource = ApiService.getRepoAsResource(params).get(function(repo) {
|
||||||
|
if (repo != undefined) {
|
||||||
$scope.repository = repo;
|
$scope.repository = repo;
|
||||||
$scope.viewScope.repository = repo;
|
$scope.viewScope.repository = repo;
|
||||||
$scope.publicRepoExperiment = CookieService.get('quay.public-repo-exp') == 'true';
|
|
||||||
|
|
||||||
// Flag for new repo page experiment
|
// Update the page description for SEO
|
||||||
$scope.newRepoExperiment = $scope.repository.is_public && $scope.user.username != $scope.repository.namespace && $scope.publicRepoExperiment;
|
$rootScope.description = UtilService.getFirstMarkdownLineAsString(repo.description);
|
||||||
|
|
||||||
// Load the remainder of the data async, so we don't block the initial view from
|
// Load the remainder of the data async, so we don't block the initial view from showing
|
||||||
// showing.
|
|
||||||
$timeout(function() {
|
$timeout(function() {
|
||||||
$scope.setTags($routeParams.tag);
|
$scope.setTags($routeParams.tag);
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@
|
||||||
buildPollChannel = AngularPollChannel.create($scope, loadRepositoryBuilds, 30000 /* 30s */);
|
buildPollChannel = AngularPollChannel.create($scope, loadRepositoryBuilds, 30000 /* 30s */);
|
||||||
buildPollChannel.start();
|
buildPollChannel.start();
|
||||||
}, 10);
|
}, 10);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,21 +16,21 @@ provideRun.$inject = [
|
||||||
'MetaService',
|
'MetaService',
|
||||||
];
|
];
|
||||||
export function provideRun($rootScope: QuayRunScope,
|
export function provideRun($rootScope: QuayRunScope,
|
||||||
Restangular: any,
|
restangular: any,
|
||||||
PlanService: any,
|
planService: any,
|
||||||
$http: ng.IHttpService,
|
$http: ng.IHttpService,
|
||||||
CookieService: any,
|
cookieService: any,
|
||||||
Features: any,
|
features: any,
|
||||||
$anchorScroll: ng.IAnchorScrollService,
|
$anchorScroll: ng.IAnchorScrollService,
|
||||||
MetaService: any): void {
|
metaService: any): void {
|
||||||
const defaultTitle: string = INJECTED_CONFIG['REGISTRY_TITLE'] || 'Quay Container Registry';
|
const defaultTitle: string = INJECTED_CONFIG['REGISTRY_TITLE'] || 'Quay Container Registry';
|
||||||
|
|
||||||
// Handle session security.
|
// Handle session security.
|
||||||
Restangular.setDefaultRequestParams(['post', 'put', 'remove', 'delete'],
|
restangular.setDefaultRequestParams(['post', 'put', 'remove', 'delete'],
|
||||||
{'_csrf_token': (<any>window).__token || ''});
|
{'_csrf_token': (<any>window).__token || ''});
|
||||||
|
|
||||||
// Handle session expiration.
|
// Handle session expiration.
|
||||||
Restangular.setErrorInterceptor(function(response) {
|
restangular.setErrorInterceptor(function(response) {
|
||||||
if (response !== undefined && response.status == 503) {
|
if (response !== undefined && response.status == 503) {
|
||||||
(<any>$('#cannotContactService')).modal({});
|
(<any>$('#cannotContactService')).modal({});
|
||||||
return false;
|
return false;
|
||||||
|
@ -59,20 +59,20 @@ export function provideRun($rootScope: QuayRunScope,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check if we need to redirect based on a previously chosen plan.
|
// Check if we need to redirect based on a previously chosen plan.
|
||||||
const result: boolean = PlanService.handleNotedPlan();
|
const result: boolean = planService.handleNotedPlan();
|
||||||
|
|
||||||
// Check to see if we need to show a redirection page.
|
// Check to see if we need to show a redirection page.
|
||||||
const redirectUrl: string = CookieService.get('quay.redirectAfterLoad');
|
const redirectUrl: string = cookieService.get('quay.redirectAfterLoad');
|
||||||
CookieService.clear('quay.redirectAfterLoad');
|
cookieService.clear('quay.redirectAfterLoad');
|
||||||
|
|
||||||
if (!result && redirectUrl && redirectUrl.indexOf((<any>window).location.href) == 0) {
|
if (!result && redirectUrl && redirectUrl.indexOf((<any>window).location.href) == 0) {
|
||||||
(<any>window).location = redirectUrl;
|
(<any>window).location = redirectUrl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$rootScope.$watch('description', function(description: string) {
|
$rootScope.$watch('description', (description: string) => {
|
||||||
if (!description) {
|
if (!description) {
|
||||||
description = `Hosted private docker repositories. Includes full user management and history.
|
description = `Hosted private Docker repositories. Includes full user management and history.
|
||||||
Free for public repositories.`;
|
Free for public repositories.`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,18 +82,7 @@ export function provideRun($rootScope: QuayRunScope,
|
||||||
$('#descriptionTag').attr('content', description);
|
$('#descriptionTag').attr('content', description);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Listen for scope changes and update the title and description accordingly.
|
$rootScope.$on('$routeChangeSuccess', (event, current, previous) => {
|
||||||
$rootScope.$watch(function() {
|
|
||||||
const title: string = MetaService.getTitle($rootScope.currentPage) || defaultTitle;
|
|
||||||
$rootScope.title = title;
|
|
||||||
|
|
||||||
const description: string = MetaService.getDescription($rootScope.currentPage) || '';
|
|
||||||
if ($rootScope.description != description) {
|
|
||||||
$rootScope.description = description;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$rootScope.$on('$routeChangeSuccess', function(event, current, previous) {
|
|
||||||
$rootScope.current = current.$$route;
|
$rootScope.current = current.$$route;
|
||||||
$rootScope.currentPage = current;
|
$rootScope.currentPage = current;
|
||||||
$rootScope.pageClass = '';
|
$rootScope.pageClass = '';
|
||||||
|
@ -102,7 +91,7 @@ export function provideRun($rootScope: QuayRunScope,
|
||||||
|
|
||||||
var pageClass: string | Function = current.$$route.pageClass || '';
|
var pageClass: string | Function = current.$$route.pageClass || '';
|
||||||
if (typeof pageClass != 'string') {
|
if (typeof pageClass != 'string') {
|
||||||
pageClass = pageClass(Features);
|
pageClass = pageClass(features);
|
||||||
}
|
}
|
||||||
|
|
||||||
$rootScope.pageClass = pageClass;
|
$rootScope.pageClass = pageClass;
|
||||||
|
@ -112,6 +101,16 @@ export function provideRun($rootScope: QuayRunScope,
|
||||||
$anchorScroll();
|
$anchorScroll();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Listen for route changes and update the title and description accordingly.
|
||||||
|
$rootScope.$on('$routeChangeSuccess', async(event, current, previous) => {
|
||||||
|
$rootScope.title = metaService.getTitle(current) || defaultTitle;
|
||||||
|
|
||||||
|
const description = await metaService.getDescription(current);
|
||||||
|
if ($rootScope.description != description) {
|
||||||
|
$rootScope.description = description;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var initallyChecked: boolean = false;
|
var initallyChecked: boolean = false;
|
||||||
(<any>window).__isLoading = function() {
|
(<any>window).__isLoading = function() {
|
||||||
if (!initallyChecked) {
|
if (!initallyChecked) {
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* Service which helps set the contents of the <meta> tags (and the <title> of a page).
|
* Service which helps set the contents of the <meta> tags (and the <title> of a page).
|
||||||
*/
|
*/
|
||||||
angular.module('quay').factory('MetaService', ['$interpolate', 'Config', '$rootScope', '$interval',
|
angular.module('quay').factory('MetaService', ['$interpolate', '$timeout', function($interpolate, $timeout) {
|
||||||
function($interpolate, Config, $rootScope, $interval) {
|
|
||||||
var metaService = {};
|
var metaService = {};
|
||||||
|
|
||||||
var interpolate = function(page, expr) {
|
var interpolate = function(page, expr) {
|
||||||
|
@ -28,12 +27,16 @@ angular.module('quay').factory('MetaService', ['$interpolate', 'Config', '$rootS
|
||||||
};
|
};
|
||||||
|
|
||||||
metaService.getDescription = function(page) {
|
metaService.getDescription = function(page) {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
if (!page || !page.$$route) {
|
if (!page || !page.$$route) {
|
||||||
return null;
|
resolve(null);
|
||||||
|
} else {
|
||||||
|
// Timeout needed because page.scope is undefined
|
||||||
|
$timeout(function() {
|
||||||
|
resolve(interpolate(page, page.$$route.description));
|
||||||
|
}, 10);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
var route = page.$$route;
|
|
||||||
return interpolate(route && route.description);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return metaService;
|
return metaService;
|
||||||
|
|
|
@ -75,6 +75,11 @@ angular.module('quay').factory('UtilService', ['$sanitize', 'markdownConverterFa
|
||||||
return '';
|
return '';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
utilService.getFirstMarkdownLineAsString = function(commentString) {
|
||||||
|
return utilService.getFirstMarkdownLineAsText(commentString, false).replace('</p>', '')
|
||||||
|
.replace('<p>', '');
|
||||||
|
};
|
||||||
|
|
||||||
utilService.escapeHtmlString = function(text) {
|
utilService.escapeHtmlString = function(text) {
|
||||||
var textStr = (text || '').toString();
|
var textStr = (text || '').toString();
|
||||||
var adjusted = textStr.replace(/&/g, "&")
|
var adjusted = textStr.replace(/&/g, "&")
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
{% block added_meta %}
|
{% block added_meta %}
|
||||||
<base href="/">
|
<base href="/">
|
||||||
|
|
||||||
<meta id="descriptionTag" name="description" content="Quay is the best place to build, store, and distribute your containers. Public repositories are always free."></meta>
|
<meta id="descriptionTag" name="description" content="Quay is the best place to build, store, and distribute your containers. Public repositories are always free." />
|
||||||
<meta name="google-site-verification" content="GalDznToijTsHYmLjJvE4QaB9uk_IP16aaGDz5D75T4" />
|
<meta name="google-site-verification" content="GalDznToijTsHYmLjJvE4QaB9uk_IP16aaGDz5D75T4" />
|
||||||
<meta name="google-site-verification" content="oio7ioMILUo9QDflvyFz8pWig1ac2eLq5IGyQuzFMh8" />
|
<meta name="google-site-verification" content="oio7ioMILUo9QDflvyFz8pWig1ac2eLq5IGyQuzFMh8" />
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ var config = {
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.ts?$/,
|
test: /\.ts$/,
|
||||||
use: ["ts-loader"],
|
use: ["ts-loader"],
|
||||||
exclude: /node_modules/
|
exclude: /node_modules/
|
||||||
},
|
},
|
||||||
|
|
Reference in a new issue