I have a project that I am writing a component, module, and editor plugin for.
I have managed to piece together a rudimentary plugin that works with TinyMCE (at least) which:
- Displays a custom button
- Triggers a popup modal window containing a dynamic table of buttons using db data
- Inserts a custom, curly-braced placeholder into an article.
The part that I am concerned with is making my solution "upgrade proof".
I followed https://mrgott.com/13-joomla/17-how-to-create-joomla-editors-xtd-plugin-button-and-open-modal-popup as much as I could, until I needed to break away and build beyond what is mentioned. That resource warns:
NOTE: Yes, the first question that arises is: What if after each update your file will be removed as it’s not a part of Joomla’s com_content component. Yeah, that’s right, but actually I’m fine by keeping this file, and uploading it after each system update, rather then doing plugin development in the wrong and dirty way.
If you are building this plugin for your client, you should better build a component, or maybe you already built some component and just add a new view file there for your editors-xtd plugin.
I feel like my component will need more than just a new file in views
. I would rather learn "the right way". I don't want to "give up" like Philippe. What files do I need to create (copy into my component and modify) to make my plugin long-lasting? I could also use a tip on how to add a little icon to my custom button in the editor; right now I only have text with an empty space on its left side.
The onDisplay()
function in /plugins/editors-xtd/picturelinkcode/picturelinkcode.php
:
public function onDisplay($name)
{
$query_string = [
"option" => "com_content", // I want this to be "com_picture",
"view" => "article",
"layout" => "picturelinkcode", // some examples use "modal" here
"tmpl" => "component",
"editor" => $name
];
$link = 'index.php?' . http_build_query($query_string);
$button = new JObject;
$button->modal = true;
$button->class = 'btn';
$button->link = $link;
$button->text = JText::_('Linkcode');
$button->name = 'picturelinkcode';
$button->options = "{handler: 'iframe', size: {x: 600, y: 400}}";
return $button;
}
The /administrator/components/com_content/views/article/tmpl/picturelinkcode.php
file:
<?php
defined('_JEXEC') or die;
$document = JFactory::getDocument();
$this->editor = JFactory::getApplication()->input->getCmd('editor', '');
$this->editor = preg_replace('~[^\w[\]-]+~', '', $this->editor); // sanitize
/**
* ...better coding practice would probably be
* to store the js and the data processing
* outside of this tmpl file
* --apologies while sprinting
*/
$script = 'function insertPictureLinkcode(linkcode) {' . "\n";
$script .= ' var tag = "{loadpicture " + linkcode + "}";' . "\n";
$script .= ' window.parent.jInsertEditorText(tag, ' . json_encode($this->editor) . ');' . "\n"; // "jform_articletext"
$script .= ' window.parent.jModalClose();' . "\n";
$script .= ' return false;' . "\n";
$script .= '}' . "\n";
JFactory::getDocument()->addScriptDeclaration($script);
?><h3>Picture Linkcodes</h3><?php
// Retrieve all linkcodes and their associated counts
$db = JFactory::getDBO();
$subquery = $db->getQuery(true)
->select("id")
->from("#__fields")
->where([
"context = 'com_picture.picture'",
"name = 'linkcode'"
]);
$query = $db->getQuery(true)
->select("value AS linkcode, COUNT(*) AS picturecount")
->from("#__fields_values")
->where("field_id = ($subquery)")
->group("value");
$db->setQuery($query);
try
{
$resultset = $db->loadObjectList();
if (!$resultset)
{
echo "No Linkcodes Available Yet<br>";
}
else
{
?>
<form class="form">
<table>
<?php
foreach ($resultset as $row)
{
?>
<tr>
<td>
<button onclick="insertPictureLinkcode('<?php echo $row->linkcode; ?>');" class="btn btn-primary">
<?php echo $row->linkcode; ?>
</button>
</td>
<td>
(<?php echo $row->picturecount; ?>)
</td>
</tr>
<?php
}
?>
</table>
</form>
<?php
}
} catch (Exception $e) {
echo "<div class='bg-danger'>Picture Linkcode Query Error - Contact Developer</div>";
//echo "<div class='bg-danger'>" , $query->dump() , "<br>" , $e->getMessage() , "</div>";
}
Screenshots of my currently functional coding attempt: https://i.sstatic.net/OabHq.jpg (I should ask @Eoin what tech he uses to make those nifty animated gifs)
In case it matters, my component is nearly identical to the core's adminstistrator/components/com_contact
and my module will only have one job -- to replace placeholders in articles with dynamic content. My plugin will eventually have greater functionality than I am showing in this question.
com_contact
this would be thecontacts
view. Does your component have a model-view where items are retrieved using the database queries shown in your question?com_picture
doesn't yet have any altered files. All of the folders and files are just likecom_contact
with the exception that I have altered filenames, variable names, class names, and maybe a function name or two to align withpicture
instead ofcontact
. If I can get away with not writing amod_picture
module to render my{placeholder}
that would be best. Have I answered your question properly? @Sharkypicturelinkcode.php
file from/administrator/components/com_content/view/article/tmpl
to/administrator/components/com_picture/view/article/tmpl
but that resulted in View not found [name, type, prefix]: article, html, pictureView I only understand about 45% of what I am doing, the rest is "Joomla magic" to me. I don't fully understand the data that I am using in$query_string
. ...Ah, I have not yet created anindex.html
andview.html.php
files incom_picture/views/article/tmpl
modal.php
file in myarticle/tmpl
folder instead of calling the filepicturelinkcode.php
? More intuitive I think.contact
topicture
, you probably have#__picture_details
table in your database. But you're querying#__fields_values
table instead? So, are your items just custom field values or do you intend to manage them like in other components (e.g.com_contact
) and store them in their own table?