Jump to content

Categorizing/tagging content


deandre212

Recommended Posts

Sure--what I would suggest is adding a text or textarea field and calling it "tags". Then people can type whatever tags in there that they want. When you want to find all pages matching a given tag, you'd do this:

$matches = $pages->find("tag*=something"); // where 'something' is a tag

If you want predefined tags, then I would use a page reference fieldtype to associate a group of pages as tags. Populate the pages with their name or title field as your tag. Then use a multiple selection field like asmSelect to allow selection of the tags/categories. To find pages matching a given tag, you'd do this:

$tag = $pages->get("/tags/something/"); 
$matches = $pages->find("title=$tag"); 
  • Like 2
Link to comment
Share on other sites

How about if I wanted to set up categories in a page structure like this (for example):

England

    London

    Manchester

    Birmingham

Scotland

    Glasgow

    Edinburgh

And then loop through them to produce some info from pages linked to these categories/tags in a nested list under each category title...

England

page-1-title + page-1-img

page-2-title + page-2-img

    Manchester

    page-3-title + page-3-img

    etc. etc.

So end result something like the list on the left of http://massagenewzealand.org.nz/find-a-therapist/

Link to comment
Share on other sites

I think you would want to use the sitemap strategy, like on the API "include & bootstrap" page. But if you only need one level of depth, we could do it even simpler. I'm on an iPhone right now so don't have good examples, but let me know if the sitemap strategy doesn't make sense an I can post some good examples in the morning.

Link to comment
Share on other sites

Yes can you provide examples. My needs are for a dedicated and intuitive way to categorize and subcategorize content. For example if I needed to categorize albums so to say. I want to be able to break it down by artist, by date, by genre, etc. Furthermore I would like to be able to take genre for example and break down by classical, blues, jazz and so on. Each category and subcategory should have url whether predefined and free-tagged. And If I have hundreds of categories it can be an overwhelming task to do so such in the manner that exist now IMHO. I'm coming from the Drupal way of doing things so all this freedom is complex to me  :D But I like the way drupal handles classifying it's content and that's what I'm use to. Plus it's easier for an end user to grasp to me at least. I'm not a really a developer, more of a designer. So as an end user a dedicated and intuitive backend way to add categories is a plus.

Link to comment
Share on other sites

Usually if I have hundreds of page references (categories) to create I use the API to create them (like from a CSV or text file) rather than doing it manually -- let me know if I can give an example of how to do that.

If you are doing something with free tagging, then I would use url segments. Lets say you've got a free tagging field called "tags", and it's just a textarea with one or more tags. You might setup a template called "tags" and on a page called "/tags/". Accessing /tags/something/ in your browser should list all pages that match the tag "something". To do that, first turn on URL segments in your template (Admin > Setup > Templates > Advanced > URL Segments). Then, in your template, your code might look something like this:

<?php
if($tag = $sanitizer->selectorValue($input->urlSegment1)) { 
    $matches = $pages->find("tags*=$tag");
    echo $matches->render(); // or loop through and print on your own
} 

For pre-defined categories using page referencs, I think that asmSelect is a good input field to use for selection. However, if you need to be able to select pages in a hierarchy (like category or subcategory with the same field) then I think the "page list select multiple" is a good solution, because it enables you to select pages in a hierarchy rather than in one level. You could also use any of the other multi select input fields and use the template as the base for selection rather than the parent.

ProcessWire is a couple months old, and Drupal has been around since 2001, so we're not going to have the same level of features in some areas. But if you think Drupal is better at this than PW2, describe further, and more specifically, so that I can make sure we get PW2 one step ahead. When it comes to working with these kind of data relationships, I believe PW2 is better than Drupal on the back-end, so I want to make sure I provide enough front-end simplicity to provide and prove that.

thanks,

Ryan

  • Like 1
Link to comment
Share on other sites

You can definitely do everything that you can in those other CMSs. But another thing to note is that both Drupal and Wordpress are primarily bucket-based CMSs, whereas ProcessWire is a page hierarchy-based CMS (as are MODx and SilverStripe, as far as I know). In a bucket-based CMS, you have no hierarchy other than an individual bucket. So custom taxonomies/categories/tags become the primary means by which you establish hierarchy (beyond a content type). Whereas in a page-hierarchy based CMS, you already have a hierarchy present which directly relates to URL structure. So additional categorization is less often used than it would be on a bucket-based CMS. I'm not suggesting that one approach is necessarily better than the other for most sites, except that I prefer a page hierarchy-based approach that can be used like a bucket when the need calls for it (which is ProcessWire's approach). I also feel that the page hierarchy approach is demonstrate-ably better at the large scale. I have a feeling we have the same preferences in this area, based on the other CMSs I know you like working with. :)

  • Like 1
