Skip to content

Feature/2010 seo friendly urls dynroutes #2446

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

Merged
merged 67 commits into from
Mar 5, 2019
Merged
Show file tree
Hide file tree
Changes from 59 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
4fb53e5
PoC - multipart, dynamic URL rewrite
pkarw Feb 8, 2019
a2f3405
Logger fixes + url mapping
pkarw Feb 12, 2019
e499ac5
Error handling on URL dispatcher
pkarw Feb 12, 2019
a365f4b
Product route links + error handling improvements
pkarw Feb 12, 2019
baddb48
Further works on UrlDispatcher - including route params
pkarw Feb 12, 2019
97d28a8
Update actions.ts
pkarw Feb 12, 2019
ff0a6ab
Further works on URL - Product + Category page refactor + hydrate pos…
pkarw Feb 13, 2019
648fd76
WIP - document.location as a workaround for same route redirects
pkarw Feb 14, 2019
3d89013
Source maps added, UrlClientDispatcher added
pkarw Feb 15, 2019
0d28943
preAsyncData action support added to UrlClientDispatcher + breadcrumb…
pkarw Feb 15, 2019
f9f73c8
Category links
pkarw Feb 15, 2019
3885e6a
Departments menu removed from Footer
pkarw Feb 15, 2019
426d37e
product/list extended for registerMapping
pkarw Feb 15, 2019
8c359d2
category/list extended with dispatcher mapping registration
pkarw Feb 15, 2019
3136e65
PoC of Url dispatcher using dynamic routing
pkarw Feb 16, 2019
9900d27
Tests + SSR Fixes
pkarw Feb 17, 2019
17191ae
References to config.seo.useUrlDispatcher limited to url module
pkarw Feb 17, 2019
726e21a
Minor fixes
pkarw Feb 17, 2019
e9bd1d1
Merge branch 'develop' into feature/2010_seo_friendly_urls_dynroutes
filrak Feb 20, 2019
cc078dd
Update core/lib/multistore.ts
patzick Feb 22, 2019
92bb3da
Code Review changes applied (thanks @patzick)
pkarw Feb 22, 2019
2d23a86
Further works on multistore support
pkarw Feb 22, 2019
b01a5a0
multistore support - WIP
pkarw Feb 23, 2019
8920978
multistore support WIP
pkarw Feb 23, 2019
c0c55aa
Multistore tests + query-string
pkarw Feb 23, 2019
c5450d9
Update CHANGELOG.md
pkarw Feb 23, 2019
9847f06
config.seo.useUrlDisaptcher is default to false now
pkarw Feb 23, 2019
bbc1a8e
Docs added
pkarw Feb 23, 2019
ca2606f
Fixed error handler
pkarw Feb 23, 2019
3b290cf
Update beforeEach.ts
pkarw Feb 23, 2019
cbf7b52
Merge branch 'develop' into feature/2010_seo_friendly_urls_dynroutes
pkarw Feb 23, 2019
f25521b
Error handler FIX
pkarw Feb 23, 2019
2af3f1c
Merge branch 'feature/2010_seo_friendly_urls_dynroutes' of https://gi…
pkarw Feb 23, 2019
94640ce
@vue-storefront/store is depreciated -> fixed reference
pkarw Feb 23, 2019
eed5c18
Merge branch 'develop' into feature/2010_seo_friendly_urls_dynroutes
pkarw Feb 24, 2019
3a4d43c
Update core/modules/url/router/beforeEach.ts
patzick Feb 24, 2019
34666aa
Update core/modules/url/helpers/index.ts
patzick Feb 24, 2019
26dca41
Update logger.ts
pkarw Feb 24, 2019
91ef98c
Merge branch 'feature/2010_seo_friendly_urls_dynroutes' of https://gi…
pkarw Feb 24, 2019
84046cf
CR fixes
pkarw Feb 24, 2019
53fc80d
Update core/modules/url/store/actions.ts
patzick Feb 24, 2019
86a9046
CR review fixes
pkarw Feb 24, 2019
0033928
Merge branch 'develop' into feature/2010_seo_friendly_urls_dynroutes
pkarw Feb 24, 2019
67d3c9a
Merge branch 'feature/2010_seo_friendly_urls_dynroutes' of https://gi…
pkarw Feb 24, 2019
ac02ab5
Minor fix
pkarw Feb 24, 2019
9cdb5ff
Refernce fix
pkarw Feb 25, 2019
8311507
Merge branch 'develop' into feature/2010_seo_friendly_urls_dynroutes
pkarw Feb 25, 2019
d53a977
Update core/client-entry.ts
filrak Feb 26, 2019
672ff09
@filrak CR fix
pkarw Feb 26, 2019
58b0184
Update core/lib/multistore.ts
filrak Feb 26, 2019
4bfba3f
CR fixes
pkarw Feb 26, 2019
873bc2c
Breadcrumbs fix
pkarw Feb 26, 2019
4eb2eb8
Update core/modules/url/router/beforeEach.ts
filrak Feb 26, 2019
174d9b4
Update core/modules/url/router/beforeEach.ts
filrak Feb 26, 2019
86bd7df
Update core/modules/url/router/beforeEach.ts
filrak Feb 26, 2019
b4579fc
another set of CR fixes
pkarw Feb 26, 2019
8fda061
last set of CR fixes
pkarw Feb 26, 2019
5e18ee5
Merge branch 'feature/2010_seo_friendly_urls_dynroutes' of https://gi…
pkarw Feb 26, 2019
e1e6adc
Merge branch 'develop' into feature/2010_seo_friendly_urls_dynroutes
pkarw Feb 26, 2019
792bf2a
Merge branch 'develop' into feature/2010_seo_friendly_urls_dynroutes
pkarw Mar 1, 2019
49e00e7
Fix with category/resetFilters for asyncData (validateRoute is not be…
pkarw Mar 1, 2019
c96804a
Update CHANGELOG.md
patzick Mar 4, 2019
135a405
Update CHANGELOG.md
patzick Mar 4, 2019
38fef2f
Update core/app.ts
patzick Mar 4, 2019
31bc157
Merge branch 'develop' into feature/2010_seo_friendly_urls_dynroutes
pkarw Mar 4, 2019
5ac260a
Update core/modules/catalog/store/product/actions.ts
patzick Mar 4, 2019
bfb5197
Merge branch 'develop' into feature/2010_seo_friendly_urls_dynroutes
patzick Mar 4, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.9.0]
### Added
- The Url Dispatcher feature added for friendly URLs. When `config.seo.useUrlDispatcher` set to true the `product.url_path` and `category.url_path` fields are used as absolute URL addresses (no `/c` and `/p` prefixes anymore). Check the latest `mage2vuestorefront` snapshot and reimport Your products to properly set `url_path` fields - #2010 - @pkarw

