Custom SEO article title in Joomla - joomla

While it's possible to manually enter the full title of a page displaying a category, how would I go about doing the same for an article page in Joomla 2.5?
The default is to use the article title as the page title, e.g. "How to care for goldfish", with an option to add the site name.
What I want is to have the title as follows:
How to care for goldfish | Fish care guides | FishSite.com
The obvious solution would be just to put all that in the title of the article, but then I'd have a problem in the "Latest articles" module, it would become unreadable with all the extra text.
How to solve this? Plugin, coding, or some clever solution? It needs to be more or less automatic though, I can access the Joomla database and change each page title manually but that wouldn't be feasible. If manual text entry is needed, it has to be in Joomla.

The plugin system responds to events, so the easiest solution would be a either a Content or System plugin that manipulates the Title by appending the relevant information prior to display.
I think with a content plugin you could use the onContentPrepare event to do all the work.
In rough psuedo code (i.e. this won't run), I would probably end up with something like this:
public function onContentPrepare($context, &$article, &$params, $page = 0)
{
// Don't run this plugin when the content is being indexed
if ($context == 'com_finder.indexer') {
return true;
}
// Perform a sanity check to make sure we're on an article layout
// Build new title
}

Related

Joomla content edit call stack and URL routing

I am using Joomla 3.x CMS. I have SEO enabled. I am also routing the URL so that article IDs, category and category IDs are hidden. Hence a typical article with an alias of my-alias will have the URL: http://localhost/my-alias. I am doing this routing in a system plugin in method onAfterInitialise(). All aliases in the system are ensured to be unique. Now when an article is being viewed, anyone with access will see an edit URL as follows: http://localhost/my-alias?task=article.edit&return=someValidToken. This too is routed properly to the actual article to be edited.
When viewing an article, the user/browser does not see the article ID (as desired). When editing, the user/browser sees the article ID (not what I want). That is, when user clicks the edit link, browser loads the edit form and user sees the following URL: http://localhost/edit-article?view=form&layout=edit&a_id=1002&return=someValidToken, where 1002 is the article ID.
Following is a code snippet from onAfterInitialise():
if (isset($query['task']) && $query['task']=='article.edit') {
// TODO Hide this change from the user/browser
JFactory::getApplication()->input->set('view', 'form');
JFactory::getApplication()->input->set('layout', 'edit');
JFactory::getApplication()->input->set('a_id', $articleId);
}
else {
JFactory::getApplication()->input->set('option', 'com_content');
JFactory::getApplication()->input->set('view', 'article');
JFactory::getApplication()->input->set('id', $articleId);
}
JFactory::getApplication()->input->set('Itemid', 111); // map to dummy item in hidden menu with alias edit-article
I would like to know how to solve this. An understanding of the call flow through the Joomla framework will help.

Setting default paragraph style without user interaction

I am trying to set the default style applied to the P elements that are automatically created when a user enters the blank editing area. I've spent many hours searching for an answer but have not found anything that works. The requirements are:
Style has to be inline, no stylesheet
No user interaction, no format/style plugin to click
When the user clicks in the editing area and starts typing, I want the style to be applied and visible automatically. Surely there is a way to accomplish this?
The closest I have gotten is by using the htmlFilter, like this :
p_rule = {
elements : {
p : function(element) {
if (element.attributes.style === undefined) {
element.attributes.style = "color: #0000ff;";
}
}
}
};
ev.editor.dataProcessor.htmlFilter.addRules(p_rule);
But the new style is not automatically visible.
It does become visible if the user goes into source editing mode and back to WYSIWYG but I want it to be automatic.
I tried using updateElement() in the filter function, but it does not work and creates infinite recursion:
p_rule = {
elements : {
p : function(element) {
if (element.attributes.style === undefined) {
element.attributes.style = "color: #0000ff;";
CKEDITOR.instances['editor1'].updateElement();
}
}
}
};
ev.editor.dataProcessor.htmlFilter.addRules(p_rule);
(I guess updateElement() triggers the filter)
If I use setData(getData()) from an event I can strangely get the textarea to update with the changes the filter applied, for example:
CKEDITOR.instances['editor1'].on('blur', function() {
CKEDITOR.instances['editor1'].setData(CKEDITOR.instances['editor1'].getData());
});
But that too requires user interaction. Using the "change" event creates recursion.
I am new at CKEditor and obviously I'm missing something on how the filter works in relation to what is currently being displayed in the textarea.
Any CKEditor guru out there? Help!
Thanks
I really advise not to go this way. You'll find yourself fighting with countless issues, like what if you copy&paste, what if you change format to h1 and then back, what if you create a list item and then convert that into a paragraph, etc. etc. There are really dozens of those. You'd need to rewrite half of the editor.
The way to handle this in CKEditor 4 is to rethink this:
Style has to be inline, no stylesheet
Inside CKEditor you clearly need to use a stylesheet. I presume though that you want the inline styles in the output. So what I would propose is to:
Write htmlFilter rule which adds this style to every paragraph.
Write dataFilter rule which removes this style from every paragraph.
The second rule is needed so if you save the data and then load it back to the editor, the styles do not pollute it.
PS. CKEditor 5 will separate data model from rendering (the view) so you'll be able to render paragraph as you wish without affecting how other features interact with it. Read more about CKEditor 5 in this article.

k2 articles in Joomla become unpublished if the author makes a minor change from the Frontend

The "Authors" group doesn't have any publish rights. This is ok. So an Editor/Administrator does an initial approve of any article.
Problem comes if the Author decides to edit the already published article. When he hit "save" from the frontend, the item immediately becomes unpublished.(Because authors group doesn't have the right to publish items). So, this a huge problem at least for my case.
I want articles to remain published after the initial approval of the admin, even if the author makes adjustments. Any idea how to do something like this?
This logic comes as the default way of doing things in the Joomla Core.
You may want to consider switching from K2 to something like else like EasyBlog then... Or just don't use K2. It seems like the default for K2 is to follow a workflow that conflicts with yours.
Otherwise you can modify K2 to suit your needs... I really don't recommend modifying extensions because then you can no longer make updates to them unless you plan to make the modifications every time you update (which is a pain).
You problem resides in the administrator/components/com_k2/models/item.php The following lines are form version 2.6.1 line 785.
if ($front)
{
if (!K2HelperPermissions::canPublishItem($row->catid) && $row->published)
{
$row->published = 0;
$mainframe->enqueueMessage(JText::_('K2_YOU_DONT_HAVE_THE_PERMISSION_TO_PUBLISH_ITEMS'), 'notice');
}
}
If I understand you correctly you want something more like:
if ($front)
{
$row->published = 1;
if (!K2HelperPermissions::canPublishItem($row->catid) && $row->published && $isNew)
{
$row->published = 0;
$mainframe->enqueueMessage(JText::_('K2_YOU_DONT_HAVE_THE_PERMISSION_TO_PUBLISH_ITEMS'), 'notice');
}
}
If I understand their model right by adding a check for $isNew to the if statement it will only apply published = 0 to new entries. Which, if I understand you, are the only ones you want to affect. This way if if the article already exists and it's published it will always stay published unless an admin changes it to unpublished.
I'm not sure if this will work the way I expect so let me know.
You should either allow Authors to edit any item or disable option for editing articles for authors.
Go to your joomla administration, go to k2 menu and in User Groups tabs create a group called editors and give it access to Publish item, then go back to Users tab and put those users that you want to make them editor in editors group.
Make sure your editor group users have access to Front-end item editing and Edit any item.
Your problem is because your editors have Edit any item access but they don't access to Publish item.
The permission that you want to set is actually in the k2 user group settings. Look for Allow editing of already published items and set it to yes.
At least this is true for k2 v. 2.6.7, although I don't think any of the permission settings have changed since v.2.6.0 or earlier.

Place certain article anywhere in joomla template

Is it possible in Joomla to place a certain article in a template, additionally to the normal content? I want the article to show up on every page.
You can simply take it from the databse and print its content. In the template, where you want to show the article, write this:
$id=/*Id of the article to show*/;
$db=&JFactory::getDBO();
$db->setQuery("SELECT * FROM #__content WHERE id=$id");
$item=$db->loadObject();
echo $item->introtext;
UPDATE: ENABLE PLUGINS
I can't find where i've used that code and i can't copy-paste it, so i try to write it again by looking at the view.html.php of the com_content:
JPluginHelper::importPlugin('content');
$dispatcher =& JDispatcher::getInstance();
$params = &$mainframe->getParams();
$dispatcher->trigger('onPrepareContent', array (&$item, &$params, 0));
//The last line triggers the onPrepareContent event, so if it does not work maybe you need other events, so try with onAfterDisplayTitle, onBeforeDisplayContent or onAfterDisplayContent
Have you seen this? http://extensions.joomla.org/extensions/news-display/content-embed/7528
It allows you to place any article as a module on your Joomla site. And with modules you can have them displayed site wide.

Joomla: How to change template on a specific article

Is there a way to change the template on a specific article only?
Note that it should work without linking the article to any menu.
If you want the template override not to depend on the menu position than the standard joomla way of assigning a different template to a menu will not work. You will need to get your hands dirty and write some custom code. You will need to use the article_id as a trigger for template switch.
I did something like that at work but don't remember now how exactly this is achieved. I will post my code here as soon as I locate it.
EDIT: Found the code :)
You need to edit the file /includes/application.php, specifically the getTemplate() method. At the end of this method, just before:
// Fallback template
if (!file_exists(JPATH_THEMES.DS.$template.DS.'index.php')) {
$template = 'rhuk_milkyway';
}
you can add your condition for applying a custom template, like so:
//CUSTOM TEMPLATE FOR THE ARTICLE 13
if (JRequest::getVar('id')=='13' && JRequest::getVar('option')=='com_content') {
$template = $custom_template_name;
}
This will apply the custom template which name is inside the $custom_template_name to article with id=13. You can also use it to apply a different template to components, like I did with simplecaddy:
//TEMPLATE FOR SIMPLECADDY
if (JRequest::getVar('option')=='com_caddy'){
$template = 'shop';
}
You should really try to stay away from hard coding anything in to the template if it can be avoided. Not sure why you would specify that the article not be linked from a menu. The easiest way to accomplish this without having to write and code is to create a new menu, then add a menu item that links to the article you want to specify the template for. You don't have to put the menu in a module anywhere so it will never show up on the site, but it will show up in the menu assignment in the template manager.
You can do this with single articles, categories, sections, or even components. As long as you have a menu link to associate the template to. I always create an Admin only menu to put links that are needed to run the site, but do not need to be accessed by users.
As Brent said, avoid the temptation to modify core Joomla code! Doing this will likely stop you from doing Joomla upgrades 'cos you know it's going to break the core changes that you made.
Apart from the "hidden menu item" technique (which is useful but can break SEF URLs in some situations), a useful tool is Chameleon. This allows you to select specific articles/categories/sections (plus things like browser type, user group, component, whatever) and use these to trigger a certain template.
Though this is an old post, I thought I'd share my thoughts: You can easily change template on a single article, by implementing the onAfterInitialize() - function in a system plugin. No need to modify the Joomla core.
This works for Joomla 1.5, but should also work in 2.5:
function onAfterInitialise(){
if(true){ // f.ex. test for article ID or whatever
JRequest::setVar('template', 'beez'); // change template
}
}
In joomla 3.x versions, url-parameters are handled differently. The following was tested in joomla 3.4.8:
public function onAfterInitialise()
{
$app=JFactory::getApplication();
if(true){ // f.ex. test for article ID or whatever
$app->input->set('template', 'beez3');
}
}
More on writing plugins for Joomla here

Resources