Link to comment
Share on other sites

Thanks Ryan, yes I think we're on same wavelength here. I agree that you're much less likely to need tags/taxonomies in ProcessWire given the tree-based approach (which I definitely favour for a number of reasons); but still good to see your various suggestions where you might need to compliment the page tree hierarchy by creating additional relationships that cut across the primary content organisation...

Link to comment
Share on other sites

  • 5 months later...

Sometimes the simple tree hierarchy isn't enough. Some more complex hierarchies could have multiple parents per child. For example we can have a category "wooden toys", which belongs to both "wooden products" and "toys by material". Or we can have multiple category trees (nodes by topic, nodes by media type), etc.

Link to comment
Share on other sites

This is actually a perfect case for the tree because you have so many options at your disposal, all which will be far better than the alternative. First off, if your products will have URLs that people can bookmark and search engines can index, then you cannot disregard everything having a fixed place (URL) in a structure (tree). A site without real locations for it's content is not an accessible or indexable site. So the idea of multiple parents per child, as it relates to a web site's URL structure, would be shooting yourself in the foot. :) But I think that you are actually talking about something different, and something that's very simple in ProcessWire.

The tree hierarchy defines the primary home of content. It does not define all of it's other categories, connections or relations to other nodes (pages) in the tree or other pages of the same type. This is what page references and templates are for. So in your case, I would suggest the following structure. I'm assuming that there are multiple product types, in addition to toys.

/products/toys/
/products/toys/some-toy/

/categories/wooden/
/categories/some-category/

/materials/wood/  
/materials/brick/
/materials/straw/

Create page relations on your product template called "categories" and "materials" and set them to choose from the relevant parents. Now you can deduce any number of other relations on the fly, like:

/categories/wooden/toys/ 

But no need to literally create that page, because the context can already be determined from the existing relations. So your 'category' template code might look like this:

<?php

if($input->urlSegment1) {
   // there is an extra component on the URL that doesn't resolve to a page, like /categories/wooden/toys
   // so we assume they are adding a product type filter
   $name = $sanitizer->pageName($input->urlSegment1); 
   $type = $pages->get("/products/$name/"); 
   $products = $type->children("category=$page"); 
} else {
   // just grab all products in this category
   $type = new NullPage();    
   $products = $pages->find("template=product, category=$page"); 
}

echo "<h1>Products in category: {$page->title}</h1>";
if($type->id) echo "<h2>With type: {$type->title}</h2>";

foreach($products as $product) {
   echo "<li><a href='{$product->url}'>{$product->title}</a></li>";
}
  • Like 1
Link to comment
Share on other sites

Robert: that video is from Processwire 1.0 (I assume). Many things work little different in 2.0. It was nice watch and probably helps to grasp the concept - but might be more confusing than helpful for some users.

Actually for me that was very interesting to see and compare to 2.0. There is much more "everything" in 1.0, and comparing these two really shows that great design is always to make things simple. Separating fieldtypes from inputfields: brilliant. Hiding fieldgroups: brilliant. Although it seems that 1.0 was already pretty simple cms (considering the flexibility).

PS: Ryan, you have great and very clear style on your videos!

Link to comment
Share on other sites

Another useful example there - thanks ryan.

PS: Ryan, you have great and very clear style on your videos!

In no particular order: Designer, developer, composer, movie star ;)

Link to comment
Share on other sites

You guys give me way too much credit. If you saw how many clips were recorded and how many umms and uhhhs were edited out, you'd laugh. I eventually realized that I had to write down whatever I say on the video, and just read it off the screen. Luckily the macbook has a camera built into the screen, so it doesn't really look like you are reading off the screen. There's a reason why I don't make many of these videos... it takes half a day just to do a short one. :) But it is true that I can build skyscrapers with my bare hands– as long as I've got enough legos to do it.  ;D

Link to comment
Share on other sites

I agree, video tutorials are great but difficult to create. There is much information in this forum that is useful but not so easy to find. I would suggest to create some wiki section on this site to allow users to collect and sort these tutorials and howtos in a reader-friendly structure. The advantage of wiki over video is that it could be created and maintained in a participatory manner.

Link to comment
Share on other sites

  • 1 month later...

Hi everyone,

I'm a bit stumped with getting categories to work for me in PW.

