1

I have some code that loops through all categories and:

  1. organize them on a Hierarchy of (parent) category and its child categories

  2. echo the titles +short description of each category +add "read more" link to the full content of that category .

  3. click on the read more of one of the child category should have lead to that category page with full content description

  4. checks if they have posts or not.

  5. displays a list of posts (excerpt+read more link) that belong to that category

Now when a user is clicking on one of the child categories (read more link) it leads to another page that shows only that category , with or without posts , but I want it to show now the full description of that category not just the short description ..

I thought if I had a way to add a unique class and by that target the pages with one category (child category) , I can solve this/is this the right way?

The code in category.php:

  <?php 
$CategoryPar = get_category( get_query_var( 'cat' ) ); 
$cat_id = $CategoryPar->cat_ID;
  $args = array(
  'orderby' => 'name',
  'child_of'           => $cat_id,
  'hide_empty' => FALSE,
  'order' => 'ASC'
        );
$Ecategories = get_categories($args);

echo'<div class="cat-sub-title">';

foreach($Ecategories as $Ecategory) { 
 echo '<p><a href="' . get_category_link( $Ecategory->term_id ) . '" title="' . sprintf( __( "View all posts in %s" ), $Ecategory->name ) . '" ' . '>' . $Ecategory->name.'</a> </p> ';
 echo '<div class="cat-sub-title-desc">'. $Ecategory->description . '</div>';
                   } 
echo'</div>';

?>

 <?php if( category_has_children( $cat ) == false) : ?>

 <?php get_template_part( 'loop' );?>

  <?php endif; ?> 

and the filter in functions.php

add_filter( 'category_description', 'cyb_trim_category_desc', 10, 2 );
function cyb_trim_category_desc( $desc, $cat_id ) {

    // wp_trim_words( $text, $num_words = 55, $more = null );
    $desc = wp_trim_words( $desc, 55, '...<p class="wrap-more-link"><a class="more-link" href="' . get_category_link( $cat_id ) . '">' . __("Read more >>", "text-domain" ) . '</a></p>' );

    return $desc;
}

First image - click on one one of the categories in the main menu will lead the user to this page (its not a template page)

second image - clicking on one of the read more links of the child categories in the previous page will lead to this page - that child category has no posts ,I want it to show full description length .these are the body classes

class="archive category category-eternal-in-the-field category-23"

3
  • 1
    Add your code please, it is impossible to guess where you are going wrong :-) Commented Sep 14, 2015 at 9:39
  • Hi Pieter you helped me the last time :)
    – tali
    Commented Sep 14, 2015 at 9:58
  • Can you describe when and where exactly do you want to apply the filter? I don't fully understand.
    – cybmeta
    Commented Sep 14, 2015 at 10:40

1 Answer 1

1

You just need to add some conditional to aplly the filter or not. For example, if you don't want to apply the trimming on category archive pages, one possible solution could be:

add_filter( 'category_description', 'cyb_trim_category_desc', 10, 2 );
function cyb_trim_category_desc( $desc, $cat_id ) {

    // Apply only if we are not in category archive template
    if( ! is_category() ) {

        // wp_trim_words( $text, $num_words = 55, $more = null );
        $desc = wp_trim_words( $desc, 55, '...<p class="wrap-more-link"><a class="more-link" href="' . get_category_link( $cat_id ) . '">' . __("Read more >>", "text-domain" ) . '</a></p>' );
    
     }

    return $desc;
}

Or, if you want to apply the trimming only to specific page template:

add_filter( 'category_description', 'cyb_trim_category_desc', 10, 2 );
function cyb_trim_category_desc( $desc, $cat_id ) {

    // Apply only if we the current page use my-page-template.php
    if( is_page_template( 'my-page-template.php' ) ) {

        // wp_trim_words( $text, $num_words = 55, $more = null );
        $desc = wp_trim_words( $desc, 55, '...<p class="wrap-more-link"><a class="more-link" href="' . get_category_link( $cat_id ) . '">' . __("Read more >>", "text-domain" ) . '</a></p>' );
    
     }

    return $desc;
}

You just need to define when you want to apply the trimming and apply the propper conditional.

A possible problem is that you are using category.php for the categories list. That template is intended to display a list of posts that belongs to some category and you should use it for that. You should build the categories list in another template file, maybe a custom page template, so you can use is_page_template() conditional just like the last example above.

UPDATE

As I said before, you should avoid the use of category.php template file to list your categories. category.php template file is intended to list posts that belongs to specific category and you may end up with problems because you are using it for other purpose.

For example, in the image you added to the question, I can see the class category-2 on body element. That means that WordPress made a query to get posts from category with ID = 2 but then, when category.php template is reached, you wasted that query and made another one to list the categories. That is wasting resources that cost money; additionally, you may end up with problems just like you are exprimenting. What happen if category with ID = 2 has not posts? What is the logic for that situation in your theme/plugins/WordPress core?

Instead, you should use a specific page template file to build the categories list. For example, you could create the template page-categories-list.php:

<?php
/**
 * Template Name: Categories list page
 */


 // Here the code to build the categories list

?>

Now, create a new page, select "Categories list page" template and instroduce the conditional in the filter for category description:

add_filter( 'category_description', 'cyb_trim_category_desc', 10, 2 );
function cyb_trim_category_desc( $desc, $cat_id ) {

    // Apply only if we the current page use my-page-template.php
    if( is_page_template( 'page-categories-list.php' ) ) {

        // wp_trim_words( $text, $num_words = 55, $more = null );
        $desc = wp_trim_words( $desc, 55, '...<p class="wrap-more-link"><a class="more-link" href="' . get_category_link( $cat_id ) . '">' . __("Read more >>", "text-domain" ) . '</a></p>' );
    
     }

    return $desc;
}

Now, you should have the categories page list with a description excerpt and categories archive with full description and without problems if the category has posts or not. And more importantly, without wasting the resources from quering posts that you are not going to use.

7
  • I don't understand that, anyway I would add that also to the answer.
    – cybmeta
    Commented Sep 14, 2015 at 10:31
  • Also, as I read the source, the second parameter of the filter is the complete category object, and not the ID of the category :-) Commented Sep 14, 2015 at 10:31
  • No Pieter, the second parameter of the filter is the category ID. Try yourself to var_dump( $cat_id ). I'm not going to add nothing else to the answer right now. I don't understand when and where the OP want to apply the filter.
    – cybmeta
    Commented Sep 14, 2015 at 10:35
  • Hi cybmeta you were my savior the last time:) I will try to add images to my question
    – tali
    Commented Sep 14, 2015 at 10:41
  • Thanks for that info. The issue was that I'm not near a computer to test it. The sources are then all wrong as all states it to be the category object :-), strange. This does add a restriction to the filter as only the ID is passed. I agree, I'm also not sure what is needed by the OP, but I hope that everything works out for your answer :-) Commented Sep 14, 2015 at 10:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.