Displaying an article by it's 'ranking'

For Joomla! 1.5 Coding related discussions, please use: http://groups.google.com/group/joomla-dev-general
Locked
User avatar
cbridges
Joomla! Intern
Joomla! Intern
Posts: 74
Joined: Tue Jun 10, 2008 10:57 am
Location: Dallas, TX (since Feb 09) - Prev London, UK

Displaying an article by it's 'ranking'

Post by cbridges » Thu Sep 11, 2008 3:28 pm

Hi guys,

Is there a way to give an article a ranking (say out of 5 or 10) and display one article at a time on a webpage, from a list of available articles, based on the articles ranking?

Background - On my site's home page I am only ever displaying one article at a time. I am displaying an article based on the results of a received URL string e.g.

Pseudo:

Get variables from string

If variablea = 1
then display articlea
else if variablea = 2
then display articleb
end
-----------

Now, I wish to build upon this functionality further by being able to choose from more than one article when for example variablea = 1, e.g.

Pseudo:

Get variables from string

Give articlea ranking 8
Give articleb ranking 4
Give articlec ranking 8
Give articled ranking 4

If variablea = 1
then display articlea or articleb
else if variableb = 2
then display articlec or articled
end
-----------

So, in theory, if the above functionality is installed and working correctly articlea would have preference over articleb and would be displayed on more occassions to users of the website & provide more page impressions for the higher ranked article. Over the period of a week or 2 you would expect to achieve results such as articlea achieving around 400 impressions and articleb achieving around 250 impressions, based on the two articles rankings.

If anyone could offer me any help that I would be extremely grateful.

Thanks
Colin Bridges
"Iced Tea with a bucket full of Sugar Please!"

whurley
Joomla! Enthusiast
Joomla! Enthusiast
Posts: 103
Joined: Thu Aug 24, 2006 3:59 pm

Re: Displaying an article by it's 'ranking'

Post by whurley » Thu Sep 11, 2008 5:55 pm

It would be possible, but you have to go about it in a somewhat different route. In order to manage ratings you would need a table to store the rating and a reference to the content item and a component to manage it. If you want to enter the rating on the administrator content management you'll need a editor-xtd to add controls to manage the rating and a plugin to handle the onAfterContentStore (or whatever the event is). If it's just user generated ranking you'll need a module to handle that data entry. One of the views the ranking component would be a 'Top X' and you would probably want a module to do that as well.

User avatar
cbridges
Joomla! Intern
Joomla! Intern
Posts: 74
Joined: Tue Jun 10, 2008 10:57 am
Location: Dallas, TX (since Feb 09) - Prev London, UK

Re: Displaying an article by it's 'ranking'

Post by cbridges » Fri Sep 12, 2008 8:57 am

The rating/ranking will not be user generated. I will assign it a ranking when the article is created.

I was hoping for a nice easy free Joomla plugin to handle this...!

If anyone could go into further detail, an almost step-by-step lamens guide, I would be an extremely happy camper!

Thanks
Colin Bridges
"Iced Tea with a bucket full of Sugar Please!"

whurley
Joomla! Enthusiast
Joomla! Enthusiast
Posts: 103
Joined: Thu Aug 24, 2006 3:59 pm

Re: Displaying an article by it's 'ranking'

Post by whurley » Fri Sep 12, 2008 2:21 pm

If it's just administrator driven you'll need the following:
An editor-xtd plugin
A content plugin
A module (optional)
A component

The editor-xtd will be something along the lines of the following:

Code: Select all

class plgButtonRateArticle extends JPlugin
{
	/**
	 * Constructor
	 *
	 * For php4 compatability we must not use the __constructor as a constructor for plugins
	 * because func_get_args ( void ) returns a copy of all passed arguments NOT references.
	 * This causes problems with cross-referencing necessary for the observer design pattern.
	 *
	 * @param 	object $subject The object to observe
	 * @param 	array  $config  An array that holds the plugin configuration
	 * @since 1.5
	 */
	function plgButtonRateArticle(& $subject, $config)
	{
		parent::__construct($subject, $config);
	}

	/**
	 * readmore button
	 * @return array A two element array of ( imageName, textToInsert )
	 */
	function onDisplay($name)
	{
		global $mainframe;

		$doc 		=& JFactory::getDocument();
		$template 	= $mainframe->getTemplate();

		// button is not active in specific content components

		$getContent = $this->_subject->getContent($name);
		$present = JText::_('ALREADY EXISTS', true) ;
		$js = /* Javascript to set form element on page to selected rating*/;

		$doc->addScriptDeclaration($js);

		$button = new JObject();
		$button->set('modal', true);
		$button->set('onclick', 'insertRating(\''.$name.'\');return false;');
		$button->set('text', JText::_('Rate'));
		$button->set('name', 'rate');
		// TODO: The button writer needs to take into account the javascript directive
		//$button->set('link', 'javascript:void(0)');
		$button->set('link', 'index.php?option=com_rating&view=ratearticle&tmpl=component');

		return $button;
	}
}
This creates the button below the content edit window with the name 'Rate' and invokes a modal dialog with the component com_rating, the view ratearticle, and displays only the component not the wrapper. There will also have to be a function that creates a form element on the page to store the rating. This will be used in the plugin that is triggered by the onAfterContentSave event. That would be something like:

Code: Select all

class plgContentRateArticle extends JPlugin
{

	/**
	 * Constructor
	 *
	 * For php4 compatability we must not use the __constructor as a constructor for plugins
	 * because func_get_args ( void ) returns a copy of all passed arguments NOT references.
	 * This causes problems with cross-referencing necessary for the observer design pattern.
	 *
	 * @param object $subject The object to observe
	 * @param object $params  The object that holds the plugin parameters
	 * @since 1.5
	 */
	function plgContentRateArticle( &$subject, $params )
	{
		parent::__construct( $subject, $params );
	}

	/**
	 * Example after save content method
	 * Article is passed by reference, but after the save, so no changes will be saved.
	 * Method is called right after the content is saved
	 *
	 *
	 * @param 	object		A JTableContent object
	 * @param 	bool		If the content is just about to be created
	 * @return	void		
	 */
	function onAfterContentSave( &$article, $isNew )
	{
		global $mainframe;

		$db		=& JFactory::getDBO();
		$rating	= JRequest::getVar('rating');

		if (true === $isNew)
		{
			/* SQL to insert rating */
		}
		else
		{
			/* SQL to update rating */
		}

		$db->setQuery($query);
		return $db->query();
	}
}
Then you'll need a component that will handle to actual selection and rendering of the article on the public side and the setting of the rating on the admin side. The actual code is kind of beyond the scope of this post, but it should probably have something like the following structure:

Public interface:
com_rating.php
controller.php
models/articles.php
models/article.php
views/articles/view.html.php
views/articles/tmpl/default.php
views/articles/tmpl/default.xml
views/article/view.html.php
views/article/tmpl/default.php
views/article/tmpl/default.xml

Admin interface
com_rating.php
controller.php
models/articles.php
models/article.php (optional)
tables/rating.php
views/articles/view.html.php
views/articles/tmpl/default.php
views/article/view.html.php (optional)
views/article/tmpl/form.php (optional)

Not sure about your level of experience developing for J!1.5, so if this is a repeat for you just ignore it.

The com_rating.php in both the public and admin sites include the controller.php which is the Controller part of the Model-View-Controller pattern. It would be something like:

Code: Select all

class RatingController extends JController
{

	function __construct( $config = array() )
	{
		parent::__construct( $config );
		// Register Extra tasks
		$this->registerTask( 'add', 			'edit' );
		$this->registerTask( 'unpublish', 		'publish' );
	}

	/**
	 * Method to show a rating view
	 *
	 * @access	public
	 * @since	1.5
	 */
	function display() {
		parent::display();
	}
}
though it would need functions to handle the normal tasks such as publishing, unpublishing, etc. on the admin side. Depending on which view is selected the appropriate Model is selected (article or articles) which would be something like:

Code: Select all

class RatingModelArticles extends JModel
{
	/**
	 * Data returned by the model
	 * @var array
	 */
	var $_data = null;

	/**
	 * Constructor
	 *
	 * @since 1.5
	 */

	function __construct()
	{
		parent::__construct();
	}

	/**
	 * Method to get rating data
	 *
	 * @access public
	 * @return array
	 */
	function &getData()
	{
		// Lets load the content if it doesn't already exist
		if (empty($this->_data))
		{
			$this->_loadData();
		}

		return $this->_data;
	}

	/**
	 * Method to load rating data
	 *
	 * @access private
	 */
	function _loadData()
	{
		$query = /* SQL to load ratings */;
		$this->_data = $this->_getList($query);
	}
}
The model is invoked by the View (the view.html.php in the appropriate directory) which then provides that data to the template for rendering:

Code: Select all

class RatingsViewArticles extends JView
{
	function display($tpl = null)
	{
		// Set toolbar items for the page
		JToolBarHelper::title(   JText::_( 'Ratings Manager' ), 'generic.png' );
		JToolBarHelper::publishList();
		JToolBarHelper::unpublishList();
		JToolBarHelper::deleteList();
		JToolBarHelper::editListX();
		JToolBarHelper::preferences('com_events', '200');

		$ratings		=& $this->get('Data');
		$this->assignRef('ratings', $ratings);

		parent::display($tpl);
	}
}
The view invokes the Model's getData() function with the get('Data') call and then creates a local reference called ratings which the template uses. The JToolBarHelper stuff creates the icons at the top of the admin site for publish, unpublish, etc.

The template is where all of the HTML happens, and in the case above it would have access to $this->ratings to output a list of ratings.

The xml files in the public interface views directories is where the configuration options would go. They could include things like minimum rating, number to display, how to order within a rating, etc.

User avatar
cbridges
Joomla! Intern
Joomla! Intern
Posts: 74
Joined: Tue Jun 10, 2008 10:57 am
Location: Dallas, TX (since Feb 09) - Prev London, UK

Re: Displaying an article by it's 'ranking'

Post by cbridges » Mon Sep 15, 2008 11:03 am

That is a hell of a lot to get my head around on a Monday morning - Thanks so much for the effort you have put in there!

Are you sure you can't be tempted to build a Joomla plugin? You would have your first downloader here, and I may even be tempted to donate! 8)
Colin Bridges
"Iced Tea with a bucket full of Sugar Please!"


Locked

Return to “Joomla! 1.5 Coding”