Support » Developing with WordPress » Extending a function

  • How can I insert this:

    <strong> <?php foreach((get_the_category()) as $category) { echo $category->cat_name . ' '; } ?> </strong>

    to this:

    add_shortcode('incipit', 'translate_incipit');
    function translate_incipit() {
      global $post;
      $german = get_post_meta( $post->ID, 'incipit_de', true );
      if ( 'de_DE' == get_locale() && ! empty( $german )){
         return $german;
      } else {
         return get_post_meta( $post->ID, 'incipit_it', true );
      }
    }

    what I want to do is having the category name printed before the value of “get_post_meta” , having in mind that I should print the name of the category eventually translated

    The page I need help with: [log in to see the link]

Viewing 6 replies - 1 through 6 (of 6 total)
  • Moderator bcworkz

    (@bcworkz)

    The code you want to insert needs to be modified for use in a shortcode callback because shortcode callbacks must not ever echo out content. Instead, all output should be collected into a single variable. Before starting a foreach loop, initialize a variable by assigning an empty string or the first part of the output. For example:
    $output = ''; or $output = '<strong>';

    Anywhere content is output, such as with echo, instead concatenate the output to $output. For example:
    $output .= $category->cat_name . ' ';
    But if the category name needs to maybe be translated it will be more complicated than this. Addressed below. Also, are you sure about cat_name? That’s an unusual object property if we’re using WP_Term objects. I think you want $category->name.

    After the foreach loop completes, don’t forget the closing strong tag:
    $output .= '</strong>';

    Where all of this goes into your current shortcode callback depends on where you want output to occur in relation to post meta content. Before or after? Then add the category code before or after the post meta code.

    Modify the post meta code. Instead of returning content, concatenate post meta content to $content. In the end after all is said and done, you will finally do:
    return $content;

    Now, how to work in possible translations of category names. The first thing your function should do is get the locale’s 2 character language code so you can use it to get the right translation. Let’s say the language code is assigned to $lang. Then you could get the right language’s post meta with something like:
    $output .= get_post_meta( $post->ID, 'incipit_'.$lang, true );

    You’d do something similar for category names, except there is only term meta for non-Italian languages. If the locale language is “it”, $category->name is fine, but otherwise it has to come from term meta. Thus you need to determine the right value to output before concatenating it to $output. Instead of just
    $output .= $category->name . ' ';
    do something like:
    $output .= 'it' == $lang ? $category->name : get_term_meta( category->term_id, 'tipologia_'.$lang, true) .' ';

    In case you’re not familiar with the $condition ? 'its true':'its false'; construct, it’s a kind of shorthand for typical if/then/else statements. It’s called a “ternary” statement. It’s equivalent to:

    if ( $condition ) {
      'its true';
    } else {
      'its false';
    }

    Will this become the code I was asking for in your other topic about filtering a taxonomy for German? Then I guess I’m answering my own question 🙂 No filtering is necessary with this approach.

    Do note that this requires you to alter the meta key names to be similar to tipologia_de, tipologia_en, tipologia_fr, etc. This means updating the code that saves term custom field data related to translated term names.

    Thread Starter sacconi

    (@sacconi)

    First of all I made a mistake about the shortcode I needed to use. That said, it makes sense a function like this?

    add_shortcode('description', 'translate_desc');
    function translate_desc() {
      global $post;
    
    $content= get_post_meta( $post->ID, 'description_it', true );
    
      $german = get_post_meta( $post->ID, 'description_de', true );
     
    
     if ( 'de_DE' == get_locale() && ! empty( $german )){
          $output .= $category->name . ' '. $german ;
      } else {
         $output .= $category->name . ' '. $content ;
      }
    }

    I have just transformed the post meta content into a variable, or better 2 variables, according to the language, than I keep the conditional structure and change the output according to the language

    Thread Starter sacconi

    (@sacconi)

    I see now that I havent solutioned the category term name in german

    Moderator bcworkz

    (@bcworkz)

    Whether the meta data exists or not does not invalidate the shortcode. You’re approach is fine if it works for you. It’s more cumbersome than what I was suggesting, but whatever works is good. However, you’d need to modify the code anytime you add another language. I was trying to avoid that by dynamically constructing the meta key based on the current locale’s language. Thus the shortcode code wouldn’t need to change when another language is added.

    But you’d still need additional meta box fields in the term editor screen, as well as the save code for each language. Right now you apparently have none of this in place. It’s the same concept as you’ve already done for custom taxonomy terms. Just be sure you’re thorough in adjusting copies of what you’ve already done to work for categories as well. For example, when you rename the function name, be sure the name in the add_filter() call is also changed to match. Be sure every instance of the custom taxonomy name is changed to “category”.

    Thread Starter sacconi

    (@sacconi)

    Since I desire more languages I’ll try to undestand better your code

    Thread Starter sacconi

    (@sacconi)

    I think my own code has some errors because the shortcode outputs nothing. I can’t see where is the problem. I checked the code with https://phpcodechecker.com/

Viewing 6 replies - 1 through 6 (of 6 total)
  • You must be logged in to reply to this topic.