I've been struggling with this for a while now. One my CMS' is ready to be extended with a translation module. I've been thinking of different methods but haven't figured out what is the best way so far.
Basically I have a CMS which uses a template system to parse all data from a database to the screen. I've come so far to "split up" my templates in different folders to be able to translate things that are "static" like images with text, footer links, etc.
However, there are many modules (pages, news, products) that have multiple fields that require a database driven method to be translated. I started off with a "languages" table which describes languages (id, iso_code, name). That's as far as I've come.. since there were a couple of projects that had to be done I haven't spend any more time to this subject thus far.
My first thought ("the quick fix") was to add multiple fields inside the tables (such as "title_nl", "title_en"), but this actually makes the database more crowded than is needed in my opinion.
My second thought was to create a table, "news_translations" for example. Which contained the language iso code, a news_id, the fields that require translation. Obviously a news_id connects the translation to it's original and the language iso code is used to get the right language from the database. Then in my front-end code I would first check if the default language is selected (=> select from the "news" table) or a translation (=> check inside translations table). If the 2nd case does not return any results a message is display "Sorry, no translation available" and the default is shown (or an error message, what fits the client best..).
But then there's a 3rd option.. my websites all use search engine friendly links (www.domain.com/pagename/ or www.domain.com/news/1-news-item-here.html). It would be far better if I had the ability to also "override" the SEF URL in my translations table. But I guess in this case I would always need 1 extra query to the translations table (since we first want to check for a translated page)... guess it's not such a big deal, but it's worth considering I guess.
In the end I guess by describing my options number 3 is what I need. But I'd like to have some other opinions on the subject as well! This is what I am trying to achieve:
Create a CMS system with multi language support
No language files (obviously this is why I use templates)
Being able to translate an original page/newsitem/product
Optionally: to change the SEF URL according to the language
I think option 3 has all this.. so the steps to create this solution is:
Create a _translation table for each item (or perhaps even in the
original by adding 2 new fields 'translation_to' (containing the
PrimaryKey) and 'translation_is' (containing ISO code) - however..
in that case all fields would need to be edited (which is not always
necessary.. plus by creating a 2nd table I keep the originals
divided with their translations, right?)
If the default language is NOT chosen first query the translations table to find a translation, if one is found display the
translation. Otherwise notify/error the user and/or display the
original text (based on the SEF URL... if the SEF is not found
within the translations or original table, then obviously display an
error only).
Any suggestions? :-)
Thanks for thinking along!
I would like to see what your table structure looks like. Probably the best thing you can do is generate two seperate new tables named something like "CONTENT_MULTI_LANG" & "SITE_LOCALES".
Then in the code that prints out your content do an initial check for a language flag. I'd create two separate classes for loading static content, something like "Content_LoadStandard" and "Content_LoadMultiLang". So then your conditional will look like this.
if ($this->site_locale == 'standard'){
$contentLoader = new Content_LoadStandard();
} else {
$contentLoader = new Content_LoadMultiLang($this->site_locale);
}
$content->blah($cheese);
Your "CONTENT_MULTI_LANG" table should be a narrowed down version of your standard CMS object table, only containing the relevant content field(s) that need to be in alternative languages.
// PSEUDO SQL
CREATE TABLE `LOCALE` (
`id` int(11),
`locale` varchar(16), // name of locale (language)
... // any other fields
)
CREATE TABLE `CONTENT_MULTI_LANG` (
`id` int(11),
`pcid` int(11), // parent content id
`lid` medint(), // locale id
`content` {$type}, // whatever type you use (varchar, text, bin, etc)
... // any other fields
)
In your Content_LoadMultiLang class, create methods to query alternate content using a join.
TIP: Might be a good idea to establish relationships in your table to do cascading deletes on content rows, that way if you delete content in standard your multi lingual version(s) will also be deleted.
From what I've seen from Drupal, option three is how they handle it, with a couple of tweaks. They keep it all in one table and a field called language. Then there is a separate table that maps which items are connected.
This way is primary language agnostic, meaning the content can be created in any language without requiring a translation in any other.
Related
Project
I am building an automated datasheet generator with the possibility to edit single blocks of the datasheet. There should be always a parent datasheet with the possibility to add translated versions to it. But those translated versions do not have to be the same in content, which means they can have a different amount of pages and blocks.
Basically you type in the article_number and my systems grabs all the default informations like article_number, manufacturer_number, ean_code, primary_image etc. from another database which stores all the product data.
Also every datasheet has a template assigned, which controls the main colors like primary, secondary and text color. Also a logo is assigned to every template.
But maybe some day there should be a possibility to have a template for pages aswell.
From this point you can start adding pages and blocks to every page etc.
Blocks should be stored as json strings and can have different types, like image, textblock, textblock with image, heading etc. So the fields can be quite different depending on the block type. Also the order of the blocks should be stored somehow. Blocks have their field definitions inside block_config also as a json string.
Finally the datasheet can be exported as a pdf file via TCPDF.
Basic Scheme
See here for my current scheme
The Problems
Let me make an example:
I create a datasheet with the article_number 12345.
This sheet contains several pages, and every page contains several blocks.
This datasheet should be available in german and english (more languages are possible too, like spanish, french etc.).
So the title and the subtitle can be different for every datasheet language.
But some attributes inside datasheets should be shared accross all languages.
There should be only one parent object which all translated objects should refer to, so I don't have to copy article 12345 over and over again inside the datasheets table.
Also the blocks can be different for every page and every translation of it.
So those fields like title and subtitle probably have to go into a separate translation table like datasheet_translations table with a locale column and datasheet_id column?
But do I have to do the same for all blocks and pages or is it fine to add a locale column directly to the pages and blocks?
So the questions are:
Is my database scheme any good and how to achieve all those goals above properly?
How to handle the translations? How to handle the order of the blocks, how to save them etc.?
I am quite unsure and afraid that the project will fail with a bad database structure.
I hope you can guide me into the right direction and I hope my explanation was clear enough. If there is any information missing, please let me know.
I need to create some sort of knowledge data base for updates (using PHP and MySQL).
Im using a database to store every update in HTML format.
People that are using the system work with different languages (information about users is stored in the DB).
Sometime the updates contain a text that should be translated and displayed taking into consideration the language that the user is working with.
What approach would you suggest, having in mind that i would like to avoid storing PHP and HTML in the DB.
I was thinking to create a col for every language and to store there the translation of every update, but what will happen it the update contains 2 different translations.
Prototype of the updates:
Some initial text
Translation of some part of the text
Some more text
Second translation
Final update text
I would create a table for languages and a table for updates. Then create a table that links languages to updates. One column for id, one column for language id, one column for update id. Then, you will be able to handle an update with multiple translations.
Another solution would be to use some sort of cdata tag, or something that you could parse easily enough. But this would be a very "wiki" based solution so there are patterns to follow to avoid mixing.
Example:
[English<-[This is the best update ever]->]
[Swedish<-[Detta är den bästa uppdateringen någonsin]->]
I am currently making a web page with dynamic content from a database (a restaurant menu) storing item names, prices, yada yada. The restaurant usually caters to English and Japanese. I have stored the titles of the items in the database as English and Japanese, however when it comes to the type of the item, for example, Type: Drink, Type of Drink: Coffee I can obviously store the type of item alongside the item in the database, but it hardly seems worth it to store it twice as two different languages in the the database which would also make the form to add a new item a pain.
What is the best way to go about translating those little tiny pieces of information, like "Coffee", "Wine", "Click Here", "Menus", and using them on the page?
You can use gettext extension for translation static or predefined info on web page.
See manual http://php.net/manual/en/book.gettext.php
Example http://mel.melaxis.com/devblog/2005/08/06/localizing-php-web-sites-using-gettext/
I would store it in both languages, it makes the most sense to me. I don't see why you would go and do a request to your translation system each time you want to show any page in your menu.
If you are using an automatic translation system that you really trust, one thing that you could do is use it when adding a new item to make a suggestion. So, after the user enters the word in English on the form, automatically attempt to translate that into Japanese and put it in the Japanese field. If the user is satisfied with the translation, that's it for that task, otherwise he/she inputs with a better one.
if you are using any phph5 based framework , major framework have localization support like zend has Zend_Locale
if you want your own translation dictionary , keep key value pair data in database table and memcached between application and DB , so static data will be cached for particular expiry time and data base load will be get decreased and fast retrieval of data
Sorry for the stupid title, but I don't know how else to name this question :)
So I'm trying to build a very simple content management system that stores data in the database.
One of the data types is a "content type" (similar to WordPress's posts / custom post types).
A content type can be whatever: a page, a car listing, a comment, a book product etc.
Each content type has its own fields. For example:
a page has the: title, text.
a car listing has: make, model, type, year, price, ...
a book has: title, author, price
and so on...
The idea is that these content types are dynamic (and so are their fields). They would be added trough a extension of the CMS. The only built-in content type would be the page.
Anyway, I need advice on how to set up the database tables for them. This should be done from the main CMS, and not from the extensions which are supposed to be very easy to write using the CMS API.
How should I set up tables / table fields, in such a way that searching for results based on certain content type fields would be very fast?
WP uses a different table for the fields, and stores them as rows with a ID pointing to the post they are attached to. But this is pretty slow when you're searching for multiple fields...
There are a bunch of different options.
The most common is storing "key/value" pairs (I believe this is the WP model), alongside the content item. There are many problems with this model - boolean logic when searching quickly becomes unintelligible, content types aren't easily be defined and validated in code (e.g. "all CAR content types must have attribute engine size"), etc. However, they do make it easy to create and change content types.
Another model is to generate database tables on the basis of the content types, usually with a "base" content item as the root. There's a good discussion in Larman's book on how to model the database tables ("Applying UML and patterns"). This design creates a large amount of housekeeping code - creating and modifying the database tables is a pain, and I wouldn't recommend doing this for solutions where you're going to need lots of content types.
The most robust solution I've seen uses XML to store the content - often within a database. XML allows you to define a content type (using a DTD or schema), and validate/query it. It isn't as fast as SQL, though...
id suggest Neville K 's first solution which would need a structure with 4 tables. contents , content_properties_name ,content_properties_values and are joined in contents_properties (content_id , content_property_id , content_value_id ). its fast , search queries are a bit complicated
Trying to work this out, but I don't know what's the best practice for this kind of things.
I'm working on a website using 3 languages: English, French & Dutch. There are categories on the website and the category names are different for the 3 languages.
For example:
Stars -> English
Sterren -> Dutch
Stars -> French
So I was thinking about adding them to the database. It's also easier for me to add more categories later if needed.
Now I'm facing the problem how to do this. My solution is:
**Cat_lang (category languages)**
cat_lang_id
language
**Categories**
categories_id
cat_lang_id
cat_title
Using cat_lang_id I can link both tables to get the language I need.
Is this the best solution for this problem?
Thanks in advance.
So that you can expand your website more easily in the future, I dont recommend having a cat_lang table. Stick with a languages table that contains language_id and language_name, and have your categories table point to it. Doing it that way allows you to have other entity types in your database (e.g. articles) that also contain multiple languages.
This is a flexible and reasonable solution. You see the same type of design in large scale ERP systems that have to handle dozens of languages and the possibility of more being added at any time.
If I were doing a website in multiple languages, I would use Zend_Translate to do the translations. Basically, you create a Zend_Translate object which reads in data files. Then you make calls on that object to translate() giving it the english version and it will give the translation in the correct language. Zend_Translate will scan your source and find all references to requested translations which will make files that can be translated by hand.
You are going to have much more than just the category names to translate, so I would recommend an approach like this where you just read in the translate file.
If you don't plan for a massive scale website and that you don't plan to increase to 100 languages, you can do a simpler and 'less nice' solution that is to have only 1 table of categories, where you hard code the language code in the category_name, for instance:
**Categories**
categories_id
cat_title_fr
cat_title_en
cat_title_de
Then in your code you set a $language_code variable at the beginning of each page using an include, you can even analyze the domain name in the $_SERVER variables to asign the correct language an by default choose the one you like (if you leave the variable empty your queries will return no text).
and you generate your queries like this:
mysql_query("SELECT cat_title_".$lang." FROM categories;");
Yeah it is dirty because you hard code the language in your DB structure, but if you have the exact same categories in each language with just a translation of the name, it is simple to implement.
Besides to add a language you just need to add a field in your table with the new translation, for instance spanish would be
cat_title_es