WordPress.org

Make WordPress Core

Opened 3 years ago

Closed 15 months ago

Last modified 15 months ago

#17134 closed feature request (wontfix)

Add support for the_slug() in template tags

Reported by: tomauger Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: Template Keywords: has-patch
Focuses: Cc:

Description

Although one can easily extract the page or post's slug from $post_datapost_name?, this seems to be one of the only important bits of data for which no template tag has been created.

The slug is often used, for example, when creating specific classes or id's within HTML elements. Presumably the other template tags were all created for convenience and to simplify template creation. Not including the_slug() in the template tags seems to be an oversight, easily corrected.

Attachments (2)

17134.diff (1.3 KB) - added by iandunn 15 months ago.
17134.2.diff (1011 bytes) - added by iandunn 15 months ago.

Download all attachments as: .zip

Change History (18)

comment:1 scribu3 years ago

  • Keywords close added

For outputting classes, you already have the post_class() template tag.

comment:2 tomauger3 years ago

That was just an example. I'm sure with a little creative thinking one can come up with many examples of where the slug might be used. Given that there's a template tag for nearly every other commonly-used data point, I think it's reasonable to request the_slug().

Also, from the point of view of improving the new developer experience, it's also the most logical starting point for someone to try, once they've learned about the_title(), the_content() and the_excerpt(). Why not the_slug()?

comment:3 scribu3 years ago

  • Keywords 2nd-opinion added; close removed
  • Version 3.1 deleted

Unlike the post title or post content, the slug is not meant to be used on it's own, but as part of it's URL.

comment:4 tomauger3 years ago

Is it always the case that the slug is intended to be used in conjunction with the URL?

post_class() is powerful and contextual, but doesn't always do what a theme developer might want. For example, if styling a section where you may want to include an id="post-name", you won't get that using post_class() and you almost certainly wouldn't want to use the_id() to have a numeric ID in your item.

I'm sure there are a million enhancements that are higher priority or more important, but I don't see that this request in any way contradicts the intent of template tags and would be a welcome addition to the list, particularly for new developers who may have no other reason to access the query object directly.

comment:5 ocean903 years ago

  • Keywords 2nd-opinion removed
  • Milestone Awaiting Review deleted
  • Resolution set to wontfix
  • Status changed from new to closed

I can't see a benefit of a the_slug() function. The slug is only for building the URL.

#18118 is about adding the slug/post name to body_class, which can help you to style a section, if you doesn't want to use the ID.

comment:6 creatorbri23 months ago

  • Cc creatorbri added
  • Resolution wontfix deleted
  • Status changed from closed to reopened

"I can't see a benefit of a the_slug() function. The slug is only for building the URL." -- ocean90


@ocean90 - I completely disagree.

There are all sorts of situations in template building where a quick & convenient the_slug() function would be beneficial.

Almost more importantly, as a theme/plugin builder, it seems intuitive to include it -- as analogous to the_title() and the_excerpt() -- and particularly unintuitive to exclude it.

Last edited 23 months ago by creatorbri (previous) (diff)

comment:7 SergeyBiryukov23 months ago

  • Keywords 2nd-opinion added
  • Milestone set to Awaiting Review

comment:8 iandunn15 months ago

#23351 was marked as a duplicate.

comment:9 iandunn15 months ago

  • Cc ian_dunn@… added

I've had a desire for get_the_slug() several times over the years. Just last week I wanted to use it to ID links that were being tracked in Google Analytics via gaq.push(), so that the report would easily show what page the click occurred on.

I could have used get_the_ID() instead, but then I'd have to manually lookup the IDs and map them to the pages. I could use get_the_title(), but that's not guaranteed to be unique and it could have characters that I'd have to strip out. It'd be much easier and simpler to just use get_the_slug(). The slug is basically a human-friendly ID.

Even if it was originally intended to be used when building URLs, I don't see why that should be considered the only valid use case. That places an artificial restriction on developers. There are millions of people using WP, and we can't possibly imagine all the different scenarios they might have.

Unless a change would cause harm or encourage bad practices, why deny people something that they're asking for? If you do a Google search for "the_slug" you'll find plenty of people looking for it, and most are surprised that it isn't included in core. e.g., 1 and
2.

