1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Categories 2.0

Discussion in 'Plugins' started by Nick, Aug 13, 2009.

  1. missha

    missha New Member

    I can't figure out how to add or create a new category :(

    Edited: Ok, I just realized I have to download yet another plugin to manage the categories. You guys really love plugins :p
    Last edited: Dec 31, 2011
  2. PuckRobin

    PuckRobin New Member

  3. blinger187

    blinger187 New Member

    how would you go about displaying a predefined image, next to the post title, depending on which category is selected?
  4. shibuya246

    shibuya246 Hotaru Developer Staff Member Admin

  5. valMETNG

    valMETNG Administrator Staff Member Admin

    Suggestion for core change to categories to allow category tree in URL

    I'd like to propose a change to base in the way URL parsing/page handling, category uniqueness, and post uniqueness occurs.

    Problem statement: Currently, categories must have a unique name, even if a category is a child to a different parent category. This means that you can't have use cases like /education/science and my_school/science. However, just allowing for categories with the same name in the categories table isn't enough because page handling assumes (and requires) that URLs be unique. So, for example, if you allow for categories with the same name but then put in a URL like all/category/education/science, Hotaru doesn't know what to do with this and just redirects to the Top Posts page. Additionally, post URLs must be unique. This prevents the use case where two different users submit the same URL to two different categories.

    Proposal: I think to make the changes required for all of this proposed functionality as a plugin (or multiple plugins) is a tad counterproductive as it adds additional layers of processing and complexity. I had a hard time tracing the logic path but, using a URL like all/category/education/science appeared to cycle eight times from PageHandling.php (p) to categories.php (c) before it finally gave up and sent me to Top Posts (i.e., p->c->p->c->p->c->p->c->p->c->p->c->p->c->p->c->Top Posts page). It wasn't clear to me why it kept cycling. Of course, if you only have unique category names, this cycling doesn't occur. So, to do away with unique category names, we have to grab the category tree from the URL.

    I propose doing the following to base:

    • As part of installation, adding a text column to the categories table named category_url_path.
    • As part of function addCategory, populating category_url_path with the parent (if != 'all') and then the child(ren) (e.g. populating category_url_path as something like '/education/science' if the category is 'science' and the parent is 'education,' or just '/education' if there isn't any child).
    • Making the appropriate changes in .htaccess as Nick described here to allow for many more levels of key/value pairs.
    • Removing the category name index and changing related processing as described here.
    • Somewhere in PageHandling.php (and/or elsewhere if necessary; e.g., Pagination.php), adding special processing via a function like the following code to grab the category tree and replace it with the category_id (e.g., adding $parts = $this->parseCategoryURL($parts) perhaps after the parts explode in function friendlyToStandardUrl, but I'm not sure if this is the only place as some might not be using friendly URLs):
    	function parseCategoryURL($h, $parts)
    		$c = false;
    		$start_position = 0;
    		$potential_categories = array();
    		// review each part to find the categories
    		foreach ($parts as $key => $url_part)
    			if ($c) { $potential_categories[] = $url_part; }
    			// we found where the category parts likely start
    			if ($url_part == 'category')
    				$start_position = $key + 1;
    				$c = true;
    		// there isn't a category in the URL, so return
    		if (!$c) { return $parts; }
    		// look up each part to see if there's an associated category, starting with the end (which will often be the one we want)
    		$OR_statement = $this->whereExploder($potential_categories, "category_safe_name", "string");
    		$sql = "SELECT category_id, category_url_path FROM " . TABLE_CATEGORIES . " WHERE " . $OR_statement . " ORDER BY category_id DESC";
    		$categories = $h->db->get_results($h->db->prepare($sql));
    		// the categories received in the URL are incorrect
    		if (!$categories) { return $parts; }
    		// put the category path together and get the proper category_id
    		$category_locator = '';
    		foreach ($potential_categories as $actual)
    		{ $category_locator = '/' . $actual . $category_locator; }
    		$location = array_search(array('category_url_path' => $category_locator), $categories);
    		// the categories received in the URL are incorrect
    		if (!$location) { return $parts; }
    		$category_id = $categories[$location]->category_id;
    		// we found it so replace the various category-related URL parts with one part - the category_id
    		$parts[$start_position] = $category_id;
    		// to prepare for the future when we could have a post URL after the category (i.e., we might have more delimeters after the category tree, so we don't want to assume we can chop off everything after 'category')
    		$end_position = count($categories) + $start_position;
    		if (count($potential_categories) != 1)
    			foreach ($parts as $key => $part)
    			{ if ($key <= $end_position && $key > $start_position) { unset($parts[$key]); } }
    		return $parts;
    	* Takes an array and blows out the values into an OR statement so we can execute one database call instead of many
    	* (This would likely be useful as a global function)
    	* Usage: $OR_statement = $this->whereExploder($post_array, "post_id", "number");
    	* $data_array - the array results from a SELECT
    	* $field_name - from which field in the array you want to pull the values
    	* $data_type - string or number
    	* @return string
    	public function whereExploder($h, $data_array, $field_name, $data_type)
    		$array_elements = count($data_array);
    		$OR_statement = " (" . $field_name . " = ";
    		// if a string is sent in, we need apostrophes; otherwise, it won't include them
    		if ($data_type == "string") { $ap = "'"; } else { $ap = ""; }
    		$i = 0;
    		// build OR statement so that we pick up all rows with one query
    		foreach ($data_array as $value)
    			if ($i == ($array_elements - 1)) {
    				$OR_statement = $OR_statement . $ap . $value . $ap . ") ";
    			} else {
    				$OR_statement = $OR_statement . $ap . $value . $ap . " OR " . $field_name . " = ";
    		return $OR_statement;
    I haven't gotten this all fully working yet because I'm still trying to figure out where the best place to put this is to prevent Hotaru from cycling through the same code as described above. Also, I haven't yet looked at what it will take to have the same post URL within different categories but, if something like this were in place, I'd expect that to be rather easy. (Famous last words...)

    What do you think? Any interest in pursuing something like this as a core change? If there isn't any interest, that's certainly OK and I will customize to my specific requirements.
    Last edited: Jul 11, 2013
  6. valMETNG

    valMETNG Administrator Staff Member Admin

    So here's why I think Hotaru is cycling through multiple times when it can't understand a URL properly: it appears query_string is getting messed up. For example, for a URL of http://mywebsite.com/all/category/politics/us-politics/, plugins/categories/categories.php gets the query string:
    $query_string = $h->cage->server->sanitizeTags('QUERY_STRING');
    ...which ends up looking like "all=category&politics=us-politics." I'm terrible at interpreting the regex/rewrite rules in .htaccess, but I'm assuming this is what Nick was getting at when he discussed .htaccess and the key/value pairs. It appears .htaccess is turning something that isn't a key/value pair into a key/value pair. Ergo, if I want to have URLs that don't strictly follow the key/value pairs, I'm going to have to remove the rewrite rules in .htaccess and then parse the URL differently. That's OK, although it might not be the best solution for accommodating multiple child categories with the same name.

    So, assuming this won't make it into a base change, if anyone has a better suggestion on how to accommodate multiple child categories with the same name and the same post multiple times within different categories (and the URL reflecting it as such), I'm all ears. Otherwise, I'm off to customize :)
  7. robin007

    robin007 Well-Known Member

    please any one help me to create a bootstrap category button thank you.

    Attached Files:

  8. valMETNG

    valMETNG Administrator Staff Member Admin

    If you want to make a link look like a button, the bootstrap css page will help. Within the button section, they show examples like this:

    <!-- Standard button -->
    <button type="button" class="btn btn-default">Default</button>

    <!-- Provides extra visual weight and identifies the primary action in a set of buttons -->
    <button type="button" class="btn btn-primary">Primary</button>

    Using this guide, I believe you could change line 427 in plugins/categories/categories.php from:
    $output .= '<li' . $active . '><a href="' . $h->url(array('category'=>$link)) .'">' . $category_name . "</a>\n";
    $output .= '<li' . $active . '><a class="btn btn-primary" href="' . $h->url(array('category'=>$link)) .'">' . $category_name . "</a>\n";
    However, if you do that, I believe you'd also want to change the way the active class works (lines 411 and 415).
  9. shibuya246

    shibuya246 Hotaru Developer Staff Member Admin

    For putting a header in the sidebar, look at the default theme, index.php file

    you will see code something like this

    <!-- SIDEBAR -->
                <?php if ($h->sidebars) { ?>
                                <div class="col-md-3">
                                        <?php if (!$h->pluginHook('theme_index_sidebar')) { $h->template('sidebar'); } ?>                   
                 <?php } ?>
    You can simply put any html code straight after the <!--SIDEBAR--> comment

    Is there something you want to put there that you have a problem with? like the sort filters from bookmarking? you would need to put

    1. put a plugin hook there
    2. make a copy of the template file you want to customise from the plugin template folder and paste it into your theme folder, then customise (make sure to keep the file name the same). Hotaru will read the theme folder first. If it finds the template file it will use that instead of the one in the plugin template folder
  10. robin007

    robin007 Well-Known Member

    horizontal category bar is not responsive. Is any way to use bootstrap navbar as category bar?
  11. valMETNG

    valMETNG Administrator Staff Member Admin

    I just tested it on my mobile and categories that don't fit are moved to the next line (which looks fine to me). Are you wanting to shrink the font size as more categories are added so they all still stay on the same line? If so, I would think this wouldn't look very good as you would have a very hard time seeing the categories on a small device.
  12. robin007

    robin007 Well-Known Member

    I attach a screen shot.

    but I need to attach 15 or more categories, that's why i need responsive categories bar. Screenshot_2016-06-17-20-22-34.png
  13. valMETNG

    valMETNG Administrator Staff Member Admin

    I guess I don't understand what you mean by responsive then and what you're trying to accomplish. Fifteen or more categories in a bar would look terrible in my opinion (and would not only look worse if the font was too small to read but also wouldn't be functional as it would be too small to even click on... at least with my fat fingers). For that many categories, I would think you'd want a drop down.
  14. robin007

    robin007 Well-Known Member

    Yes, Need drop down menu on only mobile, desktop not needed. where i should change this.
  15. valMETNG

    valMETNG Administrator Staff Member Admin

    Ah. Drop down =/= responsive :)

    If you look at navigation.php in /themes/default, you'll notice the class "navbar-toggle" with the associated data-toggle and data-target references, as well as the associated lines for icon-bar at the top of the file (starting line 43). This makes the clickable 3-bar image. Then later, on line 63, you'll see the div with navbar-collapse, etc. classes that holds the individual menu options (each with their own <ul> and associated <li>). You can use that as a template for creating one in the category_bar.php template (e.g., you'll probably want to modify lines 40-44 by inserting the code from navigation.php). However, lines 41-43 will display the actual categories by pulling from function header_end in plugins/categories/categories.php so you'll need to modify that function (and the associated loopCats function) to put in the appropriate ul and li tags.
    robin007 likes this.
  16. robin007

    robin007 Well-Known Member

    Thank you......

Share This Page