I'm looking to generate a hierarchical breadcrumb from a taxonomy term (e.g. grandparent/parent/child) when all I have is the TID of "child". I've been toying around with taxonomy_get_tree(), but it seems quite difficult to do without very heavy iteration. There has to be an easier way.
Thoughts?
Thanks!
Taxonomy Breadcrumb seems to provide this functionality.
If you don't want to use the module, the code might provide inspiration.
This is what I do:
$breadcrumb[] = l(t('Home'), NULL);
if ($parents = taxonomy_get_parents_all($tid)) {
$parents = array_reverse($parents);
foreach ($parents as $p) {
$breadcrumb[] = l($p->name, 'taxonomy/term/'. $p->tid);
}
}
drupal_set_breadcrumb($breadcrumb);
I'll typically stick this in a hook_view() function or hook_nodeapi($op="view") function.
If you are using Drupal 7, Taxonomy Breadcrumb is yet in dev version and you have to code.
A solution more complete could be the follow (put this function in YOUR_THEME_NAME/template.php)
function YOUR_THEME_NAME_breadcrumb( $variables )
{
// init
$breadcrumb = $variables['breadcrumb'];
// taxonomy hierarchy
$hierarchy = array();
if (arg(0) == 'taxonomy' && arg(1) == 'term' && is_numeric(arg(2)))
{
$tid = (int)arg(2);
$parents = array_reverse(taxonomy_get_parents_all($tid));
foreach( $parents as $k=>$v)
{
if( $v->tid==$tid ) continue;
$breadcrumb[] = l($v->name, 'taxonomy/term/'. $v->tid);;
}
}
// rendering
if (!empty($breadcrumb))
{
$output = '<h2 class="element-invisible">' . t('You are here') . '</h2>';
$output .= '<div class="breadcrumb">' . implode("<span class='separator'>»</span>", $breadcrumb) . '</div>';
return $output;
}
}
function yourthemename_breadcrumb( $variables )
{// init
$breadcrumb = $variables['breadcrumb'];
// taxonomy hierarchy
$hierarchy = array();
if (arg(0) == 'taxonomy' && arg(1) == 'term' && is_numeric(arg(2)))
{
$tid = (int)arg(2);
$parents = taxonomy_get_parents_all($tid); dpm($parents);
$parents = array_reverse($parents);dpm($parents);
$breadcrumb = array();
$breadcrumb[] = l('Home', '/');
foreach( $parents as $k=>$v)
{
$breadcrumb[] = l($v->name, 'taxonomy/term/'. $v->tid);;
}
}
// rendering
if (!empty($breadcrumb))
{
$output = '<h2 class="element-invisible">' . t('You are here') . '</h2>';
$output .= '<div class="breadcrumb">' . implode("<span class='separator'>»</span>", $breadcrumb) . '</div>';
return $output;
}
}
Related
I have a function like this:
function colorscheme( $color, $url ) {
return array( $color, $url );
}
How can I fetch them and display them like this (this is an example, it doesn't work):
function fetch_colorscheme() {
foreach() {
echo "<ul><li>$color</li><li>$url</li></ul>";
}
}
Thank you!!
Try this:
$scheme = colorscheme('color', 'url');
echo '<ul>';
foreach ($scheme as $value) {
echo '<li>' . $value . '</li>';
}
echo '</ul>';
Edit:
For multiple color schemes, you can do this:
$schemes = array(
colorscheme('color 1', 'url 1'),
colorscheme('color 2', 'url 2')
);
function fetch_colorscheme($schemes) {
echo '<ul>';
foreach ($schemes as $scheme) {
foreach ($scheme as $value) {
echo '<li>' . $value . '</li>';
}
}
echo '</ul>';
}
I'm sorry, I'm not able to test this at the moment.
I need to display my category tree as a list in a responsive menu.
The idea is to display the highest level categories. and create dynamically a list that will be displayed for each category that has children.
I stumbled upon a code that helped me a bit, but i can't figure how to get the job done.
Here is the code:
<?php
$rootCatId = Mage::app()->getStore()->getRootCategoryId();
function getTreeCategories($parentId, $isChild){
$allCats = Mage::getModel('catalog/category')->getCollection()
->addAttributeToSelect('*')
->addAttributeToFilter('is_active','1')
->addAttributeToFilter('include_in_menu','1')
->addAttributeToFilter('parent_id',array('eq' => $parentId));
$class = ($isChild) ? "sub-cat-list" : "cat-list";
$html .= '<ul class="'.$class.'">';
$children = Mage::getModel('catalog/category')->getCategories(7);
foreach ($children as $category) {
{
$html .= '<li>'.$category->getName()."";
$subcats = $category->getChildren();
if($subcats != ''){
$html .= getTreeCategories($category->getId(), true);
}
$html .= '</li>';
}
$html .= '</ul>';
return $html;
}
$catlistHtml = getTreeCategories($rootCatId, false);
echo $catlistHtml;
?>
Thank you in advance.
you can use this to create category tree:
<?php
$rootCatId= Mage::app()->getStore()->getRootCategoryId();
$categories = Mage::getModel('catalog/category')->getCategories($rootCatId);
$output= '<ul>';
foreach($categories as $category) {
$cat = Mage::getModel('catalog/category')->load($category->getId());
$count = $cat->getProductCount();
$output .= '<li>' . '' . $category->getName() . "";
if ($category->hasChildren()) {
$children = Mage::getModel('catalog/category')->getCategories($category->getId());
$array .= get_categories($children);
}
$output .= '</li>';
}
echo $output . '</ul>';
?>
For the effects of showing / hiding categories and subcategories, you can use plain css or jQuery / Prototype.
I have an array with some items. Each array could have (or not) an subarray, also with some items.
How can I call the subarray in a loop? It is difficult to describe, here is the code. I know the code/syntax is not correct, but the syntax should clarify my problem:
<?php
$subitemsA = array(
'subA1' => array('num'=>65, 'text'=>'Labor', 'url'=>'#'),
'subA2' => array('num'=>44, 'text'=>'Rare', 'url'=>'#'),
);
$subitemsB = array(
'subB1' => array('num'=>0, 'text'=>'subB1', 'url'=>'#'),
'subB2' => array('num'=>0, 'text'=>'subB2', 'url'=>'#'),
'subB3' => array('num'=>0, 'text'=>'subB3', 'url'=>'#')
);
$navArray = array(
'Home' => array('num'=>0, 'text'=>'Home', 'url'=>'#'),
'Info' => array('num'=>0, 'text'=>'Info', 'url'=>'#', 'subArray'=>$subitemsA),
'Sport' => array('num'=>0, 'text'=>'Sport', 'url'=>'#', 'subArray'=>$subitemsB),
);
$html = '';
foreach($navArray as $item) {
$html .= "<li>";
$html .= "<a href='{$item['url']}'><i class='abc'></i>{$item['text']}</a>\n";
if (count($navArray) > 3) {
foreach($navArray.subArray as $subitem) {
$html .= "<li>";
$html .= "<a href='{$subitem['url']}'>{$subitem['text']}</a>\n";
$html .= "</li>";
}
}
$html .= "</li>";
}
The first foreach loop works. But how can I access the subArray of Info and Sport?
You need a three level foreach for this to work -
foreach($navArray as $key => $item) {
$html .= "<li>";
$html .= "<a href='{$item['url']}'><i class='abc'></i>{$item['text']}</a>\n";
foreach ($item as $itemkey => $value) {
if (is_array($value)) { //Now Check if $value is an array
foreach($value as $valuekey => $subitem) { //Loop through $value
$html .= "<li>";
$html .= "<a href='{$subitem['url']}'>{$subitem['text']}</a>\n";
$html .= "</li>";
}
}
}
$html .= "</li>";
}
This is an answer to your question in more general way: How to deal with multi-level nested array using recursion and template.
function parseArray(array $navArray, &$html, $depth = 0) {
foreach ($navArray as $item) {
$html .= "<li>";
// this function use template to create html
$html .= toHtml($item['url'], $item['text'], $depth);
foreach ($item as $subItem) {
if (is_array($subItem)) {
// use recursion to parse deeper level of subarray
parseArray($item, $html, $depth + 1);
}
}
$html .= "</li>";
}
}
function toHtml($url, $text, $depth)
{
$template = '';
if ($depth == 0) {
$template = '<a href=\'{{url}}\'><i class=\'abc\'></i>{{text}}</a>\n';
} elseif ($depth >= 1) {
$template = '<a href=\'{{url}}\'>{{text}}</a>\n';
}
// define more template for deeper level here if you want
$template = str_replace('{{url}}', $url, $template);
$template = str_replace('{{text}}', $text, $template);
return $template;
}
$html = '';
parseArray($navArray, $html);
Just hurrily forge this code out of mind, haven't test it yet. Hope it help.
Regards,
I have a foreach loop (wordpress template) that lists all the categories of the post except the "top news" category:
<?php
$exclude = array("Top News");
$catagorystring = '';
foreach((get_the_category()) as $category) {
if ( !in_array($category->cat_name, $exclude) ) {
$catagorystring .= '' . $category->name . ', ';
}
}
echo substr($catagorystring, 0, strrpos($catagorystring, ','));
?>
That works but in additional i want to hide child-categories of "top news", too.
There is a wordpress function that allows me to do something like this:
<?php if(post_is_in_descendant_category('3') ) {
echo 'is in category 3';
} ?>
But i have no idea how to get this into the foreach loop.
You can use the parent property of the category object and check it against any id of the categories in the exclude array:
$excludedCategories = array();
foreach((get_the_category()) as $category) {
$breakLoop = false;
if (!in_array($category->cat_name, $exclude)) {
foreach($exclude as $cat_name_to_exclude) {
if($category->parent == get_cat_ID($cat_name_to_exclude)) {
$breakLoop = true;
}
}
if($breakLoop) {
array_push($excludedCategories, $category);
continue;
}
$categorystring .= '' . $category->name . ', ';
}
}
I am trying to add wheres to my query depending on what's coming in from GET:
public function index($type_id) {
$Product = new Product;
$Product->where('type_id', $type_id);
if(array_key_exists('ages', Input::get())) {
$Product->where('age_id', $_GET['ages']);
}
$products = $Product->get();
$productsPaginated = $Product->where('type_id', $type_id)->paginate(2);
return View::make('products.products', array(
'products' => $products,
'productsList' => $productsPaginated
)
);
}
But all it's doing is bringing back every record.
What am I doing wrong?
This is how I'm rendering my filters:
$brands = $prices = $ages = $brandsUsed = $agesUsed = array();
$out = '';
foreach ($productsList as $product) {
$brands[$product->brands->id] = $product->brands->brand;
$brandsUsed[] = $product->brands->id;
$prices[] = $product->price;
$ages[$product->ages->id] = $product->ages->age;
$agesUsed[] = $product->ages->id;
}
$brandsUsed = array_count_values($brandsUsed);
$brands = array_unique($brands);
$params = Input::get();
$lastParams = http_build_query($params);
unset($params['brand']);
$params = http_build_query($params);
if (count($brands) > 0) {
$out .= '<h5>Brands</h5>';
foreach ($brands as $brandId => $brandName) {
if (stristr($lastParams, '&brand=' . $brandId) || stristr($lastParams, 'brand=' . $brandId)) {
$out .= '<a class="filter-link" href="' . Request::path() . '?' . $params . '">';
} else {
$out .= '<a class="filter-link" href="' . Request::path() . '?' . $params . '&brand=' . $brandId . '">';
}
$out .= '<span class="cbox">';
if (stristr($lastParams, '&brand=' . $brandId) || stristr($lastParams, 'brand=' . $brandId)) {
$out .= '<span class="cbox-checked"></span>';
}
$out .= '</span>';
$out .= $brandName;
$out .= ' (' . $brandsUsed[$brandId] . ')';
$out .= '</a>';
}
}
You cannot create queries on object, you should do it this way:
public function index($type_id) {
$product = Product::where('type_id', $type_id);
if(array_key_exists('ages', Input::get())) {
$product->where('age_id', $_GET['ages']);
}
$productsAll = $product->get();
$productsPaginated = $product->where('type_id', $type_id)->paginate(2);
return View::make('products.products', array(
'products' => $productsAll,
'productsList' => $productsPaginated
)
);
}
You should also consider if it makes any sense to get all products and also paginated products. If you have many products in your database it will take long time to get all your products.
I'm also not sure what exactly you want to get for $productsPaginated. I think you will need here building new query:
$productsPaginated = Product::where('type_id', $type_id)->paginate(2);
EDIT
As you want to get count of products with only one filter, you should use here:
public function index($type_id) {
$product = Product::where('type_id', $type_id);
$productCount = $product->count();
if(array_key_exists('ages', Input::get())) {
$product->where('age_id', $_GET['ages']);
}
$productsPaginated = $product->paginate(2);
return View::make('products.products', array(
'productsCount' => $productCount,
'productsList' => $productsPaginated
)
);
}