'Pass variable from custom hook to TPL file

I have created a custom module. Which simply registers a hook, whose only function is to obtain a list of products of a specific category.

The hook works perfectly. Then I call it from a TPL file, it is called correctly, but when I try to get the hook variable from the TPL file, I can't.

This is the code of my Hook.

    public function hookDisplayCaronteCategories($params){

        if (array_key_exists('max', $params)) {
            $max = $params['max'];
        }
        else{
            $max = 1000;
        }

        $category = new Category(
            $params['id_category'], //id de la categoría
            (int)Context::getContext()->language->id // id del idioma
        );
        $caronteProducts = $category->getProducts(
            (int)Context::getContext()->language->id, //id lenguaje
             1, //número de páginas
             $max, //productos por páginas
             'date_add', //order by
             'DESC', //order way
             false, //get total
             true, //mostrar activos
             false, // random
             1, // random_number_products
             true, //check access
             Context::getContext() //context
        );
        $this->smarty->assign(array('caronteProducts', $caronteProducts));
        return $this->display('http://localhost/rapture/themes/classic_child/templates/cms/page-6.tpl');
    }

The var_dump function at the end correctly displays the product data.

enter image description here

However, if I do a var_dump from the tpl, the function returns null. This is how I call the hook from the tpl.

      {hook h="displayCaronteCategories" id_category=11}
      {$caronteProducts|var_dump}

And this is what I get:

enter image description here

How can I get the hook variable in the tpl file?

Thank you.



Solution 1:[1]

tldr: you need to send ajax request

As far as I know, tho. There are three ways to render page:

  • sending whole html page (with jinja params like you do in your example code)
  • sending json to client app
  • sending html with ajax to replace some element's inners

First method requires whole page reload.

I try to avoid writing js code when it's possible. Here is a nice js library htmx, which allows you to create axaj requests with html attributes.

main.py:

from flask import Flask, render_template, request

app = Flask(__name__)


@app.route('/')
def startup():
    return render_template('Loans.html')


@app.route('/bsearch', methods=['POST'])
def bsearch():
    '''Returns book name html'''
    found = "T"

    try:
        book_id = int(request.form["bid"])
        book_id = book_id if book_id >= 0 else None
    except BaseException:
        book_id = None

    i = 'idk what is `i` but that does not matter anyway'
    info = {i: [
        "Book 0",
        "Book 1",
        "Book 2",
        "Book 3",
        "Book 4",
        "Book 5",
    ]}

    
    if found == "T":
        try:
            html = info[i][book_id]
        except BaseException:
            html = "Book is not found"
    else:
        html = "Book is not found"

    return html


if __name__ == "__main__":
    app.run(debug=True)

Loans.html:

<html>

<head>
    <script src="https://unpkg.com/[email protected]"></script>
</head>

<body>
    <form hx-post="{{ url_for('bsearch') }}" hx-target="#returned_html_goes_here">
        Book id
        <br>
        <input type="text" name="bid" />
        <input type="submit" value="Search for books" /> 
    </form>
    <b>Book name: </b> <div id="returned_html_goes_here"></div>
</body>

</html>

You still can manually write ajax request function, but I think that's a waste of time when you can do the same thing with html.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1