Prestashop subcategories menu inside a subcategory - prestashop

I am trying to show the subcategories menu of prestashop categories inside all subcategories. By default you only can see the subcategories menu inside a category but you cant see the "brother" subcategories of a subcategory.
I think I only need to make this code to work inside a subcategory because this code works well inside a category:
{foreach from=$subcategories item=subcategory}
<li > <a href="{$link->getCategoryLink($subcategory.id_category, $subcategory.link_rewrite)|escape:'htmlall':'UTF-8'}"
class="cat_name">{$subcategory.name|escape:'htmlall':'UTF-8'}</a>
</li> {/foreach}
Any ideas?
Thanks so much

as always i don't give you a full code, but i tell you how to do it.
in smarty you need to create a function that takes as param number of parent category,
and in this function you need to use Category::getChildren( $id_category );then in smarty you need only take a loop through the smarty function.
regards
and sorry for my English.

For to start i would have created a override file in /override/controllers/, named CategoryController.php
And add this:
<?php
class CategoryController extends CategoryControllerCore
{
public function displayContent()
{
// Get the global smarty object.
global $smarty;
// Get current category's parent.
$parent_category = new Category($this->category->id_parent, self::$cookie->id_lang);
// Get parent category's subcategories (which is current category's siblings, including it self).
$category_siblings = $parent_category->getSubCategories((int)self::$cookie->id_lang)
/* Assign your siblings array to smarty. */
$smarty->assign(
array(
"category_siblings" => $category_siblings
)
);
/* This we run the normal displayContent, but pass the siblings array to
category.tpl */
parent::displayContent();
}
}
?>
And in product-list.tpl file:
<ul>
{foreach from=$category_siblings item=elemento}
<li {if $category->id == $elemento.id_category}class="active"{/if}> {$elemento.name} </li>
{/foreach}
</ul>
via Get sibling categories in category.tpl for the current category in prestashop

Related

Laravel 8 - Show database results using for loop (not foreach)

Using Laravel 8: I need to display my data (images saved as image names in the db) in 8 columns on the blade page. So if I have a db row count of 18, I would equally distribute the 18 in 8 columns (+remainder if any but that is irrelevant to this q - so, 18 images/8 cols = 2 (+2 remainder)). I can do this using two for loops so:
#for ($col=1; $col<=8; $col++)
#for ($img=1; $img<=$image_percolumn; $img++)
<img src="images/{{$featuredbrands->brandLogo'}}">
#endfor
#endfor
$featuredbrands is being passed from the controller as an array:
class HomeController extends Controller{
public function index(){
$fbrands = brands::join('subscriptions', 'brands.id','=','subscriptions.brandID')
->where('subscriptions.packageID','=',2)
->get(['brands.id','brands.brandLogo','brands.logoLink']);
return view('home',[
'featuredbrands'=>$fbrands
]);
} // end function
} // end class
I am getting the following error for the <img src...> line in my blade page:
Property [brandLogo] does not exist on this collection instance.
To test if I'm passing the data correctly to the blade page, I have tried using foreach to display the images. With foreach, I get the output in one column (so I know that data passed from controller is not the issue).
What is the correct way to reference the image field using the for loop? If that indeed is the problem?
This seems to be much harder than it should be, I am sure I am missing something.
One option - convert your collection to an array, and simply reference elements by key. Something like this:
In your Controller method:
return view('home', [
'featuredbrands' => $fbrands->toArray()
]);
And in your view:
#for ($col = 0; $col <= 16; $col += 2)
<img src="images/{{ $featuredbrands[$col]->brandLogo }}">
<img src="images/{{ $featuredbrands[$col+1]->brandLogo }}">
#endfor
You could also try to do it more the Laravel way, by using the Collection chunk() method, though this also seems very clunky here. Maybe something like:
#foreach ($featuredbrands->chunk(8) as $row)
#foreach ($row->chunk(2) as $col)
#foreach ($col as $brand)
<img src="images/{{ $brand->brandLogo }}">
#endforeach
#endforeach
#endforeach

Is it possible to not omit some opts on the outermost element in a custom Riot tag?

