WordPress.org

Make WordPress Core

Opened 6 years ago

Closed 6 years ago

Last modified 6 years ago

#9868 closed enhancement (worksforme)

the_title(), the_content(), the_permalink(), etc inconsistencies

Reported by: archon810 Owned by:
Milestone: Priority: normal
Severity: normal Version: 2.7.1
Component: Template Keywords:
Focuses: Cc:

Description

After looking at the_title(), the_content(), and the_permalink() functions, I saw that all of them, at least in WP 2.7.1 by default just echo everything and don't return anything back.

the_title(), however, supports a flag that says do not print and return instead, like so

the_title(null, null, false)

The other 2, however, don't have such flags, and such inconsistency is quite shocking to me.

Indeed, a call to get_the_SOMETHING() functions could be wrapped into an apply_filters() function but I think it is

  • for the_content() with the 3rd flag=false and get_the_content(), it provides duplicate and inconsistent with other fucntions functionality
  • hacky
  • some the_SOMETHING() functions do additional processing after the get_the_SOMETHING() calls, for example the_content()

I've opened a Stack Overflow question to get to the bottom of this but so far nobody offered an acceptable solution.

A similar ticket #7166 has been closed as "wontfix" but it offered a different solution and was indeed superfluous.

A solution is to allow all the_SOMETHING() functions to skip printing and being able to specify a flag to return data instead, like the_title() does. Please do not close simply because this ticket reminds you of #7166 and instead discuss :)

Change History (8)

comment:1 @filosofo6 years ago

The general naming convention in WP now is that the_[something] prints what get_the_[something] returns.

The print arguments in functions such as the_title are vestiges from the old way of doing it, kept for backwards-compatibility purposes.

Any proposed changes should go along those lines.

If you think the_content and get_the_content are bad, take a look at get_the_excerpt. The trick is fixing these inconsistencies without breaking zillions of themes and plugins.

comment:2 @archon8106 years ago

filosofo, in this case, what is the suggested way of cycling through posts without printing them, for example while developing an admin-only plugin that needs to apply logic to various post content? Is get_the_ really the best solution?

comment:3 @archon8106 years ago

By the way, the get_posts() function already returns an array of posts, and then for each element in the array I can access $post->post_content, $post->post_title, etc. Now I'm not even sure what I'd need get_the_content() for in the first place. /confused.

comment:4 @filosofo6 years ago

Using get_the__ is the way to go.

The problem with using the post object properties directly is that you circumvent the standard filters.

comment:5 follow-up: @archon8106 years ago

OK, I got it all sorted now. Here is the final outcome, for whoever is interested:

  • Each post's data can be accessed via iterating through the array returned by get_posts(), but this data will just be whatever is in the database, without passing through any intermediate filters
  • The preferred way is to access data using get_the_ functions and them wrapping them in an call to apply_filters() with the appropriate filter. This way, all intermediate filters will be applied.
apply_filters('the_permalink', get_permalink())
  • the reason why get_the_content() was returning an empty string is that apparently a special call to setup_postdata($post); needs to be done first. Then get_the_content() returns data properly.

Am I on the right track here?

comment:6 @Denis-de-Bernardy6 years ago

  • Component changed from General to Template
  • Milestone changed from Unassigned to Future Release

comment:7 in reply to: ↑ 5 @scribu6 years ago

  • Milestone Future Release deleted
  • Resolution set to worksforme
  • Status changed from new to closed

Replying to archon810:

OK, I got it all sorted now. Here is the final outcome, for whoever is interested:

  • Each post's data can be accessed via iterating through the array returned by get_posts(), but this data will just be whatever is in the database, without passing through any intermediate filters
  • The preferred way is to access data using get_the_ functions and them wrapping them in an call to apply_filters() with the appropriate filter. This way, all intermediate filters will be applied.
apply_filters('the_permalink', get_permalink())
  • the reason why get_the_content() was returning an empty string is that apparently a special call to setup_postdata($post); needs to be done first. Then get_the_content() returns data properly.

Am I on the right track here?

Yes, you need to call setup_postdata($post);

But a better solution would be to use a custom loop:

$query = new WP_Query( ...query vars... );

while ( $query->has_posts() ) : $query->the_post();
  $content = apply_filters('the_content', get_the_content());
endwhile;

I think that's an acceptable workaround.

Closing for lack of traction.

Feel free to reopen if you have a patch.

comment:8 @archon8106 years ago

scribu, I think the solution here is to add consistent flags to all the_BLA functions. The flag would be $do_not_echo, like in the_title(). It's the inconsistency that is rubbing me the wrong way - that's mostly it.

Note: See TracTickets for help on using tickets.