1

I have to generate something like star rating and I have to generate some html for styling ect.

        <div class="star on"><i>*</i></div>
        <div class="star on"><i>*</i></div>
        <div class="star on"><i>*</i></div>
        <div class="star"><i></i></div>
        <div class="star"><i></i></div>

I want to render using a twig function passing active stars parameters.

{{ stars(4) }}

Is correct use twig functions for generate html code? Or maybe should I use {% include ... %}

2 Answers 2

4

No need in overengineering for such simple task.

If you generate your array in Controller, then it could look like this:

$stars = array(
    true,
    true,
    true,
    false,
    false,
);

Then you could render your HTML in Twig:

{% for star in stars %}
    <div class="star{{ star ? ' on' }}"<i>{{ star ? '*' }}</i></div>
{% endfor %}

In case if you would like to operate with Twig only, I recommend you to use macro:

{% macro stars(stars, total) %}
    {% for item in 1..total %}
        {{ item }}<br>
        {% if item <= stars %}
            <div class="star on"><i>*</i></div>
        {% else %}
            <div class="star"><i></i></div>
        {% endif %}
    {% endfor %}
{% endmacro %}

If you've defined your macro in the same template, you should call it via _self, if in another file - just like a function, but not forget to import your file into needed twig. See chapter about macros (linked above).

Following call will produce HTML structure that you described in your question:

{{ _self.stars(3,5) }}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your response. I don't have an array in the controller, just an integer ex. 5 for generate 5 stars. I'm evaluating use a twig function because I don't need to repeat the foreach block and other logic related. I render this stars in many templates. I think the macro solution is better, but I can't define the macro in each template. DRY!!. and then I need to import the macro in every template. Why do you say use a function is a overengineering?
You don't have to define macro in each template. You have to define it once, and then just import it. Its common practice.. And - I say that function/macro is overeng. since I think it is possible to reach your goal using controller and native twig methods :)
2

See the Extending Twig section of its docs. According to the table in the first section on that page, using functions for content generation is natural. I create a lot of Twig functions and I suggest you create one to solve your problem.

BTW, your function can render a separate template with HTML code — do not generate the HTML code right in your Twig function's PHP code. To render a separate template from your Twig function, inject the service_container service into it, get the templating service and call the render() method on it:

return $this->container->get('templating')->render($pathToYourCustomTemplate);

Usually, it's best to inject the needed services individually, but if you inject the templating service instead of service_container, you'll get a cyclic dependencies problem. That's why injecting the whole container into Twig extensions is a reasonable exception.

1 Comment

Thanks for your answer elnur! I've created the twig function, but I generated the html inside php function. Can you tell me where I can find in docs how to render a separate template with html?

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.