Working with Topics & Tags (5.7)

Permalink 2 users found helpful
I am creating a site (using 5.7.5.6) that makes use of the Topics and Tags features. I have a page set up (“Template”) with the Page List block that both Topics and Tags use to show their filtered results. The sidebar of all pages contains a Topics block and a Tags block. Been playing with it, and so far, so good, but there are a few things I’d like to tweak.

1) The page the Topics & Tags blocks use for results (“Template”) is otherwise invisible on the site (not used for other content.) Is there any way to prevent the name of the Template page from showing up it the URL? So it’s just “topic/1/my-topic” or “tag/my-tag” without “template” at the beginning. I can’t figure out how to set custom URLs since these aren’t actual pages existing somewhere. It also shows up in the meta page title, would like to remove that as well.

SOLVED! 2) The meta page title when displaying a Tag’s results is always lowercase, even when the Tag isn’t (Topics’ reflect the capitalization of the Topic.) Is there a way to fix this so the Tag meta title directly reflects the actual Tag, like Topics do?

SOLVED! 3) Using the Archive template for the Page Title on the Template page allows the current Topic being viewed to customize the Page Title. That’s awesome. Is there a way to do the same thing for Tags?

4) Similarly, is there a way to have the title of the Page List block change on the fly, depending on the Topic or Tag results being viewed? I use both the Blog Index and the Thumbnail Grid templates in different places, both of their view.php files show the title being written in the same way:
$title = $th->entities($page->getCollectionName());
                <div class="ccm-block-page-list-title">
                    <?php echo $title; ?>
                </div>


5) Is it possible to have an introductory paragraph at the top of the page that swaps out with another depending on which Topic or Tag is being viewed? Or that isn’t displayed at all in some cases? I can’t create custom templates for each Topic or Tag, since you select a destination page for the block as a whole and not for each individual Topic/Tag, so it would be very helpful to be able to vary the content accordingly.

Any pointers on these items would be great, thanks!

OddSpoon
 
siton replied on at Permalink Reply
siton
I hope you find answers.

I add this issue to github about 2 weeks ago. The topic list misses some basic & usefull "build in" "one line code" features for more complicated structures. Examples: Get selected topic name // "get topic link // "get -"no filter" = see all / get parent topic // "get number of children" + ....more control on urls' for SEO like in wordpress categories %category/%post)

Example:
http://www.sitepoint.com/
(3 levels of hierarchy + show topic name & topic parent name in the title + show clickable topic name on each pagelist item + nice hierarchy urls for seo)

Today its hard to create structures like this with the core topic-list.
OddSpoon replied on at Permalink Reply
OddSpoon
I am still futzing around with my item #5 in the list above, the ability to have an introductory paragraph that changes (or doesn't display at all) depending on the Tag or Topic being viewed. It seems like it should be possible to have a block whose content would change, using the mechanism that the Archive template of the Page Title does.

Unfortunately I don't know enough about writing PHP, or know where to look for the specific info. For instance, the Archive template uses
$currentTopic->getTreeNodeDisplayName()
to display the title of the current Topic being viewed- what would be the equivalent for a Tag? In digging around in the Tags controller and view files, I see
$option->getSelectAttributeOptionValue()
. Now how do I use that information to create the same functionality on the Page Title for Tags? If I could figure out that step, then I could figure out the next step to apply such functionality to a block of text instead of the title. Can anyone point me in the right direction here?
Parasek replied on at Permalink Reply
Parasek
Tags are very simple attribute, they don't containt more information other than title.

1. How to display tag title

First method (using block page_title):
a) Copy file
application/concrete/blocks/page_title/controller.php
to
application/blocks/page_title/controller.php

b) In copied file change namespace in third line to:

namespace Application\Block\PageTitle;


c) Add this code before last parenthesis (})

public function action_tag($currentTag = false)
{
   if ($currentTag) {
      $this->set('currentTag', $currentTag);
   }
   $this->view();
}


d) Create another template (or modify existing)
application/blocks/page_title/templates/tag_title.php
and paste this code:

<?php  defined('C5_EXECUTE') or die("Access Denied."); ?>
<?php if (isset($currentTag) AND $currentTag): ?>
    <<?php echo $formatting;?> class="page-title"><?php echo h(ucfirst($currentTag)); ?></<?php echo $formatting;?>>
<?php else: ?>
    <<?php echo $formatting;?> class="page-title"><?php echo h($title)?></<?php echo $formatting;?>>
<?php endif; ?>


e) change block template in CMS.

--------------------------------------

Second method:
You can get title from url:
somesite.com/tags/tag/tagname
and display it directly in your template file.
<?php
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$pathElements = explode('/', $path);
$tagTitle = end($pathElements);
echo $tagTitle;
?>


Of course you can check if you are on tags page, for example:
if ($c->getCollecctionID=pageIDWhereYouPutTags) {
//your code
}

You can use ucfirst() function if needed etc.



2. Introductory text (or custom meta description etc for each tag etc.)
This requries much more effort/coding. What you need to do is to prepare custom dashboard single page/package where you can assing introductory text to each tag + prepare frontend block where you display it.
OddSpoon replied on at Permalink Reply
OddSpoon
Woohoo, Parasek, thank you! Your info is a huge help, and thank you also for giving it step-by-step, as I need that basic info. Between the information you provided, the bit to add to the controller file, and the existing Page Title archive template, I was able to create a template that will show EITHER the Topic title or the Tag title depending on which is being viewed, and it works like a charm. Just what I wanted!
<?php
defined('C5_EXECUTE') or die("Access Denied.");
if (isset($currentTopic) && is_object($currentTopic)) {
    $title = t('Image Collection: %s', $currentTopic->getTreeNodeDisplayName());
} else 
if (isset($currentTag) AND $currentTag) {
    $title = t('Tag: %s', (ucwords($currentTag)));
}
if (isset($title)) {
    ?><h1 class="page-title"><?php echo h($title)?></h1><?php
}


Now I'm going to dig into the info in your item #2, the tips you gave there point me in a helpful direction. Thanks again!
siton replied on at Permalink Reply
siton
Parasek - Good tut, Thanks.

I try this code - work well. I dont understand something - In controller.php - From Where, how you get the right value of $currentTag? (I dont see any getTagValue or something like this in the code )

You can also add this trick/code to get "action_archive" (may 2015 as title for example)?
For complete picture : topic/tag/archive -- as title
Parasek replied on at Permalink Reply
Parasek
It is just a special function available in block controller and Concrete5 is making all the magic for you:

function action_xxx($nextUriSgment = false, $anotherUriSegment = false)

where instead of xxx you can write first URI segment (relative to your "canonical" url, which you can access in theme template as $c->getCollectionLink()).
Arguments of this function become next consecutive uri segments in url.
Above example will translate to urls like:

yoursite/some-page-where-you-inserted-block/xxx/some-value/another-value
yoursite/some-page-where-you-inserted-block/xxx/something/
etc.

When Concrete5 finds out that you added "xxx" (in browser) after the end of your canonical url - it will trigger that function and do whatever you wrote there.

Of course you can do all of that in any other block. Also "action_xxx" doesn't have to be "action_tag" or "action_topic" only, you can make your own functions like "action_like", "action_top_ten" etc.

------------------

Concrete5 doesn't make tags seo friendly (like page handles, where everything is lowercase, spaces replaced with hyphen, foreign characters replaced etc.) - it only lowercases first character (try to add two-word tag - space will become %20).
That means, what you need to do is to get value from url and uppercase first character.
Parasek replied on at Permalink Reply
Parasek
Regarding to second part of your question. Yes you can!

But you will need to use another special concrete5 function: getPassThruActionAndParameters()

1. Copy file
concrete\blocks\page_title\controller.php
to
application\blocks\page_title\controller.php

2. In copied file change namespace in third line to:

namespace Application\Block\PageTitle;

3. Load "Core" class (paste it after line 7)

