Can't define permalink structure in YFM #41

Open
joshfry opened this Issue Feb 11, 2014 · 33 comments

Comments

Projects
None yet
4 participants

joshfry commented Feb 11, 2014

Hey guys, I want to be able to define a page's url directly in YFM. Here's an example:

YFM

---
title: page
url: path/to/my

---

Permalink options

options: {
  permalinks: {
    structure: ':url/:basename/index.html',
  }
},

Result

Assembling dist/pathtomy/page/index.html OK

What I wish it would do

Assembling dist/path/to/my/page/index.html OK

Is this possible or is there another way?

Thanks in advance.

Owner

doowb commented Feb 11, 2014

Oh... I think that's due to slugify. I haven't tried this yet but you might be able to add slugify: false to your options:

options: {
  permalinks: {
    slugify: false,
    structure: ':url/:basename/index.html'
  }
}

If this doesn't work, then I'll have to look into it more to see if we can fix the slugify option.

Owner

doowb commented Feb 11, 2014

Actually, I'm wrong. We always slugify yaml front matter. @jonschlinkert do you know if there's a way to escape slugify?

@joshfry the other work around for now is to use multiple variables for each segment for now.

joshfry commented Feb 11, 2014

@doowb yea, slugify: false didn't work. I'll try multiple variables.

Owner

jonschlinkert commented Feb 11, 2014

Sounds like we just need to push up a fix. I can look at it in a bit

Sent from my iPhone

joshfry commented Feb 11, 2014

Thanks! This might be another issue, but is there a way to tell the permalink structure to add a variable ONLY if it exists in YFM otherwise use a default?

if :url, :url / else :category

  • Josh

On Feb 10, 2014, at 6:03 PM, Jon Schlinkert notifications@github.com wrote:

Sounds like we just need to push up a fix. I can look at it in a bit

Sent from my iPhone

Reply to this email directly or view it on GitHub.

Owner

jonschlinkert commented Feb 11, 2014

When I responded I thought this was about just slugifying. I'll look into that as a separate issue, but this I think should be a feature request.

is there a way to tell the permalink structure to add a variable ONLY if it exists in YFM otherwise use a default?

Yeah, you could create a lodash mixin:

_.mixin({
  default: function (primary, secondary) {
    return primary != null ? primary : secondary;
  }
})

and then use it like this:

---
dest: foo/<%= _.default(url, category) %>/bar/
---

I think that should work, let me know if you have any issues

Owner

jonschlinkert commented Feb 11, 2014

oh... put the mixin just before the grunt.initConfig object:

