export default ({ filter }, { exceptions, logger, services }) => { const { InvalidPayloadException } = exceptions const { ItemsService } = services /** * filter create page, * call getPermalinks * * * @param 'pages.items.update' * */ filter('pages.items.create', async (input, { collection }, { database, schema }) => { // create services const pages = new ItemsService('pages', { knex: database, schema }) return await getPagePermalinks(input, pages) }) /** * filter update page, * getting current entity and check if values has changed and call getPermalinks * * * @param 'pages.items.update' * */ filter('pages.items.update', async (input, { keys, collection }, { database, schema }) => { // only if single page is updated if (keys.length > 1) { return } // create services const pages = new ItemsService('pages', { knex: database, schema }) // getting current entity const entity = await pages.readOne(keys[0]) // adding title of site if (!input.title) { input.title = entity.title } // check if input has no slug, and check entity if (!input.slug) { if (entity.slug) { input.slug = entity.slug } } // check if input has no parent and is not null (null if it get removed from object), then check entity if (!input.parent && input.parent !== null) { if (entity.parent) { input.parent = entity.parent } } return await getPagePermalinks(input, pages) }) /** * create permalink for single page, using current slug of site * and check for parent pages * * @param {object} input * @return {object} * */ const getPagePermalinks = async function(input, pages) { // parents const parents = [] // breadcrumbs const breadcrumbs = [] // push first slug to parents, if there is a value if (input.slug) { parents.push(input.slug) // @TODO only workaround, change for process translations and handle multiple breadcrumbs.push(createCrumb('', 'Home', '/')) } // if input has parent if (input.parent) { let current = input.parent // getting parents if there are no moooooreeeee do { current = await getParentPage(current, pages) if (current.slug) { parents.push(current.slug) } breadcrumbs.push(createCrumb(current.id, current.title, current.permalink)) current = current.parent } while(current) } // adding default for home input.permalink = '/' // check if parents have slugs if (parents.length > 0) { input.permalink = '/' + parents.reverse().join('/') } if (input.slug) { breadcrumbs.push(createCrumb('', input.title, '')) } input.breadcrumbs = breadcrumbs return input } /** * filter update site * * adding permalinks in site for blog and also breadcrumbs * * * @param 'pages.items.update' * */ filter('directus_settings.items.update', async (input, { collection }, { database, schema }) => { //logger.debug(JSON.stringify(input.permalinks_blog_page)) if (input.permalinks_blog_page) { // create services const pages = new ItemsService('pages', { knex: database, schema }) // getting current entity const blog = await pages.readOne(input.permalinks_blog_page) if (blog && blog.breadcrumbs) { // change breadcrumbs and add permalink of blog blog.breadcrumbs[blog.breadcrumbs.length - 1].permalink = blog.permalink input.permalinks_blog_url = blog.permalink input.permalinks_blog_breadcrumbs = blog.breadcrumbs } } return input }) /** * getting parent from a page * * @param {[type]} id * @return {undefined|object} */ const getParentPage = async function(id, pages) { let result const parent = await pages.readOne(id, { fields: ['id', 'slug', 'parent', 'title', 'permalink'], filter: { 'status' : 'published' } }) if (parent) { result = parent } return result } /** * getting single data for breadcrumbs * * @param {[type]} id * @param {[type]} title * @param {[type]} permalink * @return * */ const createCrumb = function(id, title, permalink) { return { id: id, title: title, permalink: permalink } } /** * after update a Page, check if breadcrumbs are have the current title and permalink * * * * @param 'pages.items.update' * */ action('pages.items.update', async (payload, { database, schema }) => { // getting pages const pages = new ItemsService('pages', { knex: database, schema }) // getting all pages with a breadcrumb const results = await pages.readByQuery({ fields: [ 'id', 'breadcrumbs' ], filter: { 'breadcrumbs': { '_nnull': true }} }) results.forEach((page) => { page.breadcrumbs.forEach((breadcrumb, index) => { let hasChange = false if (breadcrumb.id === payload.keys[0]) { // if permalink has change if (breadcrumb.permalink !== payload.permalink) { page.breadcrumbs[index].permalink = payload.permalink hasChange = true } // if title has changed if (breadcrumb.title !== payload.title) { page.breadcrumbs[index].title = payload.title hasChange = true } // if there are changes, update page if (hasChange === true) { pages.updateOne(page.id, page) } } }) }) }) }