use Core;

4. Add this before last parenthesis (})

public function action_filter_by_date($year = false, $month = false)
{
   if ($year AND $month) {
      // You can wrap month names in t('') function if you want to have multilingual names
      $months = array();
      $months[1]  = 'January';
      $months[2]  = 'February';
      $months[3]  = 'March';
      $months[4]  = 'April';
      $months[5]  = 'May';
      $months[6]  = 'June';
      $months[7]  = 'July';
      $months[8]  = 'August';
      $months[9]  = 'September';
      $months[10] = 'October';

5. And somehwere in your block template add:

if (isset($currentDateTitle) AND $currentDateTitle) {
    $title = $currentDateTitle;
}



--------------------
getPassThruActionAndParameters() is just another way of doing action_xxx function.
As you can see we can't create "action_date" function because concrete5 url lacks "date" or any similar segment name (which would be translated to method name) and starts directly with year:
yoursite.com/2016/02

I don't know if concrete5 generate urls without month (only year). But if it does - just modify a little code in getPassThruActionAndParameters() to display only year if $month is false.
OddSpoon replied on at Permalink Reply
OddSpoon
I actually spent a couple hours yesterday trying to add the Date to the title template, too (no luck), so this is perfect!

I've been wondering how to control the formatting of the url, to replace that '%20' with a hyphen. It does it for both Topics and Tags. Is there any way to fix that?
OddSpoon replied on at Permalink Reply
OddSpoon
Parasek, this works perfectly to show the date in the page title, however then the custom title display for the Topics and Tags don't work. When I remove the getPassThruActionAndParameters function, the Topics & Tags titles work again. Any idea what the conflict is?
bjalexander replied on at Permalink Reply
bjalexander
This has been so helpful. Thank you! Since you have such a good understanding of this block, I'm wondering if you can help:

I went back to using the archive template since we mostly operate with topics instead of tags. It works great when I'm signed in. As soon as I sign out, it locks onto the topic and displays the same one no matter what is selected. Suggestions?

Topic selections are at the bottom of the page:
http://newspaces.com/our-work/remodeling-projects/topic/109/white%2...
bjalexander replied on at Permalink Reply
bjalexander
I'll leave this up even though I've figured it out just in case someone else has the same issue. Easy fix. Just go into the block controller and make sure the cache-related stuff is set to "false." Lines 16-17-18 for me:
protected $btCacheBlockOutput = false;
    protected $btCacheBlockOutputOnPost = false;
    protected $btCacheBlockOutputForRegisteredUsers = false;
OddSpoon replied on at Permalink Reply
OddSpoon
Solved my item #2, Tags showing as lowercase in the meta title. In the controller file for the Tags block, in the getTagLink function, is this bit:
if ($option) {
            return \URL::page($target, 'tag', strtolower($option->getSelectAttributeOptionDisplayValue()));
        }

So I replaced "strtolower" with "ucwords," and ta da! (In a new copy of the controller file in the application folder, of course.)

I would still like to know how to set a custom meta title for individual Tags and Topics so that it doesn't include the template page being used as part of the title (my item #1), if anyone has any ideas.
Parasek replied on at Permalink Reply
Parasek
I wouldn't do it that way, because your urls will look like:
yoursite.com/tags/tag/Tagname

Fortunately there is a better and cleaner solution. Check this file:
concrete\blocks\page_list\controller.php - line 276 and 289
Concrete is using his own seo helper.

So replace:

$seo->addTitleSegment($tag);

with

$seo->setCustomTitle(ucwords($tag));

or

$seo->addTitleSegment(ucwords($tag));

depending how do you want your Meta title to look like.

You can do the same for topics (action_filter_by_topic above).

If you have other question or if I missed something feel free to ask. I recently created small blog and modified some things here and there, like:
- display 10 random tags with counter
- make tag urls seo-friendly
so I can share what have I learned
OddSpoon replied on at Permalink Reply
OddSpoon
That works beautifully, thank you. Why is it better to keep the URL lowercase? For SEO?