If-else and for loops not working in HTML for new XBlock

Hi!
I’m trying to pass data from python file to HTML file, but standard syntax is not supported, HTML file code below

<p>EdlyCarouselXBlock: count is now
    <span class='count'>{self.count}</span> (click me to increment).
    {{ self.count }}
    {% if self.count%}
    <p>Simple If</p>
    {%endif%}
</p>
<p id="decrement">(click me to Decrement).</p>
</div>

It is supporting a single bracket to access values {self.name} , for loops & if-else it throws an error.

Tried using python 3.6.5 & 3.8.0, the same issue on both versions, any help would be appreciated.
Same issue in the lms/cms as well.
cc: @regis @braden

Solve the issue, posting the solution for future references.
Default xblock is created without using Django templating so we need to configure it manually.

Following default student_view function is added

def student_view(self, context=None):
    """
    The primary view of the SampleXBlock, shown to students
    when viewing courses.
    """
    html = self.resource_string("static/html/sample.html")
    frag = Fragment(html.format(self=self))
    frag.add_css(self.resource_string("static/css/sample.css"))
    frag.add_javascript(self.resource_string("static/js/src/sample.js"))
    frag.initialize_js('SampleXBlock')
    return frag

so in order to involve Django template rendering make the following changes.
include template and context

from django.template import Context, Template

# Add this method in your xblock class

def render_template(self, template_path, context={}):
    template_str = self.resource_string(template_path)
    template = Template(template_str)
    return template.render(Context(context))

def student_view(self, context=None):
    """
    The primary view of the SampleXBlock, shown to students
    when viewing courses.
    """
    frag = Fragment()

    html = self.render_template("static/html/sample.html", {'count': self.count})
    frag.add_content(html)
    frag.add_css(self.resource_string("static/css/sample.css"))
    frag.add_javascript(self.resource_string("static/js/src/sample.js"))
    frag.initialize_js('SampleXBlock')
    return frag

It looks like you might be trying to use Django template syntax, but your XBlock code is trying to render it as a Mako template (EDIT: oh, not even mako template, from your own answer I see it was plain python format). They are two different template languages used Open edX to render HTML from python.

I strongly recommend using Django templates instead of Mako, so instead of calling mako.lookup.TemplateLookup(...).get_template(...).render_unicode(...), I’d suggest calling xblockutils.resources.ResourceLoader.render_django_template().

By the way, using render_django_template() (and passing in i18n_service=self.runtime.service(self, 'i18n') as a keyword argument) is the only easy way to get translation files (i18n/l10n) that come with your XBlock to be used by your template, instead of the default platform strings.


All that said, if you can avoid using server-side templates at all, and use JavaScript-based templates (like React) instead, even better!

1 Like

Thank you for quick response, I was able to solve it and you are right I was missing Django Template reference.