## [1.8.3] - 2019.02.27
### Fixed
- Problem with placing second order (unbinding payment methods after first order) - @patzick (#2195, #2503)

### Changed / Improved
- The `core/helpers` parsing URL methods exchanged to `query-string` package
- Fixed an issue where the correct image for a product configuration wasn't set on the product page image carousel. Also added the fix on the productcarousel in the zoom component - @DaanKouters (#2419)
- Way of creating VS Modules was changed to use factory method instead of explict object creation. - @filrak (#2434)
- Added clear filters button on desktop also and only show if filters are applied - @DaanKouters (#2342)
Expand Down
7 changes: 4 additions & 3 deletions config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
"twoStageCaching": true,
"optimizeShoppingCart": true,
"category": {
"includeFields": [ "id", "*.children_data.id", "*.id", "children_count", "sku", "name", "is_active", "parent_id", "level", "url_key", "product_count", "path"],
"includeFields": [ "id", "*.children_data.id", "*.id", "children_count", "sku", "name", "is_active", "parent_id", "level", "url_key", "url_path", "product_count", "path"],
"excludeFields": [ "sgn" ],
"categoriesRootCategorylId": 2,
"categoriesDynamicPrefetchLevel": 2,
Expand All @@ -155,11 +155,11 @@
},
"productList": {
"sort": "",
"includeFields": [ "type_id", "sku", "product_links", "tax_class_id", "special_price", "special_to_date", "special_from_date", "name", "price", "priceInclTax", "originalPriceInclTax", "originalPrice", "specialPriceInclTax", "id", "image", "sale", "new", "url_key", "status", "tier_prices", "configurable_children.sku", "configurable_children.price", "configurable_children.special_price", "configurable_children.priceInclTax", "configurable_children.specialPriceInclTax", "configurable_children.originalPrice", "configurable_children.originalPriceInclTax" ],
"includeFields": [ "type_id", "sku", "product_links", "tax_class_id", "special_price", "special_to_date", "special_from_date", "name", "price", "priceInclTax", "originalPriceInclTax", "originalPrice", "specialPriceInclTax", "id", "image", "sale", "new", "url_path", "url_key", "status", "tier_prices", "configurable_children.sku", "configurable_children.price", "configurable_children.special_price", "configurable_children.priceInclTax", "configurable_children.specialPriceInclTax", "configurable_children.originalPrice", "configurable_children.originalPriceInclTax" ],
"excludeFields": [ "description", "configurable_options", "sgn", "*.sgn", "msrp_display_actual_price_type", "*.msrp_display_actual_price_type", "required_options" ]
},
"productListWithChildren": {
"includeFields": [ "type_id", "sku", "name", "tax_class_id", "special_price", "special_to_date", "special_from_date", "price", "priceInclTax", "originalPriceInclTax", "originalPrice", "specialPriceInclTax", "id", "image", "sale", "new", "configurable_children.image", "configurable_children.sku", "configurable_children.price", "configurable_children.special_price", "configurable_children.priceInclTax", "configurable_children.specialPriceInclTax", "configurable_children.originalPrice", "configurable_children.originalPriceInclTax", "configurable_children.color", "configurable_children.size", "configurable_children.id", "configurable_children.tier_prices", "product_links", "url_key", "status", "tier_prices"],
"includeFields": [ "type_id", "sku", "name", "tax_class_id", "special_price", "special_to_date", "special_from_date", "price", "priceInclTax", "originalPriceInclTax", "originalPrice", "specialPriceInclTax", "id", "image", "sale", "new", "configurable_children.image", "configurable_children.sku", "configurable_children.price", "configurable_children.special_price", "configurable_children.priceInclTax", "configurable_children.specialPriceInclTax", "configurable_children.originalPrice", "configurable_children.originalPriceInclTax", "configurable_children.color", "configurable_children.size", "configurable_children.id", "configurable_children.tier_prices", "product_links", "url_path", "url_key", "status", "tier_prices"],
"excludeFields": [ "description", "sgn", "*.sgn", "msrp_display_actual_price_type", "*.msrp_display_actual_price_type", "required_options"]
},
"review": {
Expand Down Expand Up @@ -192,6 +192,7 @@
"tax_class_id",
"media_gallery",
"url_key",
"url_path",
"max_price",
"minimal_regular_price",
"special_price",
Expand Down
2 changes: 1 addition & 1 deletion core/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const createApp = async (ssrContext, config): Promise<{app: Vue, router: VueRou
// sync router with vuex 'router' store
sync(store, router)
// TODO: Don't mutate the state directly, use mutation instead
store.state.version = '1.7.0'
store.state.version = '1.8.2'
store.state.config = config
store.state.__DEMO_MODE__ = (config.demomode === true) ? true : false
if(ssrContext) Vue.prototype.$ssrRequestContext = ssrContext
Expand Down
1 change: 1 addition & 0 deletions core/build/webpack.base.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export default {
inject: isProd == false
})
],
devtool: 'source-map',
entry: {
app: ['babel-polyfill', './core/client-entry.ts']
},
Expand Down
2 changes: 1 addition & 1 deletion core/build/webpack.client.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const config = merge(base, {
'process.env.VUE_ENV': '"client"'
}),
new VueSSRClientPlugin()
]
],
})

