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.

Saturday, May 30, 2009

Convocation

Well convocation is coming up and I have accepted the honour of valedictorian. I now need to find time around my new job to write up a speech. I also keep adding tasks to my calendar to get back into my Mozilla Project but life keeps eating up my time. I don't know where you guys find the time. Do you have a magic box and when you need more time you just reach in and pull it out? Hit a reset button? Wiggle your nose?

Please, please share your secret.

Thursday, April 30, 2009

After Graduation ...

It has been awhile since I have posted on this blog. My final project required a lot of my time. My final project was an Online Ordering System for a comic book store. We used ASP.NET, C#, and MySQL. The team was also working on a Point of Sale system so we divided the work among the four of us. I did the back end logic for the Website and another guy did the Look and feel.

The hardest part of this project was implementing PayPal. The owner wanted PayPal as the means of payment. I had to do a lot of reading on the PayPal site and research to find the right solution for our site. Trouble shooting was a little difficult also. In the end, a customer could place an order and receive a receipt of the order from the store plus PayPal.

Now I'm looking for a job. I'm trying not to look for any job but a job that will align with my values, strengths and skills. The University of Waterloo has a Self-Assessment guide that is available to anyone. I have been going through it and I know myself better because of this assessment. I also joined a Job Finding Club that is being offered through Seneca. I hope to improve on my interview skills and learn techniques for tapping into the hidden job market.

It was a little hard to get back into groove after Kaitlyn was born still in January but I feel that I am back at 100%. My wife is still working through the process and has decided to look for work also. She has her own blog where she is blogging about her experience.

Tuesday, December 9, 2008

0.3 Release

So this is my last contribution to the OSD 600 Course but not my last contribution to my project. With this release I will be slowing down my activity but I hope I find the time to finish what I have started.

0.3 Release Details
My 0.3 Release project release can be found here.

The summary is I have landed a patch that keeps PGO for Thunderbird breaking on Windows. A module in the mozilla-core called lcms breaks when it is not linked into the xul library. The patch basically disables pgo for that module if it is not being linked into the library otherwise pgo is enabled for it.

As I was trying to enable pgo for Thunderbird related modules I discovered that PGO gets enabled for all modules. This was good news until I noticed that only 5 modules were getting optimized out of 74.

As I looked into this it turned out that the folder that most of the profile data was in was being deleted before used to optimize the modules. I created a new bug for this problem.

I have added my proposed patch and using that patch and doing some simple profiling 69 of 74 modules were optimized.

And that is my 0.3 Release.

I have learned about using Make and Python and compiler options for PGO. I still don't understand PGO entirely and don't understand why it does what it does. Example would be when using the option to optimize for size the compile spits out that the module was optimized for speed. I guess at some point I should make an inquiry on the Microsoft forums.

I plan on taking the OSD700 class but am looking at working with Eclipse.

Monday, December 8, 2008

Thunderbird components getting Optimized

So the problem I ran into with optimizing Thunderbird was all the profile data was getting deleted before it was used. I opened a new bug for this.

The other part of the problem was the python script, pgomerge.py, was not looking in the objdir/dist/bin/components for the profile data. So I have edited the pgomerge.py file and it does find and merge in all the profile data.

AWESOME!!!

New problem...the profile data in the dist/bin is not getting touched. I pretty sure my script is broken.

Time to look into this python stuff some more.

Saturday, December 6, 2008

New Bug for PGO

I've been trying to enable pgo on different Thunderbird components but I've been having problems.

Problem
The build output says these files are compiled with optimization flags but no optimization data is being collected.

It turns out the data is being collected and placed in the objdir/dist/bin/components directory. BUT!!!! This folder gets deleted.

I told ted about this. Here is a paraphrase of our conversation.

Basically, i need a flag to tell the make not to delete the folder when second profile build is being done and to look in the right directory for the optimization files.

I have posted a bug about this. This will be interesting to see how many components will get optimized without breaking.