I'm using RiotJS v3.9
I've written a custom tag that accepts a few opts. The problem is that the markup it generates includes all of those opts on the outermost element, in addition to the interior tags where I explicitly deposit them. I do not want any opts to appear on the top element unless I make that happen.
In this case, my custom tag display a list of items. One of the opts it accepts is the value for a specific data- attribute on each list item. So, I want data-something={opts.itemSomething} to appear on each list item, but I do not want that to appear on the wrapper.
// my-list.tag
<my-list>
<ul data-something={ opts.something }>
<li
each={ item in opts.items }
data-something={ parent.opts.itemSomething }
>
{ item }
</li>
</ul>
</my-list>
Using it:
<my-app>
<my-list
something="parent-value"
item-something="child-value"
items={['one', 'two', 'three']}
/>
</my-app>
What it emits into the page:
<my-list something="parent-value" item-something="child-value">
<ul data-something="parent-value">
<li data-something="child-value"> one </li>
<li data-something="child-value"> two </li>
<li data-something="child-value"> three </li>
</ul>
</my-list>
I don't want the emitted <my-list> tag to have either the parent-value or the child-value on it. I only want those attributes to appear on the <ul> and <li>, like I coded it.
// bad output
<my-list something="parent-value" item-something="child-value">
// good output
<my-list>
Is this possible?
Also, I know from working with React that I'm likely to encounter future cases where I want some of the opts to appear on the wrapper while hiding others. So, ideally I'd like to know how to control this behavior on a per-opt basis.
you can remove the unwanted attributes in both the "updated" and "mount" event.
check this demo
However I strongly suggest you to switch to riot#5!!

Razor Pages Tag Helper with Dynamic Parameters Assigning Current Url as Href

I'm running into trouble trying to set anchor tag helper parameters dynamically and looking for some help.
I have a nav that is a view component inside the shared _Layout.cshtml page that populates departments from a model.
#model List<DepartmentModel>
<ul class="nav">
#foreach (var d in Model)
{
<li>
<a asp-page="catalog/departments" asp-route-departmentName="#d.Name" asp-route-departmentId="#d.Id">#d.Name</a>
</li>
}
</ul>
Here is the InvokeAsync() from my View Component class
public async Task<IViewComponentResult> InvokeAsync()
{
var departments = _catalogService.GetNavDepartments();
return View(departments);
}
When I first launch the page, all the hrefs are populating correctly.
"catalog/departments/department-name-1/department-id-1"
"catalog/departments/department-name-2/department-id-2"
"catalog/departments/department-name-3/department-id-3"
If I click on one of the links, like the first link for example, I go to the proper department page "catalog/departments/department-name-1/department-id-1"
However, once I click that first link and navigate to the respective page, all the nav hrefs populate to the current url "catalog/departments/department-name-1/department-id-1" instead of the originally generated hrefs. This makes it so I can't navigate to another department.
Here is my route in the Startup.cs
services.AddRazorPages().AddRazorPagesOptions(options => {
options.Conventions.AddPageRoute("/Catalog/Departments", "{dName}/{dId}");
});
Based on the convention above, it eliminates the "catalog/department" piece of the url but I added it in this description for a sense of what I'm trying to accomplish. Even if I add this template to the page that populates the "catalog/departments" url, I get the same result.
#page "{dName}/{dId}"
Can anyone help me figure out what I am missing? Thanks in advance!
******** UPDATE ********
Currently, the only way I am able to get this to work is by adding the cache tag helper.
<cache>
<ul class="nav">
#foreach (var d in Model)
{
<li>
<a asp-page="catalog/departments" asp-route-departmentName="#d.Name" asp-route-departmentId="#d.Id">#d.Name</a>
</li>
}
</ul>
</cache>
This doesn't seem like a proper fix. Seems more of a hack then anything. Anybody have any ideas? Thanks!

Need assistance with Prestashop label code

