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

[Feature] Permalink Settings UI #1631

Closed
ErisDS opened this issue Dec 7, 2013 · 21 comments

Comments

Projects
None yet
@ErisDS
Copy link
Member

commented Dec 7, 2013

The current Permalink Settings UI is just a checkbox to switch between WP style and Ghost style permalinks. But Ghost is capable of supporting many, many more formats. In order to make these formats accessible, we are going to add a new UI to the general settings pane that is going to look something like this:

In order to ship this, the following tasks need to be completed:

  • Code up the UI in HTML & CSS #3920 Mockup here
  • Mockup needs fixing / would be good to have a gif showing how it is supposed to work #4454
  • Wire up the new UI as an ember component which replaces the existing checkbox (issue #4484)
  • Implement validation on the client and server to ensure that only valid permalinks can be created with the UI and saved in the DB (issue #4486)
  • Ensure the frontend correctly handles various permalinks #4322, which depended on #4445

Ghost Permalink Spec

The details of what permalink formats we support were originally covered by #2057 and extended by #3858

The full details of what constitutes a valid permalink as a result of those two issues are:

A permalink can contain any of the following items:

  • :slug
  • :id
  • :year
  • :month
  • :day
  • :author
  • santised custom text containing a-z, 0-9, - or _

To be a valid permalink:

  • each item must be separated by a '/',
  • there should be a maximum of 5 items
  • one of them must be :slug or :id so that the post can be identified.
  • no url part can be ghost

Examples

I could set my blog posts to have a URL like any of these:

  • /:year/:month/:slug/
  • /:year/:slug/
  • /blogpost/:id/
  • /post/:year/:month/:day/:slug/
  • /:author/:slug/
  • And many more combinations

Please note that contrary to what is shown in the new UI, Ghost does not yet support having a tag in your permalink, because at present we have no way to indicate which tag would be the canonical one.

@andystanton

This comment has been minimized.

Copy link

commented Jan 26, 2014

Custom permalinks from the UI would be smashing.

I'm not a js dev but managed to fudge it so the blog is served from:
http://andy.stanton.is/writing/

but pages have a custom path e.g.
http://andy.stanton.is/writing/about/unit-testing-and-mocking-in-c/

It would be great to have this in the UI.

@JohnONolan

This comment has been minimized.

Copy link
Member

commented Apr 22, 2014

Once UI ^ is done, this issue can be used for the back end implementation. Assigning back to @jgillich

@JohnONolan JohnONolan assigned jgillich and unassigned JohnONolan Apr 22, 2014

@ErisDS ErisDS added the help wanted label Jul 31, 2014

@ErisDS ErisDS modified the milestones: 0.6 Apps, Future Release Backlog Aug 20, 2014

@ErisDS ErisDS changed the title Permalink Settings UI [Feature] Permalink Settings UI Aug 20, 2014

shane-tomlinson added a commit to shane-tomlinson/Ghost that referenced this issue Aug 25, 2014

Add permalink customization.
* Change the permalink input element to type text.
* URLs can be any combination of `^(\/([a-z-0-9_-]+|:id|:slug|:year|:month|:day))+\/` to allow for URLs like `/way_to-customize/:id/:slug/another-customization/`
* Checking is not very strict, could be made more so.
* Permalink toggling test code is updated to handle new format.

fixes TryGhost#1631

shane-tomlinson added a commit to shane-tomlinson/Ghost that referenced this issue Aug 25, 2014

Add permalink customization.
* Change the permalink input element to type text.
* URLs can be any combination of `^(\/([a-z-0-9_-]+|:id|:slug|:year|:month|:day))+\/` to allow for URLs like `/way_to-customize/:id/:slug/another-customization/`
* Checking is not very strict, could be made more so.
* Permalink toggling test code is updated to handle new format.

fixes TryGhost#1631

shane-tomlinson added a commit to shane-tomlinson/Ghost that referenced this issue Aug 25, 2014

Add permalink customization.
* Change the permalink input element to type text.
* URLs can be any combination of `^(\/([a-z-0-9_-]+|:id|:slug|:year|:month|:day))+\/` to allow for URLs like `/way_to-customize/:id/:slug/another-customization/`
* Checking is not very strict, could be made more so.
* Permalink toggling test code is updated to handle new format.

fixes TryGhost#1631

shane-tomlinson added a commit to shane-tomlinson/Ghost that referenced this issue Aug 25, 2014

Add permalink customization.
* Change the permalink input element to type text.
* URLs can be any combination of `^(\/([a-z-0-9_-]+|:id|:slug|:year|:month|:day))+\/` to allow for URLs like `/way_to-customize/:id/:slug/another-customization/`
* Checking is not very strict, could be made more so.
* Permalink toggling test code is updated to handle new format.

fixes TryGhost#1631
@novaugust

This comment has been minimized.

Copy link
Member

commented Nov 14, 2014

Heyo, where are we at with this? It seems all referenced issues in the original issue description have been closed. and #4217 added a mockup for the UI. It now just needs to be added to the general settings page, and hooked into the api? (is there an api endpoint for it?)

Mockup here

@PaulAdamDavis

This comment has been minimized.

Copy link
Contributor

commented Nov 17, 2014

How this UI should work

  • With certain keys such as a comma (final to be determined), the current value of the input is taken and added to the permalink structure
  • Pressing backspace in an empty input deletes the last parameter
  • gif's are worth a thousand words

permalinks

@ErisDS

This comment has been minimized.

Copy link
Member Author

commented Nov 19, 2014

I've now raised two further issues for this, which I believe should cover the implementation of the feature.

@ravinggenius

This comment has been minimized.

Copy link

commented Dec 7, 2014

Why not allow arbitrary separators (or no separators)? For instance:

/:year-:month-:day-:slug
/:year-:month/:id-:slug

If arbitrary separators cannot be done, and I have post URLs following /:year/:month/:day/:slug, what happens when a user navigates to (for instance) /:year/:month/:day or /:year/:month. I can see two valid responses:

  1. Ghost returns a 404 and calls it a day.
    1. To a certain extent, users have been trained to recognize / as the separator to stop at when URL-hacking. I'd really prefer to use arbitrary separators to communicate the non-hackability of my URLs.
  2. Ghost returns a list of posts that where written on that day/month/year.
    1. Implied in this approach is that Ghost generates a permalink pattern for each parent pattern (defining /:year/:month/:day/:slug implicitly defines /:year/:month/:day, /:year/:month, /:year).
    2. What if there are no posts published during the specified time frame?
    3. What if there are many posts? I would assume paging, but that complicates the implementation even more.

Personally I like the idea of option 2, or at least arbitrary separators.

@ravinggenius

This comment has been minimized.

Copy link

commented Dec 7, 2014

Are literal segments going to be supported (for instance /blog/:year/:month/:day/:slug)?

Also, why limit to five segments? That sounds like an arbitrary decision, which might hint at a code smell.

@JohnONolan

This comment has been minimized.

Copy link
Member

commented Dec 7, 2014

Why not allow arbitrary separators (or no separators)? For instance:

Agree, that should be possible

Ghost returns a 404 and calls it a day.

Is absolutely what's going to happen if someone visits a random URL. The alternative would be a nightmare in many, many ways.

Are literal segments going to be supported (for instance /blog/:year/:month/:day/:slug)?

Yes, that should be possible

Also, why limit to five segments? That sounds like an arbitrary decision, which might hint at a code smell.

I agree it shouldn't be limited to 5, cc @ErisDS

NB: Keep in mind all of this is simply a default set of dynamic permalinks. You can enter whatever the hell you want into the database, which in future will be possible via an App UI.

@javorszky

This comment has been minimized.

Copy link
Member

commented Dec 7, 2014

Why not allow arbitrary separators (or no separators)? For instance:

Agree, that should be possible

Slug has - in it. Specifically it replaces whitespace characters to be -. If there are arbitrary separators, such as replacing / with -, then this url:

http://example.com/2014/11/32/the-best-thing-ever will be http://example.com/2014-11-32-the-best-thing-ever. Which sounds ok. Until Ghost wants to split it up, because then the individual segments would be 2014, 11, 32, the, best, thing, ever.

Again, unless we start from the beginning, and count. Is the first segment [\d]{4}? That's a year then, use that. Is the second one [\d]{2}? Month. Third the same? Day. The rest is slug. This feels incredibly fragile.

@ErisDS

This comment has been minimized.

Copy link
Member Author

commented Dec 7, 2014

Hi @ravinggenius what you refer to as a literal segment, I called 'santised custom text' :)

As for arbitrary separators, in my opinion this adds unnecessary complexity at this stage. It would require the UI that has been designed and built to be redesigned, as well as adding complexities to processing URLs as @javorszky has explained. I believe we should aim for the existing spec, and if arbitrary separators is something required by enough people then it can be added later.

@JohnONolan

This comment has been minimized.

Copy link
Member

commented Dec 7, 2014

Makes total sense RE separators. Agreed.

@ErisDS

This comment has been minimized.

Copy link
Member Author

commented Dec 7, 2014

Also, why limit to five segments? That sounds like an arbitrary decision, which might hint at a code smell.

I agree it shouldn't be limited to 5, cc @ErisDS

It is a somewhat arbitrary decision, intended to limit the complexity of URLs that users design. Currently there are only 5 possible sections according to the validation in the codebase (id, day, month, year, slug and id), and having any one of them twice would be odd. Issue #4486 aims to update this validation, and it can also remove the restriction to 5 items if it is felt strongly that it should be possible to build longer URL structures.

@ravinggenius

This comment has been minimized.

Copy link

commented Dec 8, 2014

Hi @ravinggenius what you refer to as a literal segment, I called 'santised custom text' :)