Say my page setup is like this:

Home

- Portfolio

-- work item

-- work item

-- work item etc

- Blog

-- Blog item

-- Blog item

-- Blog item etc

- Categories

-- Work

--- cat_name

--- cat_name

--- cat_name etc

-- Blog

--- cat_name

--- cat_name

--- cat_name etc

In my work and blog pages I have a field called categories with each parent being the Work and Blog subpages in Categories. I can add a category (via pageselect) to a work or blog entry no problems.

What I can't work out is how to get a list of categories and filter work or blog items on those categories.

Can I have: .com/work/categories/design - do I need to then move my Categories/Work tree beneath my Portfolio tree?

or does it need to be: .com/categories/work/design/

Confusedly yours,

Marty

Link to comment
Share on other sites

Marty, the possibilities are pretty much limitless here, so this can be structured however you want it.

If I'm following your right, it sounds like you want to be able to list the categories in your Portfolio section even though they don't technically live there. That's no problem. Just edit your Portfolio index template, click on the URLs tab and tell it to allow URL segments.

Now you can have our Portfolio index template look for categories and display items from them:

<?php

if($input->urlSegment1 == 'categories') {

    if($input->urlSegment2) {

        // example: /categories/work/architects/ 
        // category specified, list items in category: 

        $name = $sanitizer->pageName($input->urlSegment2);
        $category = $pages->get("/categories/work/$name/");

        if($category->id) {
            // valid category, list items in it
            echo $page->children("categories=$category")->render(); 

        } else {
            // unknown category
            echo "<p>I don't know that category.</p>";
        } 

    } else {
        // list categories
        echo $pages->get('/categories/work/')->children()->render(); 
    }

} else {
    // list all portfolio items
    echo $page->children()->render(); 
}
Link to comment
Share on other sites

Thanks Ryan.

I've tried to strip your example back to something I could understand :) and tried to use urlSegment2 as a trigger to retrieve notes from a particular category: .com/notes/categories/links for example (similar to your journal on ryancramer.com). Can I use that url variable this way?

<?php
if($input->urlSegment1 == 'categories') {
   if($input->urlSegment2) {
       $urlcat = $sanitizer->pageName($input->urlSegment2);
	$notes = $pages->get("/notes/")->find("template=notes, sort=-publish_date, note_category=$urlcat");
	foreach($notes as $note) {
	    echo "<p>{$note->title}</p>";
		}
	}
}

Regards

Marty

Link to comment
Share on other sites

Marty, looks good except that page reference fields in a selector expect a page ID (number). If your $urlcat variable represents the page ID, then your example will work. However, I'm pretty sure that's not the case in your example. Also, I don't personally like using page ID numbers in URLs, much preferring to use the name, which is more meaningful. So assuming you agree, here's what you'd want to do (below). This is your example, but I just added one line:

<?php
if($input->urlSegment1 == 'categories') {
    if($input->urlSegment2) {
        $name = $sanitizer->pageName($input->urlSegment2);
        $urlcat = $pages->get("/categories/")->find("name=$name"); // this is the only line I added
        $notes = $pages->get("/notes/")->find("template=notes, sort=-publish_date, note_category=$urlcat");
        foreach($notes as $note) {
            echo "<p>{$note->title}</p>";
        }
    }
}
Link to comment
Share on other sites

  • 3 years later...

You need:

  • Page Reference Field 
  • Parent page to hold the tags (for example: /config/tags/)
  • Template for the tags
  1. Create the parent page /config/tags/
  2. Create the tags template (no need to have a file, and only needs one field "title")
  3. Create a Page reference field. (called tags for this example)
    a. In the settings "Allow new pages to be created from this field"
    b. input field type: autocomplete, or whatever type works for what you are after.

Assign your "tags" field to templates where you want to allow tagging.

  • Like 1
Link to comment
Share on other sites

You need:

  • Page Reference Field 
  • Parent page to hold the tags (for example: /config/tags/)
  • Template for the tags
  1. Create the parent page /config/tags/
  2. Create the tags template (no need to have a file, and only needs one field "title")
  3. Create a Page reference field. (called tags for this example)

    a. In the settings "Allow new pages to be created from this field"

    b. input field type: autocomplete, or whatever type works for what you are after.

Assign your "tags" field to templates where you want to allow tagging.

If my understanding is correct, each tag is a page store under /config/tags/

That's is

+config/tags/

   -apple

   -banana

   -orange

   -lemon

right ?

Then, what is in /config ?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...