Custom Ratings for Theme, Proper way to Refactor Code and Clean up Template File

Always try to keep your code DRY. Your code is basically a large violation of this principle. In order to refactor this, let’s think about the steps that your code goes through

  • determine whether it is overall, marketing, sales, …
  • get those ratings from db
  • convert ratings to name of template
  • get the template

The only difference between all of your functions is the first part. So this is the only thing each function should do. Since the field names all have the same prefix, you can use that as well.

function rating_helper($name) {
    $ratings = get_field('provider_ratings_' . $name);
    // template stuff
}

function rating_overall() {
    rating_helper('overall');
}
function rating_marketing() {
    rating_helper('marketing');
}
// ...

The next thing is that big block of if/else. There is no restriction with dots in template names, so no need to convert the numbers to names. If you name them templates templates/star-rating/rating-4.5.php, rating-3.0.php, … and rating.php (for the case of == ''), then simply include them like so

function rating_helper($name) {
    $ratings = get_field('provider_ratings_' . $name);
    echo get_template_part('templates/star-rating/rating', $ratings);
}

I am using the second parameter of get_template_part() here because .. well WordPress offers it and does the string concatenation for you, so this is a bit cleaner in my opinion.


If the only thing changing in the templates themselves is the CSS class / amount of stars displayed, you do not need separate templates at all! You can use the $ratings variable from the rating_helper() function.

function rating_helper($name) {
    $ratings = get_field('provider_ratings_' . $name);
    echo get_template_part('templates/star-rating/rating');
}

and templates/star-rating/rating.php (preg_replace() isn’t necessarily bad, but a bit of an overkill)

<?php
if ($ratings != '') {
    $css_class = substr($ratings, 0, 1) . substr($ratings, 2, 1);
} else {
    $css_class="0";
}
echo '<div class="class-name-' . $css_class . '">

If you need to display various amount of stars, you can convert them to integer with floor() and add a half star if necessary

$stars = floor($ratings);
foreach ($i=0; $i<$stars; $i++) {
    echo '<span class="star"><i class="nc-icon nc-ic_star_24px"></i></span>';
}
// floor(x.0) == x.0
// floor(x.5) != x.5
if ($stars != $ratings) {
    // echo half star
}