export default config;
1 change: 1 addition & 0 deletions core/build/webpack.prod.client.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const extendedConfig = require(path.join(themeRoot, '/webpack.config.js'))

const prodClientConfig = merge(baseClientConfig, {
mode: 'production',
devtool: 'nosources-source-map',
plugins: [
]
})
Expand Down
1 change: 1 addition & 0 deletions core/build/webpack.prod.server.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const extendedConfig = require(path.join(themeRoot, '/webpack.config.js'))

export default extendedConfig(baseServerConfig, {
mode: 'production',
devtool: 'nosources-source-map',
isClient: false,
isDev: false
})
11 changes: 3 additions & 8 deletions core/client-entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const invokeClientEntry = async () => {
prepareStoreView(storeCode)
}
}

store.dispatch('url/registerDynamicRoutes')
function _commonErrorHandler (err, reject) {
if (err.message.indexOf('query returned empty result') > 0) {
rootStore.dispatch('notification/spawnNotification', {
Expand Down Expand Up @@ -68,7 +68,6 @@ const invokeClientEntry = async () => {
_commonErrorHandler(err, next)
})
}

router.onReady(() => {
router.beforeResolve((to, from, next) => {
if (!from.name) return next() // do not resolve asyncData on server render - already been done
Expand All @@ -88,14 +87,10 @@ const invokeClientEntry = async () => {
}
}
}
let diffed = false
const activated = matched.filter((c, i) => {
return diffed || (diffed = (prevMatched[i] !== c))
})
if (!activated.length) {
if (!matched.length) {
return next()
}
Promise.all(activated.map((c: any) => { // TODO: update me for mixins support
Promise.all(matched.map((c: any) => { // TODO: update me for mixins support
const components = c.mixins && config.ssr.executeMixedinAsyncData ? Array.from(c.mixins) : []
union(components, [c]).map(SubComponent => {
if (SubComponent.preAsyncData) {
Expand Down
13 changes: 7 additions & 6 deletions core/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import rootStore from '@vue-storefront/core/store'
import SearchQuery from '@vue-storefront/core/lib/search/searchQuery'
import { remove as removeAccents } from 'remove-accents'
import { Logger } from '@vue-storefront/core/lib/logger'
import { formatCategoryLink } from '@vue-storefront/core/modules/url/helpers'

/**
* Create slugify -> "create-slugify" permalink of text
Expand Down Expand Up @@ -50,15 +51,15 @@ export function getThumbnailPath (relativeUrl, width, height) {
* @param {Array} categoryPath
*/
export function breadCrumbRoutes (categoryPath) {
const tmpRts = []
for (let sc of categoryPath) {
tmpRts.push({
name: sc.name,
route_link: (rootStore.state.config.products.useShortCatalogUrls ? '/' : '/c/') + sc.slug
const breadCrumbRoutes = []
for (let category of categoryPath) {
breadCrumbRoutes.push({
name: category.name,
route_link: formatCategoryLink(category)
})
}

return tmpRts
return breadCrumbRoutes
}

/**
Expand Down
4 changes: 2 additions & 2 deletions core/lib/async-data-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ const AsyncDataLoader = {
flush : function (actionContext: AsyncDataLoaderActionContext) {
if (!actionContext.category) actionContext.category = DEFAULT_ACTION_CATEGORY
const actionsToExecute = this.queue.filter(ac => (!ac.category || !actionContext.category) || ac.category === actionContext.category && (!ac.executedAt)).map(ac => {
ac.executedAt = new Date()
return ac.execute(actionContext) // function must return Promise
})
if (actionsToExecute.length > 0) {
Logger.info('Executing data loader actions(' + actionsToExecute.length + ')', 'dataloader')()
}
return Promise.all(actionsToExecute).then(results => {
actionsToExecute.map(ac => ac.executedAt = new Date())
return Promise.all(actionsToExecute).then(results => {
return results
})
}
Expand Down
53 changes: 35 additions & 18 deletions core/lib/logger.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { isServer } from '@vue-storefront/core/helpers'
import buildTimeConfig from 'config'

const bgColorStyle = (color) => `color: white; background: ${color}; padding: 4px; font-weight: bold; font-size: 0.8em'`

/** VS message logger. By default works only on dev mode */
Expand Down Expand Up @@ -34,6 +33,16 @@ class Logger
this.isProduction = process.env.NODE_ENV === 'production';
}

/**
* Convert message to string - as it may be object, array either primitive
* @param payload
*/
convertToString (payload: any) {
if (typeof payload === 'string' || typeof payload === 'boolean' || typeof payload === 'number') return payload
if (payload && payload.message) return payload.message
return JSON.stringify(payload)
}

/**
* Check if method can print into console
*
Expand Down Expand Up @@ -65,12 +74,12 @@ class Logger
* @param tag short tag specifying area where message was spawned (eg. cart, sync, module)
* @param context meaningful data related to this message
*/
debug (message: string, tag: string = null, context: any = null) : () => void {
debug (message: any, tag: string = null, context: any = null) : () => void {
if (!isServer && this.canPrint('debug')) {
if (tag) {
return console.debug.bind(window.console, '%cVSF%c %c' + tag +'%c ' + message, bgColorStyle('grey'), 'color: inherit', bgColorStyle('gray'), 'font-weight: normal', context);
return console.debug.bind(window.console, '%cVSF%c %c' + tag +'%c ' + this.convertToString(message), bgColorStyle('grey'), 'color: inherit', bgColorStyle('gray'), 'font-weight: normal', context);
} else {
return console.debug.bind(window.console, '%cVSF%c ' + message, bgColorStyle('white'), 'font-weight: normal', context);
return console.debug.bind(window.console, '%cVSF%c ' + this.convertToString(message), bgColorStyle('grey'), 'font-weight: normal', context);
}
} else {
return function () {}
Expand All @@ -85,7 +94,7 @@ class Logger
* @param tag short tag specifying area where message was spawned (eg. cart, sync, module)
* @param context meaningful data related to this message
*/
log (message: string, tag: string = null, context: any = null) : () => void {
log (message: any, tag: string = null, context: any = null) : () => void {
return this.info(message, tag, context);
}

Expand All @@ -97,12 +106,12 @@ class Logger
* @param tag short tag specifying area where message was spawned (eg. cart, sync, module)
* @param context meaningful data related to this message
*/
info (message: string, tag: string = null, context: any = null) : () => void {
info (message: any, tag: string = null, context: any = null) : () => void {
if (!isServer && this.canPrint('info')) {
if (tag) {
return console.log.bind(window.console, '%cVSF%c %c' + tag +'%c ' + message, bgColorStyle('green'), 'color: inherit', bgColorStyle('gray'), 'font-weight: bold', context);
return console.log.bind(window.console, '%cVSF%c %c' + tag +'%c ' + this.convertToString(message), bgColorStyle('green'), 'color: inherit', bgColorStyle('gray'), 'font-weight: bold', context);
} else {
return console.log.bind(window.console, '%cVSF%c ' + message, bgColorStyle('green'), 'font-weight: bold', context);
return console.log.bind(window.console, '%cVSF%c ' + this.convertToString(message), bgColorStyle('green'), 'font-weight: bold', context);
}
} else {
return function () {}
Expand All @@ -117,12 +126,16 @@ class Logger
* @param tag short tag specifying area where message was spawned (eg. cart, sync, module)
* @param context meaningful data related to this message
*/
warn (message: string, tag: string = null, context: any = null) : () => void {
if (!isServer && this.canPrint('warn')) {
if (tag) {
return console.warn.bind(window.console, '%cVSF%c %c' + tag +'%c ' + message, bgColorStyle('orange'), 'color: inherit', bgColorStyle('gray'), 'font-weight: bold', context);
warn (message: any, tag: string = null, context: any = null) : () => void {
if (this.canPrint('warn')) {
if (!isServer) {
if (tag) {
return console.warn.bind(window.console, '%cVSF%c %c' + tag +'%c ' + this.convertToString(message), bgColorStyle('orange'), 'color: inherit', bgColorStyle('gray'), 'font-weight: bold', context);
} else {
return console.warn.bind(window.console, '%cVSF%c ' + this.convertToString(message), bgColorStyle('orange'), 'font-weight: bold', context);
}
} else {
return console.warn.bind(window.console, '%cVSF%c ' + message, bgColorStyle('orange'), 'font-weight: bold', context);
return console.warn.bind(console, message, context);
}
} else {
return function () {}
Expand All @@ -137,12 +150,16 @@ class Logger
* @param tag short tag specifying area where message was spawned (eg. cart, sync, module)
* @param context meaningful data related to this message
*/
error (message: string, tag: string = null, context: any = null) : () => void {
if (!isServer && this.canPrint('error')) {
if (tag) {
return console.error.bind(window.console, '%cVSF%c %c' + tag +'%c ' + message, bgColorStyle('red'), 'color: inherit', bgColorStyle('gray'), 'font-weight: bold', context);
error (message: any, tag: string = null, context: any = null) : () => void {
if (this.canPrint('error')) { // we should display SSR errors for better monitoring + error handling
if (!isServer) {
if (tag) {
return console.error.bind(window.console, '%cVSF%c %c' + tag +'%c ' + this.convertToString(message), bgColorStyle('red'), 'color: inherit', bgColorStyle('gray'), 'font-weight: bold', context);
} else {
return console.error.bind(window.console, '%cVSF%c ' + this.convertToString(message), bgColorStyle('red'), 'font-weight: bold', context);
}
} else {
return console.error.bind(window.console, '%cVSF%c ' + message, bgColorStyle('red'), 'font-weight: bold', context);
return console.error.bind(console, message, context);
}
} else {
return function () {}
Expand Down
3 changes: 2 additions & 1 deletion core/lib/module/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { router } from '@vue-storefront/core/app'
import { isServer } from '@vue-storefront/core/helpers'
import { VSF, VueStorefrontModuleConfig } from './types'
import { doesStoreAlreadyExists, mergeStores } from './helpers'
import { RouterManager } from '@vue-storefront/core/lib/router-manager'

const moduleExtendings: VueStorefrontModuleConfig[] = []
const registeredModules: VueStorefrontModuleConfig[] = []
Expand Down Expand Up @@ -49,7 +50,7 @@ class VueStorefrontModule {
private static _extendRouter (routerInstance, routes?: RouteConfig[], beforeEach?: NavigationGuard, afterEach?: NavigationGuard): void {
if (routes) {
setupMultistoreRoutes(rootStore.state.config, routerInstance, routes)
routerInstance.addRoutes(routes)
RouterManager.addRoutes(routes, routerInstance)
}
if (beforeEach) routerInstance.beforeEach(beforeEach)
if (afterEach) routerInstance.afterEach(afterEach)
Expand Down
Loading