I want to add a Best Seller label to products in Prestashop 1.6, on both product list and product pages, the same as the labels for New Products. Can anybody point me in the right direction to accomplishing this, if it is possible, i.e will it require a controller etc.
At this stage all I have tried is simply,
{if isset($best_sellers) && $best_sellers|#count > 0}
<span class="bestseller">
<label>{l s='best seller' mod='modulename'}</label>
</span>
{/if}
This did not work. I don't need any help with the css, I can handle that. Thanks
Hello again,
Using some of the information you gave me below I have come up with the following to add a best seller label to my custom module without using an override.
Following is the function:
public function getcustomBestSellersLabel($params)
{
$id_product = (int)$params['product']['id_product'];
return Db::getInstance()->executeS('SELECT `id_product`, `sale_nbr` AS customnbr FROM '._DB_PREFIX_.'product_sale ps WHERE `id_product` = '.(int)$id_product.' ORDER BY `customnbr` DESC LIMIT 5');
}
and in my hook
public function hookdisplayCustomBestSellersTag($params)
{
$id_product = (int)Tools::getValue('id_product');
if (!$this->isCached('custombestsellertag.tpl', $this->getCacheId($id_product))) {
$custombestsellers = CustomModule::getCustomBestSellersLabel($params);
$this->context->smarty->assign(array(
'custombestsellers' => Module::getInstanceByName('CustomModule')->getCustomBestSellersLabel($params),
'id_product' => $id_product,
));
}
return $this->display(__FILE__, 'views/templates/front/custombestsellerlabel.tpl', $this->getCacheId());
}
and in my tpl
{if (isset($custombestsellers) && $custombestsellers)}
<span class="custom-best-seller-label">
<label>{l s='best seller' mod='CustomModule'}</label>
</span>
{/if}
This actually works except for one problem, the LIMIT doesn't work. I have tested it in phpMyAdmin where it does work. I have tested it with LIMIT 5 and there is no change, instead all products in the product_sale database table are showing a label.
Can you give me some advice on how to fix this problem.
Thank you.
It's much more complicated than that, to achieve that you need:
create override of Product.php method called getProductProperties
check if product is in TOP X in terms of sales in PREFIX_product_sale table
if so, mark it as a bestseller by adding a new variable (alternative is to do this directly in SQL statement)
if you'll do everything properly and new variable will be available you would have a chance to use it like this:
{if $product.is_bestseller}bestseller label{/if}

How to check if there is a strikethrough on some text in selenium webdriver?

There are many planbox, which are having same class and ids, inside them there are a number of <p> tags and decorated text.
<div class="planbox">
<p class="baseprice">
<span>
<strike> $70 </strike>
</span>
</p>
<p> New discount price is etc. </p>
</div>
<div class="planbox">
<p class="baseprice">
<span> $70 </span>
</p>
</div>
Now, My test case is - if the base price is strikethrough, only then <p> 'New discount price .. </p> will show, otherwise not.
How to check whether a text is strikethrough or not? And even if we get this how will I check that <p> New discount.. </p> should not show if the text is not striked.
As there is no class in <p> tag on which I can check whether it displayed or not.
One solution in my mind was - add one dummy class in <span> tag and using findChildren('span.dummyCLass') it will result all the webelements having dummyClass.
Now I will check whether web-elements have strike tag or not, and this is the place where I got stuck.
Initially, i was thinking of a Jquery solution, but is it possible to do without adding new class and jquery?
You don't need to add a class to any element to accomplish this task. In general, you don't want to edit the HTML. Another issue is... if you can find the element to add a class, then you don't need to add the class to find the element. :)
The way I approach tasks like these is to find the outermost element that contains all the elements that you are interested in. I refer to this as a "container". What you want to do in this case is to find the containers and loop through them looking for the strikethrough price and for the "New discount price..." text.
The containers are DIVs with the planbox class. The strikethrough price is indicated by the STRIKE tag. The "New discount price..." text is in a P tag. With this info we can write some code. This is Java because I don't know what language you want and I'm not familiar with the Galen framework.
// gets the collection of containers using a CSS selector
List<WebElement> containers = driver.findElements(By.cssSelector("div.planbox"));
// loops through the containers
for (WebElement container : containers)
{
// determine if the STRIKE tag exists
boolean strikeExists = !container.findElements(By.tagName("strike")).isEmpty();
// determine if the "New discount price is..." text exists in the 2nd P tag
boolean discountPriceExists = container.findElements(By.tagName("p")).get(1).getText().trim().contains("New discount price is");
// if both are true log a pass, otherwise log a fail
if (strikeExists && discountPriceExists)
{
// log a pass
}
else
{
// log a fail
}
}
I haven't used much of selenium. But you can port this jquery code to selenium,
//if there is a strike element
if($(".baseprice span strike").length > 0){
//next() will select the sibling of the p tag with baseprice class
$("p.baseprice).next() != undefined){
return true
}else{
return false
}
}
you can use Galen for this. There you can verify certain CSS properties.