I'm working on a patch for this, in case others think that it should be included in a future version. Many of the homegrown versions out there don't prefix their functions names, so one potential problem will be collisions. Here are a couple ideas for addressing that:

  1. Choose different names to avoid collisions. The downside here is that the new function names wouldn't be consistent with similar functions like the_title(), the_guid(), etc.
  2. Make the new functions pluggable, so they'd only be declared if others didn't already exist.
  3. Just let collisions happen. The error PHP spits out is fairly descriptive, so it shouldn't be too hard for people to realize what's going on.

I'm leaning towards #3, but would like to hear other opinions.

iandunn15 months ago

comment:10 iandunn15 months ago

  • Keywords has-patch added

comment:11 wonderboymusic15 months ago

if you're in the loop already, or have already called the_post() - why not one of these:

get_post()->post_name

or

get_post_field( 'post_name', get_the_ID() )?

comment:12 iandunn15 months ago

For the same reasons it's not good to access $post->post_title or $post->post_content directly. Using the API ensures a consistent interface over time, allows for filters, etc. The patch also allows for calling arbitrary posts outside the loop via get_slug( $id ).

comment:13 wonderboymusic15 months ago

post_name appears in core 176 times, almost every time it is directly accessed from the object, unfiltered. The only filters that are ever called on it are editable_slug in the admin, and sanitize_title, only when going into the database or being faked for a draft or pending post.

Adding a filter that could alter its uniqueness is dangerous. If the plan is for no one to ever filter it, and the filter's removed from your patch, then it's too much reflection - there are other ways to access it. The new functions would make sense if they got rid of the value being filtered in a bunch of places and replaced them with handy helper functions, but that doesn't seem to be the case.

comment:14 nacin15 months ago

I think only bad things can come from using this function.

  1. Filters don't make sense here. Title, content, excerpt, etc. have filters because raw content is stored in the database and we clearly need to process it before displaying it. With a sanitized post slug, that is not the case. There is no processing that should occur. The filter just doesn't make sense — if you are going to have a function that returns the slug, it would be best unfiltered as it is raw data.
  1. It may be used, improperly, to construct a URL. Never underestimate the ingenuity of fools. Someone, somewhere, will do <a href="/<?php the_slug(); ?>/">. Why? Because there isn't another obvious use case for such a function.
  1. For hierarchical post types, I don't know if this is the expected return value.
  1. It may be used, improperly, as an HTML ID or class name, or a more restrictive field. There is no guarantee that an unprocessed slug meets the standards of one of these attributes. It could potentially have uppercase characters, spaces, periods, international characters, and other special characters, because the sanitization is flexible and may be modified by plugins. (Example: api.jquery.com allows periods and uppercase characters.) A class name should really go through sanitize_html_class(), which makes me wonder what an echo-based the_slug() could ever be used for.

And if there is no good use of the_slug(), do we even need the associated getter? As stated, A) there is no common use case for this, which basically means no template tag is necessary, and B) this is raw data, which further limits the reason for having a template tag. At that point, one should use get_post( optional $id )->post_name.

I have yet to do a Google search for the_slug but I think I would be hard-pressed to find valid and common use cases among the results.

iandunn15 months ago

comment:15 iandunn15 months ago

  • Keywords 2nd-opinion removed
  • Resolution set to wontfix
  • Status changed from reopened to closed
  1. I see your points about filters; I've removed them from the patch.
  2. I don't personally like the idea of denying something to everyone because a few people will abuse or misunderstand it, but I understand your reasoning.
  3. That's also a good point, it'd have to be tested and possibly handled if this were to go anywhere.
  4. Same as #2, anything can be misused, but I don't feel like that's a good reason not do it. I don't think the_slug() is essential, though, so I removed that too.

So, I don't really agree with all your reasons, but I do appreciate both of you taking the time to articulate why you're against it. I'll move on to other tickets and just use get_post( $id )->post_name in the future. That way still provides some abstraction in the (albeit unlikely) event that $post changes in the future.

comment:16 SergeyBiryukov15 months ago

  • Milestone Awaiting Review deleted
Note: See TracTickets for help on using tickets.