I've been trying to create a form in the article component backend, so that I can add few things attributes per article. I got this sample code from the joomla website documentation. http://docs.joomla.org/Adding_custom_fields_to_the_article_component
I understand the method onContentPrepareForm is an important function which adds this form in the joomla article backend. However, it doesn't appear for me. I somehow checked global other options and I got to see that the form comes up in the global article options as a seperate tab. However I'd like to add this form for each article.
The version of joomla I am using is 3.2 ... Btw I have enabled the plugin in the backend ...
<?php
/**
* @package Joomla.Site
* @subpackage plg_content_rating
* @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_BASE') or die;
jimport('joomla.utilities.date');
/**
* An example custom profile plugin.
*
* @package Joomla.Plugin
* @subpackage User.profile
* @version 1.6
*/
class plgContentRating extends JPlugin
{
/**
* Constructor
*
* @access protected
* @param object $subject The object to observe
* @param array $config An array that holds the plugin configuration
* @since 2.5
*/
public function __construct(& $subject, $config)
{
parent::__construct($subject, $config);
$this->loadLanguage();
}
/**
* @param string $context The context for the data
* @param int $data The user id
* @param object
*
* @return boolean
* @since 2.5
*/
function onContentPrepareData($context, $data)
{
if (is_object($data))
{
$articleId = isset($data->id) ? $data->id : 0;
if (!isset($data->rating) and $articleId > 0)
{
// Load the profile data from the database.
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('profile_key, profile_value');
$query->from('#__user_profiles');
$query->where('user_id = ' . $db->Quote($articleId));
$query->where('profile_key LIKE ' . $db->Quote('rating.%'));
$query->order('ordering');
$db->setQuery($query);
$results = $db->loadRowList();
// Check for a database error.
if ($db->getErrorNum())
{
$this->_subject->setError($db->getErrorMsg());
return false;
}
// Merge the profile data.
$data->rating = array();
foreach ($results as $v)
{
$k = str_replace('rating.', '', $v[0]);
$data->rating[$k] = json_decode($v[1], true);
if ($data->rating[$k] === null)
{
$data->rating[$k] = $v[1];
}
}
}
}
return true;
}
/**
* @param JForm $form The form to be altered.
* @param array $data The associated data for the form.
*
* @return boolean
* @since 2.5
*/
function onContentPrepareForm($form, $data)
{
if (!($form instanceof JForm))
{
$this->_subject->setError('JERROR_NOT_A_FORM');
return false;
}
/* if (!in_array($form->getName(), array('com_content.article'))) {
return true;
}*/
// Add the extra fields to the form.
// need a seperate directory for the installer not to consider the XML a package when "discovering"
JForm::addFormPath(dirname(__FILE__) . '/rating');
$form->loadFile('rating',false);
return true;
}
/**
* 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 string The context of the content passed to the plugin (added in 1.6)
* @param object A JTableContent object
* @param bool If the content is just about to be created
* @since 2.5
*/
public function onContentAfterSave($context, &$article, $isNew)
{
$articleId = $article->id;
if ($articleId && isset($article->rating) && (count($article->rating)))
{
try
{
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->delete('#__user_profiles');
$query->where('user_id = ' . $db->Quote($articleId));
$query->where('profile_key LIKE ' . $db->Quote('rating.%'));
$db->setQuery($query);
if (!$db->query()) {
throw new Exception($db->getErrorMsg());
}
$query->clear();
$query->insert('#__user_profiles');
$order = 1;
foreach ($article->rating as $k => $v)
{
$query->values($articleId.', '.$db->quote('rating.'.$k).', '.$db->quote(json_encode($v)).', '.$order++);
}
$db->setQuery($query);
if (!$db->query()) {
throw new Exception($db->getErrorMsg());
}
}
catch (JException $e)
{
$this->_subject->setError($e->getMessage());
return false;
}
}
return true;
}
/**
* Finder after delete 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 string The context of the content passed to the plugin (added in 1.6)
* @param object A JTableContent object
* @since 2.5
*/
public function onContentAfterDelete($context, $article)
{
$articleId = $article->id;
if ($articleId)
{
try
{
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->delete();
$query->from('#__user_profiles');
$query->where('user_id = ' . $db->Quote($articleId));
$query->where('profile_key LIKE ' . $db->Quote('rating.%'));
$db->setQuery($query);
if (!$db->query())
{
throw new Exception($db->getErrorMsg());
}
}
catch (JException $e)
{
$this->_subject->setError($e->getMessage());
return false;
}
}
return true;
}
public function onContentPrepare($context, &$article, &$params, $page = 0)
{
if (!isset($article->rating) || !count($article->rating))
return;
// add extra css for table
$doc = JFactory::getDocument();
$doc->addStyleSheet(JURI::base(true).'/plugins/content/rating/rating/rating.css');
// construct a result table on the fly
jimport('joomla.html.grid');
$table = new JGrid();
// Create columns
$table->addColumn('attr')
->addColumn('value');
// populate
$rownr = 0;
foreach ($article->rating as $attr => $value) {
$table->addRow(array('class' => 'row'.($rownr % 2)));
$table->setRowCell('attr', $attr);
$table->setRowCell('value', $value);
$rownr++;
}
// wrap table in a classed <div>
$suffix = $this->params->get('ratingclass_sfx', 'rating');
$html = '<div class="'.$suffix.'">'.(string)$table.'</div>';
$article->text = $html.$article->text;
}
}
EDIT POST: I added this code to /administrator/components/com_content/views/article/tmpl/edit.php
<?php
$i = 0;
$fieldSets = $this->form->getFieldsets();
foreach ($fieldSets as $name => $fieldSet) :
if($i <= 3){
$i++;
continue;
}
echo JHtml::_('bootstrap.addTab', 'myTab', $fieldSet->name, JText::_($fieldSet->label, true));
?>
<div class="tab-pane" id="<?php echo $name;?>">
<?php
if (isset($fieldSet->description) && !empty($fieldSet->description)) :
echo '<p class="tab-description">'.JText::_($fieldSet->description).'</p>';
endif;
foreach ($this->form->getFieldset($name) as $field):
?>
<div class="control-group">
<?php if (!$field->hidden && $name != "permissions") : ?>
<div class="control-label">
<?php echo $field->label; ?>
</div>
<?php endif; ?>
<div class="<?php if ($name != "permissions") : ?>controls<?php endif; ?>">
<?php echo $field->input; ?>
</div>
</div>
<?php
endforeach;
?>
</div>
<?php echo JHtml::_('bootstrap.endTab'); ?>
<?php endforeach; ?>
As you've mentioned the core tmpl file won't support your changes.
Hacking the core files (as you've done) is a very bad idea for several reason, including that they could be overwritten when the next 3.2.x security patch is released (like the upcoming 3.2.1) and most certainly will be when 3.5 is released. Given the rapidity Joomla releases security patches and their regular 1-click Major and Minor update cycle the last thing you want to be worrying about is your changes being blown away.
Luckily Joomla lets you create template overrides, the process for admin is pretty much the same as overrides for front-end templates.
Luckily for you the modification is in the right file, assuming you're using the default Admin template
Isis
simply copy/administrator/components/com_content/views/article/tmpl/edit.php
to:
/administrator/templates/isis/html/com_content/article/edit.php
You may want to revert your original file but as mentioned it's almost certainly to get updated in either a security update or version update.