How to pass a parameter to a block?

#1
Hello,

I display a category with products. The display of products is done in a products.tpl file.
For each product, I need to display a special block. For this I created a module with ESI block.

This is a sample of the products.tpl file
Code:
{foreach from=$produits_categories key="i" item="product"}
<div class="product_block">
<p>{$product.description</p>
<div class="special_content">
{hook h="litespeedEsiBegin" m="mycustomblock" field="widget_block" tpl="module:mycustomblock/mycustomblock_product_bouton.tpl"}
{widget_block name="mycustomblock"}
{include 'module:mycustomblock/mycustomblock_product_bouton.tpl'}
{/widget_block}
{hook h="litespeedEsiEnd"}
</div>
</div>
{/foreach}
This is the content of the tpl file (mycustomblock/mycustomblock_product_bouton.tpl) from my module
Code:
<p class="launchJS" productid="{$product.id_product}">{l s='Do something'}</p>
Sometimes $product appears to be NULL, sometimes it shows only the first product id.
I have two cases of generated HTML content.
First :
HTML:
<div class="product_block" id="1">
<p>Product description 1</p>
<div class="special_content">
<p class="launchJS" productid="1">Do something</p>
</div>
</div>
<div class="product_block" id="2">
<p>Product description 2</p>
<div class="special_content">
<p class="launchJS" productid="1">Do something</p>
</div>
</div>
Second :
HTML:
<div class="product_block" id="1">
<p>Product description 1</p>
<div class="special_content">
<p class="launchJS" productid="">Do something</p>
</div>
</div>
<div class="product_block" id="2">
<p>Product description 2</p>
<div class="special_content">
<p class="launchJS" productid="">Do something</p>
</div>
</div>
It seems the difference depends of browsers so maybe a problem with cookies. In all cases I am not logged into my account.
In case 1, if i go to account page, the account fields are prefilled that's why I think it's a story with cookies.
In case 2, if I go to account page, the account fields are empty.

Anyway, in these 2 cases, I have a problem. In case 1, we can see that '<p class="launchJS" productid="1">Do something</p>' has always the id of the first product found.
So is there something I can do to pass the correct value of the $product variable to my ESI block?

As additional info, this is the part of my htaccess file related to LSCache:
Code:
<IfModule Litespeed>
RewriteEngine On
RewriteCond %{HTTP_COOKIE} my_cookie_admin [NC]
RewriteRule .* - [E=Cache-Control:no-cache]
</IfModule>
### LITESPEED_CACHE_START - Do not remove this line, LSCache plugin will automatically update it
# automatically genereated by LiteSpeedCache plugin: https://docs.litespeedtech.com/lscache/lscps/
<IfModule LiteSpeed>
CacheLookup on
RewriteEngine on
RewriteCond %{HTTP_COOKIE} !PrestaShop-
RewriteRule .* - [E=Cache-Control:vary=guest]
</IfModule>
### LITESPEED_CACHE_END
 
#3
In the CategoryController.php, I assign a variable
Code:
$this->context->smarty->assign('isAdmin', $isAdmin);
I want to show this code
Code:
<p class="launchJS" productid="1">Do something</p>
only if I am admin so basically in my products.tpl I have
Code:
{if $isAdmin}<p class="launchJS" productid="{$product.id_product}">Do something</p>{/if}
but if admin is the first to go to this page then cache is generated and all other users see the same content and I don't want that other users see this content.
Yesterday, you helped me and it was useful in a single product page context.

If I can avoid to use ESI I am ok with this but I don't know how to proceed.
 
#5
I outputted the content of '$smarty.cookies' ( with {$smarty.cookies|@var_dump}) and it is exactly the same between all browsers. It seems that if the admin goes to the category page then all users have the same html content and exactly the same content for '$smarty.cookies'.
Even the $smarty.cookies.PHPSESSID is the same!
 

serpent_driver

Well-Known Member
#6
If you are logged in as Admin and if no-cache rule for Admin cookie still exists only the Admin sees the cookie name.

{$smarty.cookies.my_cookie_admin} == my_cookie_admin

It seems that if the admin goes to the category page then all users have the same html content and exactly the same content for '$smarty.cookies'.
Even the $smarty.cookies.PHPSESSID is the same!

That's logical! You show all cookies with the dump, but you do not impose any conditions on this display.
Correct would be this, so only the Admin sees cookies, but nobody else.
Code:
{if isset($smarty.cookies.my_cookie_admin)}
{$smarty.cookies|@var_dump}
{/if}


Code:
{if isset($smarty.cookies.my_cookie_admin)}
<p class="launchJS" productid="{$product.id_product}">Do something</p>
{/if}
Is the same as with PHP, so nothing goes to anywhere. Isset cookie_name is global and therefore available everywhere.
 

serpent_driver

Well-Known Member
#7
FYI: If a page is cached there is no more PHP or Smarty and therefore no Session and no Session id. Unless you are logged in as admin and he has no cache.
 
#8
That is exactly my point. Once the page is cached I cannot test $smarty.cookies.my_cookie_admin or my variable $isAdmin. As the admin visits a page, the cache is cleared for this page as set in the htaccess but it caches the page and any user will see the same content as the admin. That's why I was thinking that I could use ESI blocks in this context.
Eventually, is there any way to have separated cache for employees (admins) and for other users?
 

serpent_driver

Well-Known Member
#9
Again, if no-cache rule for Admin still exists you don't have to care about the content that is only for the admin, because only the Admin sees it. $isAdmin doesn't work because it is binded to PHP session, but you don't have a session if page is cached, so forget this variable. Only
{if isset($smarty.cookies.my_cookie_admin)}{/if} works.


Eventually, is there any way to have separated cache for employees (admins) and for other users?
Theoretically yes. With this code you set an additional cache vary, so the admin with cookie for the admin gets an own cache copy that other users don't get because other users don't have admin cookie, but this rule works global on every URL. But the problem is, that you can't use this cache vary due to no-cache rule for the admin.

Apache config:
<IfModule Litespeed>
    RewriteRule .* - [E=cache-vary:my_cookie_admin]
</IfModule>
As the admin visits a page, the cache is cleared for this page
Cache isn't cleared(purged). no-cache only means don't cache it (for the admin) if there is a rewrite rule. It doesn't purge anything.
 
Last edited:
#10
For now, I leave the subject aside because I had short time to test it.
I have to master the subject to avoid surprises between different user contexts (employees, clients, not logged in users, ...). Litespeed has wonderful caching possibilities but it can be very dangerous if we don't use it perfectly.
Anyway, thank you for your help. I'll be back later to work on this subject again :)
 
#12
I think I was very clear.
It's really simple. I am in a category page which displays products.
So in the tpl file, there is a loop for showing products, this is my code working correctly (without Litespeed)
Code:
{foreach from=$produits_categories key="i" item="product"}
<div class="product_block">
<p>{$product.description}</p>
<div class="special_content">
{if !empty($isAdmin)}<a href="{$actionLink}?productid={$product.id_product}">Do administrative action</a>{/if}
</div>
</div>
{/foreach}
The context :
I am logged in as administrator. I go to the front page. For each product, I have a button allowing to run an administative action on each product.
If I am not an administrator, I don't see the button.

The smarty $isAdmin variable is set in the CategoryController.php.

So the problem (with Litespeed) :
I am the administrator, I go to a category page then the page is cached => All users see the button.
 

serpent_driver

Well-Known Member
#13
Indepently from anything you describe if you have admin cookie set and no-cache rule for the admin's cookie exists it is impossible that anything is cached! If all users see this button either the admin doesn't have this cookie and|or there is no no-cache rewrite rule!

Actually logical, right?

As long as you cannot ensure the above condition, you can save yourself any thought of installing said function.
 
Top