MyBB Community Forums

Full Version: Returning array to template variable
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hey folks, I'm back.

I was wondering, how do I go about returning a set of values to a template variable? Is that even possible? 

What I want to do is usually quite simple, I want to call a series of rows from a table, then print out their data in a particular place on the page.  In my case, I have {$products} assigned in my template, and I want to do something like:

$products = "<p>' . $product['productName'] . '</p>

And repeat this until every result has been rendered out (using the following while statement):
while($res = $db->fetch_array($query))

Any suggestions?

You would use $res['productName'], not $product['productName'].
Sorry that's what I meant. But then, how do I assign that variable to the $products var in my template and have it repeat for every result?
I may need to look at your code a little more to get a better idea on how you would do it in your specific instance, but the way this is done is generally to evaluate the template on each iteration of the loop. This is not PHP code that will be specific to your project, per se, so modify as you need.

// Get results from your database query. Rename your variables as needed.    
while($querydata = $db->fetch_array($query)) {
        $productID = (int) $querydata[‘id’];
        $productName = htmlspecialchars($querydata[‘product_name’]);
        $productDate = '('.my_date('F d, Y', $querydata['date']).')';
        // Put any other variables here. 

        // Add a product and parse all of the above variables. Add it to {$projects} variable. 
        eval("\$products .= \"".$templates->get(“your_product_template”).”\”;”);
// Evaluate final template, and load the full projects list {$products}
eval("\$product_container = \"".$templates->get(“your_product_container_template).”\”;”);

// In further templates, use {$project_container} to display the full project list. 
// The container is not technically necessary. You could use {$projects} instead, but using a container is good practice, 
// as it allows you to put your product list within a <div> and add additional styling and structure. 

When your plugin code looks like the above (which variables replaced with the ones corresponding to your database and code), you will need two templates. The first template will be a product template, which will be for each individual product. You can use your variables ($productID, $productName, $productDate) like normal in this template.

The second template is your product container template. In this template, you will need to have a {$products} variable. This variable stores the full list of parsed products that were generated by your code. You do not need to use any of your other variables in this template. The full parsed list of products is already stored by the {$products} variable.

Last, to display the list of products, your page must have the template variable {$product_container} in place. If, for example, you are displaying these on the index page, you will need to modify your index template for your theme to have this variable.

Modify this code to serve your needs, but this should give you the general idea. This is how I’ve always approached this functionality in my plugins, so it has always worked well for me.

-Darth Apple
That makes a lot of sense, thank you very much. I'll give it a go shortly, and I'll report back.

You guys have been great. This is my first plugin so I'm a little 'tardy
Haha, no worries there! We are always glad to help where we can.

MyBB's plugin API is pretty well documented, but there is always a situation where there is something that is a little unclear. Looking at other plugins usually is a great way to get a sense of how these things are usually done. It's pretty simple once you get the hang of the basics. Smile
So, I've had a tinker around and I've got the data printing, just not in their template if that makes sense.

$template = '<div class="grid-item"><center><img src="{$productImg}" width="80%"><h4>{$productName}</h4>';

So I created this template named "paypalShopTemplateItem", which is for every individual product, however the data does not filter into it. This is the code I ended up with: 

        $query = $db->write_query("SELECT * FROM " . TABLE_PREFIX ."paypal");
        while($res = $db->fetch_array($query)) {
            $productID = (int)$res['productID'];
            $productName = htmlspecialchars($res['productName']);
            $productImg = $res['productImg'];
            $products = $productID . $productName . $productImg;
            eval("\$products .= \"".$templates->get("paypalShopTemplateItems")."\";");
        eval("\$product_container = \"".$templates->get("paypalShopTemplateProducts")."\";");
When the line with "$products =" is removed, nothing is outputted. Also, it only displays the most recent table entry
            eval("\$products .= \"".$templates->get("paypalShopTemplateItems")."\";");
        eval("\$product_container = \"".$templates->get("paypalShopTemplateProducts")."\";");

It sounds like there is a mismatch between the variables your code is creating, and the variable the templates expect.

In your code now, the paypalShopTemplateItems (with the s at the end) is the template that is for every individual product. This is what your code expects to put these variables into.

The paypalShopTemplateProducts template is the container. It must contain {$products} for it to load the products. Once you get these set up correctly, you should be able to remove the "$products = $productID . $productName . $productImg;" line. It might interfere with what the templates expect.

Otherwise, everything looks correct. One thing I should add: Make sure to use htmlspecialchars on the $productImg = $res['productImg'] line as well. If you leave it out, it leaves an XSS vulnerability.

Let me know if this works!
So I was trying to figure it all out, because I had no idea why this wasn't working. My small brain made a typo. The template was Item not Items.

That's working as expected now. Thank you. Time to move onto forms!