Wednesday, December 23, 2009

TinyMCE - Strict XML Compliance

So I thought I was done.

I am always wrong about that.

Joomla is setup and the sample content has been written up and I thought I was done. But this project requires Strict XML Compliance. I have no idea why except that it does. So I make my way over to the w3c validator. Oh my I have errors.  Cue rolling eyes AND .  So I begin my attempt to clean up my html.  It is pretty clean to begin with but not for Mr. Validator!

The Errors
First few errors are easy.  <br />
are not allowed outside of a block tag.  Hmmm, what is that doing there anyways? Oh, thanks Joomla.  Ok, clean that up and next. <input />tags not allow outside of a block tag....huh? didn't I already have this problem.  Oh, thanks again Joomla.  Ok, that is fixed and now the really easy error to fix ( boy was I wrong ).  <img /> tags cannot have the border attribute.  No Problem!

The Fix
Go into the article editor.  Click on the offending image and set border to .... nothing.  Click update and done and done.

Of course toggle the editor to html mode just to confirm and ............... the border = 0 is back.  What?!?!?

The next Fix
Ok not a problem.  I'll just remove it here in the html and update.  Problem solved.  But .... I should check just in case.  What?!?!?!? It's back!  But!!! How?!?! Where?!?! AAAAAAAAAARGGGGGGG!!!!!!

At this point I'm about to declare that we cannot be strict compliant using Joomla when I finally discover the answer to life ....... I mean the answer to my problem.

The actual Fix
In plugins/editors/tinymce.php on line 353 is the valid elements control for the img tag.  On this line exists border=0 which means if border is missing add it with a value of 0.  So, I removed it.  And all is right in the world.

So to change what attributes tinymce forces, adds, or to change the default value. The file to change is plugins/editors/tinymce.php.

Good Luck and Good Night!

Tuesday, December 22, 2009

JoomFish Multi-Language In Custom Components

Table Of Contents
  1. What is JoomFish?
  2. How does it work with Joomla?
  3. Requirements
  4. First Step - Create translation.xml
  5. Second Step - Update SQL queries
  6. Third Step - Add direct translation parameters
  7. Finished!
Joomla and JoomFish
Developing components in Joomla that integrate with JoomFish can be frustrating for the uninitiated. There isn't much documentation or it is spread about in multiple articles. I didn't find the JoomFish forums too helpful for searching through but I eventually found everything I needed. This article is about putting all the pieces together.



What is Joomfish?
For those of you that do not know JoomFish is an multi-language extension for Joomla. It allows for a site to control the translations of multiple languages.



How does it work with Joomla?
In Joomla everything is broken into components, modules, plugins and content. JoomFish adds the ability to control the language translations for all these parts. The most common use is creating translations for content and menus.

But that is not all. JoomFish can also be used to manage translations for custom components.

Requirements
If you have never installed JoomFish or need assistance then please visit JoomFish Installation.
Software: Joomla version 1.5.15
JoomFish 2.0.4
PHP 5+

This article assumes: you are a php developer who is ripping up Joomla with extension development, you have a finished component you want to add multi-language support to, and you have JoomFish installed, working, and have played with it enough to understand how to manage translations.

Note:
If these assumptions do not apply to you please bookmark this page because once you start into working with JoomFish you'll need the information I am posting here.

First Step
We need JoomFish to be aware of the content that needs translating. This part assumes we have created our own tables to contain our content.

Create Content Description File
For JoomFish to know what content needs translation we need to create an xml file.
Here is a description of the xml file.

Create a new text file with the same name as the content table and the extension .xml.

The table we'll be using is ca_geekpower_accordianitem.

Note: I spelled Accordion wrong from the beginning and I have it spelled wrong all through out. :(

id is the primary key
accordianId is the parent this item belongs to
title is the name of the item which appears as a header
ordering is the order the item - not used here
content is the content to show or hide



The file name will be ca_geekpower_accordianitem.xml file.

The file contents are:

<?xml version="1.0" encoding="UTF-8"?>
<joomfish type="contentelement">
<name>Accordian Item</name>
<author>GeekPower</author>
<version>1.5</version>
<description>Definition for the Accordian component</description>
<reference type="content">
<table name="ca_geekpower_accordianitem">
<field type="referenceid" name="id" translate="0">ID</field>
<field type="titletext" name="title" translate="1">Accordian Item Name</field>
<field type="htmltext" name="content" translate="1">Content</field>
</table>
</reference>
</joomfish>
<joomfish type="contentelement"> - this specifics that this is a content element. There may be more to it than that.

<name>Accordian Item</name> - this is the name of this content element. This will appear in the translation administration section of JoomFish.


As you can see the name we provided is listed under the content elements.

<reference type="content"> - not sure about this so we'll leave it as content.

<table name="ca_geekpower_accordianitem"> - the name of the table.

<field type="referenceid" name="id" translate="0">ID</field> - the primary key for this table. Translate is 0 because we don't need a translation or a different value.

Note:
Keep this in mind if you have columns that contain data that doesn't need a language translation but needs a different value. In that case translate will be 1. Example: the name of an image file which will need to change for the each language.

<field type="titletext" name="title" translate="1">Accordian Item Name</field> - title is header of the accordian time. Type of titletext makes the editable area an input text box. See the description of xml from above for more information on types. This is also the text that will appear in the Translation manager for listing the items.



<field type="htmltext" name="content" translate="1">Content</field> - content is the content of the item and htmltext displays an editor.



Now that you have created this file, save it in the adminstrator/components/com_joomfish/contentelements folder.

After we have saved the file in the folder we can now go into the admin section -> Components -> JoomFish -> Translations and from the right hand side Select A Language -> Content Element.

We should see all our content listed with a state of a red dot meaning there is no translation and an x under published for not published.

Now we can translate our content and put it live but .... it is most likely that our translations will not appear on the front-end.

When JoomFish is installed it will intercept all database calls and using some magic ( basically I just haven't looked into it) will grab our translated content. IF our sql queries are setup correctly.

Second Step
Anywhere we are retrieving content from our custom tables we need to retrieve the primary key. For us this is the id column. If we do make these changes but our translated content is not appearing then we need to look at compatible query construction to make sure our query statements are in an acceptable format.

That is all that is required to get JoomFish to recognize our component, translate it and display it.

"But that fancy drop down menu for translating articles and menu's doesn't work for my component?", you are right! It doesn't work. But it can. There is a direct translation module for the admin section that controls what gets that fancy drop down menu.

Admin -> Extensions -> Module Manager -> Administrator -> Direct Translation




By adding a line to the components we can tell the direct translation module which components and which views of a component to display the drop down list.



Third Step
The line we'll use is: com_accordian#ca_geekpower_accordianitem#id#controller#items#task#!edit

First Part
... is the component name

Second Part
... is the table name

Third Part
... is the variable that holds the primary key of the item to translate. For the direct translation to work there has to be a way to check which item will be translated. Each of my items have a checkbox in front of them. The name of the checkbox is id[]. We only have to pass id because the Direct Translation Module (mod_translate.php) adds the [] to id.

Using firebug we can see that the checkboxes have id[] as the name.




Note: You may need to click on the image

Forth and beyond Parts
After the third part we get into the interesting stuff. Our component may have many views and each view uses a different table or certain views we do not want to allow any translations.

Filtering
The additional values represent name/value pairs in the URL. Our values ( controller#items #task#!edit ) indicate that for a parameter called controller it must have a value of items and for the parameter task is must not be the edit task.

Note:
The ! is the only operator that can be added to a value.

Finished!
So hopefully that helps you on how to add JoomFish support to your custom components.