Thanks for the clarification.

http://example.com/2014/11/32/the-best-thing-ever will be http://example.com/2014-11-32-the-best-thing-ever. Which sounds ok. Until Ghost wants to split it up, because then the individual segments would be 2014, 11, 32, the, best, thing, ever.

In my opinion we shouldn't be manually splitting strings to parse out segments. A while ago I wrote some code (test) to transform a pattern like /:year-:month-:day-:slug[1] into a regular expression like /^\/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})-(?<slug>[0-9a-z\-_\.\/])/[2]. Matching /2014-11-32-the-best-thing-ever would extract 2014, 11, 32, the-best-thing-ever. Incidentally this approach makes handling arbitrary separators a non-issue, as separators are no longer special. I wouldn't expect implementing this in JavaScript to be much harder.

[1] The GUI could instead generate patterns like /blog/{year}-{month}-{day}/{slug}, which would likely be easier to work with.

[2] If you don't know, Ruby can optionally name capture groups. For instance ?<year>.

@ErisDS

This comment has been minimized.

Copy link
Member Author

commented Dec 8, 2014

@ravinggenius It is not a good idea to introduce further complexity at this stage. We need to implement a base-level version of this, just to get it off the ground and into the code base - this is a relatively old issue, and it's not being worked on at present. Therefore we're far more likely to simplify the problem to make it easier to pick up and work on.