module.exports = function(grunt) {

  _.mixin({...});

  // Project configuration.
  grunt.initConfig({
  ...

We'll have on a better way to register mixins in 0.5.0

joshfry commented Feb 11, 2014

Your assumption was right about this issue. It's about defining url in YFM. (See my first comment). The part about the mixin you provided... I'm getting this error: >> ReferenceError: _ is not defined. I'm not sure what action to take here.

Owner

jonschlinkert commented Feb 11, 2014

Okay, @joshfry I pushed up a fix for the autho-slugification, let me know if that helps.

Also, sorry in my example I left out the var _ = require('lodash');. So do this:

var _ = require('lodash');
_.mixin({
  default: function (primary, secondary) {
    return primary != null ? primary : secondary;
  }
});

not even sure if that will work, it should haven't I been able to test it.

Owner

jonschlinkert commented Feb 11, 2014

pls close if the yfm issue is fixed. thanks!

joshfry commented Feb 11, 2014

@jonschlinkert almost there. Permalink placeholders should still be slugified. I had URLs outputting with spaces in them. On the bright side, / characters are no longer ignored. But placeholders with spaces should definitely be slugified.

joshfry commented Feb 11, 2014

@jonschlinkert @doowb I'm so sorry to bug you about this but is it possible to still have auto-slugification but allow / characters in YFM?

category: this string should be slugified
url: this/url/structure/is/nice
:category = this-string-should-be-slugified
:url = this/url/structure/is/nice
Owner

doowb commented Feb 12, 2014

Basically we don't know what should and shouldn't be slugified and we use the underscore.strings library to do the slugification (slugifying?).

@jonschlinkert and I were talking more about this today and we removed slugifying all the YFM parameters by default, but I think there should be a way to slugify some parameters. What I'm thinking is adding an option that specifies all the properties that should be slugified...

options: {
  permalinks: {
    slugify: ['category']
  }
}

Then we could automatically do that just for those properties.

The other option is to use a custom replacement pattern that does the slugification on the properties yourself...

var _ = require('lodash');
var _s = require('underscore.string');
_.mixin({
  slugify: function (str) {
    return _s.slugify(str);
  }
});

grunt.initConfig({
  assemble: {
    myTarget: {
      options: {
        permalinks: {
          patterns: [
            { pattern: ':category', replacement: '<%= _.slugify(category) %>' }
          ]
        }
      }
    }
  }
});

joshfry commented Feb 12, 2014

In what situation would you not want a url to be slugified? If you passed in a space delimited string, I would expect it to always be slugified. My issue is that assemble was removing the / character in YFM. I think by default slugification should be on and you can turn it off for certain perameters. I'm not sure what that would look like..

options: {
  permalinks: {
    unslug: ['category']
  }
}

I'm not sugesting doing it like that... but yea. Default = slug, option to unslug.. haha

Owner

jonschlinkert commented Feb 12, 2014

What I'm thinking is adding an option that specifies all the properties that should be slugified...

that's not a bad idea, but let's try to exhaust other options first.

The other option is to use a custom replacement pattern that does the slugification on the properties yourself...

...like this. :-) this is the kind of use case that I had in mind when I added the custom replacement patterns. So maybe instead of adding this as a feature, we could just push up a function for it somewhere.

Owner

jonschlinkert commented Feb 12, 2014

In what situation would you not want a url to be slugified

Slugified how? Meaning, should users expect slugification to work the way we want it to? Or should it work the way that wordpress might do it? Or some other way? Sometimes spaces in slugs are replaced with dashes, sometimes underscore. sometimes dashes on the left and right are retained, sometimes not.

the point is that, if we slugify everything by default, then it might actual un-permalink someone's stuff if they used to do it some other way. This gives you the ability to choose how you want to do it. there is no downside other than having to add a mixin to your code.

Owner

jonschlinkert commented Feb 12, 2014

.... although, I would consider adding it as a default. I just need to think about it for a bit

joshfry commented Feb 12, 2014

ohhhhh.. so could I choose to replace spaces with /, - or _? That would be awesome!

Owner

doowb commented Feb 12, 2014

@joshfry

In what situation would you not want a url to be slugified?

I think a URL should be slugified too and we're using underscore.string to do the slugifying which removes '/'. So right now, we either slugify or we don't.

That's why the mixin/custom patterns is a good option...

btw... @jonschlinkert replied while I was typing 😉

joshfry commented Feb 12, 2014

That's why the mixin/custom patterns is a good option...

I think that's a good idea

Owner

jonschlinkert commented Feb 12, 2014

ohhhhh.. so could I choose to replace spaces with /, - or _? That would be awesome!

exactly! that's the advantage of the replacement patterns.

To expand on @doowb's example a bit, here is what you could do (I put this demo together to demystify what the replacement patterns are doing).

First npm install frep underscore.string

var frep = require('frep');

// We'll use underscore string's slugify function for one example
var _str = require('underscore.string');

// Custom slugification function
var slugger = function(str) {
  return str.replace(/( |-|\.)/g, '_').toLowerCase();
};

// Another slugification function
var sluggifier = function(str) {
  return str.replace(/( |\.)/g, '-');
};

// Our object of data that needs to be slugified. 
// This is essentially what's being passed in
// from yaml from matter, or really anything on 
// the context
var obj = {
  foo: 'This is foo.',
  bar: 'ThIs iS bAr.',
  baz: 'THIS is BAZ.',
};

// Our custom replacement patterns
var patterns = [
  {
    pattern: /:foo/g,
    replacement: _str.slugify(obj.foo) // underscore.string
  },
  {
    pattern: /:bar/g,
    replacement: slugger(obj.bar)  // custom function #1
  },
  {
    pattern: /:baz/g,
    replacement: sluggifier(obj.baz)  // custom function #2
  }
];

// Our "structure", which determines how
// the values from each property will be
// stitched together
var str = ':foo/:bar/:baz';

// This is frep (find-and-replace), which just
// processes each of the replacement patterns
// in sequence. 
console.log(frep.strWithArr(str, patterns));

joshfry commented Feb 12, 2014

heads up.. I'll have to check this out in the AM. thanks alot!

Owner

jonschlinkert commented Feb 12, 2014

👍

Owner

jonschlinkert commented Feb 13, 2014

I changed my mind on this. We'll slugify each segment by default, then if someone needs to only slugify one property they can use a custom pattern.

👍 from #39 ;)

joshfry commented Feb 13, 2014

Cool. If you push an update I'd love to try out your new ideas.

Owner

doowb commented Feb 13, 2014

Thanks @waynedpj for reminding me about that other issue.

@doowb no problem, though it was not really "hey, get on this!", just wanted to link the related issues

Owner

jonschlinkert commented Feb 15, 2014

👍 hey @doowb, get on this!

lol, just wanted to say it.

LOL :) a local colloquialism ;)
and for the record, i apologize as my comment was in no way a "hey, get on this!", which maybe was not clear from the original post. you 2 seem very busy and still are very active in supporting your projects. thanks as always.

Owner

doowb commented Feb 16, 2014

No worries. I tend to forgot about some of these issues because of having so many projects and it's nice to get reminded of them. I wish github had a way of pinging you when an issue hasn't been updated for x amount of time.

Owner

jonschlinkert commented Feb 16, 2014

I wish github had a way of pinging you when an issue hasn't been updated for x amount of time.

you could build a service :-) this might be nice, but only if it was labeled with "reminder" or something.

@waynedpj I knew you were just joking lol, we're all friends here!

:=)

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