-
Notifications
You must be signed in to change notification settings - Fork 42
Branding Phase 2 - Provider Domains [PREP-259] #201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4807b45
45ca1fb
ad2668a
2e8f4da
f226122
b671199
8f8d242
3499073
3d0b1eb
3041db0
09bb9a1
f28a3a4
c9cd22c
d238433
287a2e7
2b48c33
f723673
2d198ca
e8fd5f3
868ef36
d211a46
ea435ad
8e96e60
1f72e0c
2cc81a8
8d3b63c
eb2a309
21e2f19
1e6a1d7
b29b85f
867774c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| import Ember from 'ember'; | ||
| import Analytics from '../mixins/analytics'; | ||
|
|
||
| export default Ember.Component.extend(Analytics, { | ||
| theme: Ember.inject.service(), | ||
| classNames: ['preprint-error-page'], | ||
| label: '', | ||
| translationKey: '', | ||
| supportEmail: Ember.computed('theme.isProvider', 'theme.provider.emailSupport', function() { | ||
| return this.get('theme.isProvider') ? this.get('theme.provider.emailSupport') : 'support@osf.io'; | ||
| }) | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import Ember from 'ember'; | ||
|
|
||
| /** | ||
| * @module ember-preprints | ||
| * @submodule helpers | ||
| */ | ||
|
|
||
| /** | ||
| * Needed for link-to for branded routing to get the correct route path | ||
| * | ||
| * @class route-prefix | ||
| */ | ||
| export default Ember.Helper.extend({ | ||
| theme: Ember.inject.service(), | ||
|
|
||
| onSubRouteChange: Ember.observer('theme.isSubRoute', function() { | ||
| this.recompute(); | ||
| }), | ||
|
|
||
| compute(params) { | ||
| const route = params.join(''); | ||
|
|
||
| return this.get('theme.isSubRoute') ? `provider.${route}` : route; | ||
| } | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,37 @@ | ||
| import Ember from 'ember'; | ||
| import config from 'ember-get-config'; | ||
|
|
||
| const {hostname} = window.location; | ||
|
|
||
| const provider = config | ||
| .PREPRINTS | ||
| .providers | ||
| // Exclude OSF | ||
| .slice(1) | ||
| // Filter out providers without a domain | ||
| .filter(p => p.domain) | ||
| .find(p => | ||
| // Check if the hostname includes: the domain, the domain with dashes instead of periods, or just the id | ||
| hostname.includes(p.domain) || | ||
| hostname.includes(p.domain.replace(/\./g, '-')) || | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When is this relevant, out of curiosity?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had a conversation with @icereval a while back about how we might deploy this on staging/test. |
||
| hostname.includes(p.id) | ||
| ); | ||
|
|
||
| const Router = Ember.Router.extend({ | ||
| location: config.locationType, | ||
| rootURL: config.rootURL, | ||
| metrics: Ember.inject.service(), | ||
| theme: Ember.inject.service(), | ||
|
|
||
| init() { | ||
| this._super(...arguments); | ||
|
|
||
| if (provider) { | ||
| this.set('theme.id', provider.id); | ||
| this.set('theme.isDomain', true); | ||
| } | ||
| }, | ||
|
|
||
| didTransition() { | ||
| this._super(...arguments); | ||
| this._trackPage(); | ||
|
|
@@ -25,17 +50,25 @@ const Router = Ember.Router.extend({ | |
|
|
||
| Router.map(function() { | ||
| this.route('page-not-found', {path: '/*bad_url'}); | ||
| this.route('index', {path: 'preprints'}); | ||
| this.route('page-not-found', {path: 'preprints/page-not-found'}); | ||
| this.route('submit', {path: 'preprints/submit'}); | ||
| this.route('discover', {path: 'preprints/discover'}); | ||
| this.route('content', {path: '/:preprint_id' }); | ||
| this.route('provider', {path: 'preprints/:slug'}, function() { | ||
| this.route('content', {path: '/:preprint_id'}); | ||
| this.route('discover'); | ||
|
|
||
| if (provider) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does provider get recalculated properly when window.location changes? I would assume it does, since it works, but it seems weird that a const value changed would cause this Router.map to be rerun, assuming the preprint app is still a singleton across the different providers
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since changing the provider requires a full page reload, the entire app, including the router, will be evaluated each time. |
||
| this.route('index', {path: '/'}); | ||
| this.route('submit'); | ||
| this.route('discover'); | ||
| this.route('page-not-found'); | ||
| }); | ||
| } else { | ||
| this.route('index', {path: 'preprints'}); | ||
| this.route('submit', {path: 'preprints/submit'}); | ||
| this.route('discover', {path: 'preprints/discover'}); | ||
| this.route('provider', {path: 'preprints/:slug'}, function () { | ||
| this.route('content', {path: '/:preprint_id'}); | ||
| this.route('discover'); | ||
| this.route('submit'); | ||
| }); | ||
| this.route('page-not-found', {path: 'preprints/page-not-found'}); | ||
| } | ||
|
|
||
| this.route('content', {path: '/:preprint_id'}); | ||
| this.route('forbidden'); | ||
| this.route('resource-deleted'); | ||
| }); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,9 @@ import Analytics from '../mixins/analytics'; | |
| import config from 'ember-get-config'; | ||
| import loadAll from 'ember-osf/utils/load-relationship'; | ||
| import permissions from 'ember-osf/const/permissions'; | ||
| import getRedirectUrl from '../utils/get-redirect-url'; | ||
|
|
||
| const providers = config.PREPRINTS.providers; | ||
|
|
||
| // Error handling for API | ||
| const handlers = new Map([ | ||
|
|
@@ -67,7 +70,7 @@ export default Ember.Route.extend(Analytics, ResetScrollMixin, SetupSubmitContro | |
| }, | ||
| afterModel(preprint) { | ||
| const {origin, search} = window.location; | ||
| let contributors = Ember.A(); | ||
| const contributors = Ember.A(); | ||
|
|
||
| return preprint.get('provider') | ||
| .then(provider => { | ||
|
|
@@ -82,20 +85,30 @@ export default Ember.Route.extend(Analytics, ResetScrollMixin, SetupSubmitContro | |
| preprint.get('node') | ||
| ]); | ||
|
|
||
| // Otherwise, redirect to the proper branded site. | ||
| // Hard redirect instead of transition, in anticipation of Phase 2 where providers will have their own domains. | ||
| const urlParts = [ | ||
| origin | ||
| ]; | ||
| // Otherwise, find the correct provider and redirect | ||
| const configProvider = providers.find(p => p.id === providerId); | ||
|
|
||
| if (!configProvider) | ||
| throw new Error('Provider is not configured properly. Check the Ember configuration.'); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There does not appear to be any .catch statement associated with this promise. (aside from whatever ember will do internally if the afterModel hook returns a rejected promise)
|
||
|
|
||
| if (!isOSF) | ||
| urlParts.push('preprints', providerId); | ||
| const {domain} = configProvider; | ||
| const urlParts = []; | ||
|
|
||
| urlParts.push(preprint.get('id'), search); | ||
| // Provider with a domain | ||
| if (this.get('theme.isDomain') || domain) { | ||
| urlParts.push(getRedirectUrl(window.location, domain)); | ||
| // Provider without a domain | ||
| } else { | ||
| urlParts.push(origin); | ||
|
|
||
| const url = urlParts.join('/'); | ||
| if (!isOSF) | ||
| urlParts.push('preprints', providerId); | ||
|
|
||
| urlParts.push(preprint.get('id')); | ||
| } | ||
|
|
||
| window.history.replaceState({}, document.title, url); | ||
| urlParts.push(search); | ||
| const url = urlParts.join('/').replace(/\/\/$/, '/'); | ||
| window.location.replace(url); | ||
|
|
||
| return Promise.reject(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,9 @@ | ||
| import Ember from 'ember'; | ||
| import config from 'ember-get-config'; | ||
| import getRedirectUrl from '../utils/get-redirect-url'; | ||
|
|
||
| const providers = config.PREPRINTS.providers.slice(1); | ||
| const providerIds = providers.map(p => p.id); | ||
|
|
||
| /** | ||
| * @module ember-preprints | ||
|
|
@@ -12,19 +16,28 @@ import config from 'ember-get-config'; | |
| export default Ember.Route.extend({ | ||
| theme: Ember.inject.service(), | ||
|
|
||
| providerIds: config.PREPRINTS.providers | ||
| .slice(1) | ||
| .map(provider => provider.id), | ||
|
|
||
| beforeModel(transition) { | ||
| const {slug} = transition.params.provider; | ||
| const slugLower = (slug || '').toLowerCase(); | ||
|
|
||
| if (this.get('providerIds').includes(slugLower)) { | ||
| if (providerIds.includes(slugLower)) { | ||
| const {domain} = providers.find(provider => provider.id === slugLower) || {}; | ||
|
|
||
| // This should be caught by the proxy, but we'll redirect just in case it is not. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note to self: "the proxy" refers to nginx handling domain redirect (before it hits ember) |
||
| if (domain) { | ||
| window.location.replace( | ||
| getRedirectUrl(window.location, domain, slug) | ||
| ); | ||
|
|
||
| return; | ||
| } | ||
|
|
||
| if (slugLower !== slug) { | ||
| const {pathname} = window.location; | ||
| const pathRegex = new RegExp(`^/preprints/${slug}`); | ||
|
|
||
| window.location.pathname = pathname.replace( | ||
| new RegExp(`^/preprints/${slug}`), | ||
| pathRegex, | ||
| `/preprints/${slugLower}` | ||
| ); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this something we really need to expose to translations?
If the goal is only to DRY this code, consider using the ember-page-title addon config:
https://github.com/tim-evans/ember-page-title#api