Skip to content
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

Unique slug generation #24

Open
mwickett opened this issue Jul 17, 2017 · 2 comments
Open

Unique slug generation #24

mwickett opened this issue Jul 17, 2017 · 2 comments

Comments

@mwickett
Copy link
Contributor

With the help of @kbrandwijk (thank you!), I've got a much more robust slug function that seems to be working well and handling every case (that I've thought of yet).

  1. It takes a title value from a new record, slugifies it (using slugs, rather than regex. Handles far more inputs - unicode, other language characters, etc.))
  2. then queries for a slug with the same value. If one exists, it appends -n+1 to the end. (e.g. title-of-post-1, title-of-post-2

I feel like this could be implemented as a schema extension as well, although I'm fairly new to that, so may be wrong.

It also needs to be adjusted heavily based on the particular project schema and naming etc.

'use latest';

const { GraphQLClient } = require('graphql-request')
const slugify = require('slugs')

const client = new GraphQLClient('__ENDPOINT__', {
  headers: {
    Authorization: 'Bearer __PAT-TOKEN__',
  }
})

module.exports = function (event) {
  // This query returns only the highest numbered slug (which could be the
  // only existing slug that may not have a trailing integer
  const query = `
    query($slug: String!) {
      allJobs(filter: {
        slug_starts_with: $slug
      }
      orderBy: slug_DESC
        first: 1
      ) {
        slug
      }
    }
  `

  const variables = {
    // Uses slugs to create slug - https://www.npmjs.com/package/slug
    slug: slugify(event.data.title)
  }

  return new Promise((resolve, reject) => {
    client.request(query, variables)
    .then(data => {
      let slug = variables.slug
      // If nothing comes back in the query, the slug doesn't already exist
      if (data.allJobs.length === 0) {
        const response = Object.assign({}, event.data, {slug})
        resolve({ data: response })
      } else {
        // Check the length of the returned result with the new slug to determine if there is
        // a trailing integer. If there isn't, use -2 or else create the next one.
        if (data.allJobs[0].slug.split('-').length === slug.split('-').length) {
         	slug = `${slug}-2`
        } else {
        	slug = `${slug}-${parseInt(data.allJobs[0].slug.split('-').pop()) + 1}`  
        }
        const response = Object.assign({}, event.data, {slug})
        resolve({ data: response })
      }
    })
    .catch(error => {
      console.log(error)
      reject(error)
    })
  })
}

I'm putting this in as an issue to look for guidance on whether this is worth writing up an including in these function examples. And should it be a Schema extension rather than a transform function?

@marktani
Copy link
Contributor

Hey Mike, thanks a lot for putting this out here, this is exactly the kind of example I'd like to see in this repository! 😄

I think a transform function fits better, but you can also implement this with a Schema Extension function.

It also needs to be adjusted heavily based on the particular project schema and naming etc.

This is perfectly fine! The way I approached this in other examples is by providing a example.graphql schema file that can be used with the Graphcool CLI to bootstrap a project with the right structure. This way, you have something working quite fast that you can hopefully adjust easily to your own use case.

I'd love to collaborate on this! Maybe we can add another variant to the generate-slug, or add this as a new example advanced-generate-slug or similar?

@mwickett
Copy link
Contributor Author

mwickett commented Jul 22, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

2 participants