Once we've got a basic version in, by all means the community can extend it to do more - but right now there's very little point talking about a more advanced version when it doesn't exist at all ;)

Perhaps you'd like to pick up #4486 to ensure it's done in a way that is easily extensible in future?

@ErisDS ErisDS modified the milestones: Next Backlog, Current Backlog Apr 3, 2015

@ErisDS ErisDS removed this from the Next Backlog milestone Oct 8, 2015

@ErisDS

This comment has been minimized.

Copy link
Member Author

commented Oct 8, 2015

Short term, custom permalinks are working well if you configure them via the database. Long term we'll revisit adding the UI to settings again, or via some other method when it becomes more of a priority issue.

@jloh

This comment has been minimized.

Copy link

commented Nov 22, 2016

I asked this question on slack however didn't get a response so thought I'd shoot a question on here. Is there any plans of implementing this for 1.0/x or a general overhaul of the whole permalink structure so you can do things like sub pages or put all posts under /post for example?

@ErisDS

This comment has been minimized.

Copy link
Member Author

commented Jan 5, 2017

@jloh sorry for the slow reply. This issue represents the idea of adding a UI for the existing permalink settings. Adding this would not result in the ability to sub pages. It is already possible to put all posts under /post, however it can only be done by modifying the database rather than via a UI at present.

@Cellane

This comment has been minimized.

Copy link

commented May 31, 2018

@ErisDS Apologies for asking a partially unrelated question in the issue but I think this thread is the most related discussion to an issue I have right now. I’m thinking of migrating my site from Jekyll to Ghost and putting all posts under /post is exactly what I need – you mentioned in your comment that it can be done by modifying the database, although I wasn’t able to find any resource on that topic (other than this issue). Would you mind sharing more about how that would be done?

@kirrg001

This comment has been minimized.

Copy link
Contributor

commented May 31, 2018

@Cellane There is a table called settings.

update settings set value='/post/:slug/' where `key`='permalinks';

This query makes it possible to change the location of all posts.

But note: We are about to ship the beta of dynamic routing. This feature makes it possible to configure your routes in a yaml routing file. I would recommend waiting for the upcoming release next week.

@Cellane

This comment has been minimized.

Copy link

commented May 31, 2018

@kirrg001 I see, thank you very much for this information! With that new piece of information in mind, I think I’ll spend the weekend doing the actual article migration (while avoiding modifying the settings table) and delay deploying the finished site for a few days until the beta version you mentioned is released. Thank you once again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.