ASP.Net / MySQL : Translating content into several languages - asp.net

I have an ASP.Net website which uses a MySQL database for the back end. The website is an English e-commerce system, and we are looking at the possibility of translating it into about five other languages (French, Spanish etc). We will be getting human translators to perform the translation - we've looked at automated services but these aren't good enough.
The static text on the site (e.g. headings, buttons etc) can easily be served up in multiple languages via .Net's built in localization features (resx files etc).
The thing that I'm not so sure about it how best to store and retrieve the multi-language content in the database. For example, there is a products table that includes these fields...
productId (int)
categoryId (int)
title (varchar)
summary (varchar)
description (text)
features (text)
The title, summary, description and features text would need to be available in all the different languages.
Here are the two options that I've come up with...
Create additional field for each language
For example we could have titleEn, titleFr, titleEs etc for all the languages, and repeat this for all text columns. We would then adapt our code to use the appropriate field depending on the language selected. This feels a bit hacky, and also would lead to some very large tables. Also, if we wanted to add additional languages in the future it would be time consuming to add even more columns.
Use a lookup table
We could create a new table with the following format...
textId | languageId | content
-------------------------------
10 | EN | Car
10 | FR | Voiture
10 | ES | Coche
11 | EN | Bike
11 | FR | VĂ©lo
We'd then adapt our products table to reference the appropriate textId for the title, summary, description and features instead of having the text stored in the product table. This seems much more elegant, but I can't think of a simple way of getting this data out of the database and onto the page without using complex SQL statements. Of course adding new languages in the future would be very simple compared to the previous option.
I'd be very grateful for any suggestions about the best way to achieve this! Is there any "best practice" guidance out there? Has anyone done this before?

In your case, I would recommend using two tables:
Product
-------------------------------
ProductID | Price | Stock
-------------------------------
10 | 10 | 15
ProductLoc
-----------------------------------------------
ProductID | Lang | Name | Description
-----------------------------------------------
10 | EN | Bike | Excellent Bike
10 | ES | Bicicleta | Excelente bici
This way you can use:
SELECT * FROM
Product LEFT JOIN ProductLoc ON Product.ProductID = ProductLoc.ProductID
AND ProductLoc.Lang = #CurrentLang
(Left join just in case there is no record for the current lang in the ProductLoc table)

It's not good idea just to add new columns to existing table. It will be really hard to add a new language in the feature. The lookup table is much more better but I think you can have problem with performance because number of translated records.
I think best solution is to have a shared table:
products: id, categoryid,
and same tables for every language
products_en, products_de: product_id (fk), title, price, description, ...
You will just select from the shared one and join table with your language. The advantage is that you can localize even the price, category, ...

Related

Optimize complex scenario in Cucumber

I have been working on an automation project where I have to write cucumber test for search filter. Search filter works dynamically where parameters are nested - next parameter are populated based on previous parameter e.g. On selecting "Subscribers" next parameters in dropdown are "Name", "City", "Network". Likewise, on selecting "Service Desk", parameters in subsequent dropdown are "Status", "Ticket no.", "Assignee". I am using Scenario Outline as below:
Scenario Outline: As a user, I can search records
Given I am on search page
When I search on "<category>" and "<nestedfilter>"
Then I see records having "<category>" category
Examples:
|category |nestedfilter|
|Subscribers |Name |
|Subscribers |City |
|Subscribers |Network |
|Service Desk|Status |
|Service Desk|Ticket no. |
|Service Desk|Assignee |
The filter could be more complex as there could be more nested filters based on previous nested filters.
All I need to know if there could be a more efficient way to handle this problem? For example passing data table to step_definition for which I am not too sure.
Thanks
If you really need the order of your items to be preserved, use a data table instead of a scenario outline.
A scenario outline is a shorthand notation for multiple scenarios. The execution of each scenario is not guaranteed. Or at least it would be a mistake to assume a specific execution order. The order of the items in a data table will not change if you use a List as argument and therefore a lot safer in your case.
A common mistake with Cucumber is to use Scenario Outline and example tables to do some sort of semi-exhaustive testing. This tends to hide lots of interesting things about the functionality being developed.
I would start writing single features for the searches you are working with and explore what those searches are and why they are important. So if we start with your first one we get ...
Note: all of the following assumes a background step Given I am searching
When I search on subscribers and name
Then I should see records for subscribers
and with the second one
When I search on subscribers and city
Then I should see records for subscribers
Now it becomes clear that there is a serious flaw in these scenarios, as both scenarios are looking for the same result.
So what you are actually testing is that
The subscribers search has name and city filters
A subscriber search should return subscriber results
Now you can refactor and get
When I do a subscriber search
Then I should see city, name, network filters
When I do a subscriber search
Then I should only see subscriber results
note: This is already much more efficient as you have reduced the number of scenarios from 3 to 2, and reduced the number of searches you have to do from 3 to 1.
Now I have no idea if this is what you want to do, but this is what your current scenario is doing. However because you are using an Outline and Example tables you can't see this.
The fact that you have a drop-down and nested filters is an implementation detail, which describes how the user is trying to achieve what they want to achieve.
If you think of what you're trying to do as examples of how the system behaves, rather than tests, it might be easier. You're not looking for something exhaustive. You also want your scenarios to be specific, so that you're illustrating them with realistic data and concrete examples. If you would commonly have some typical data available, that's a perfect thing to set up using Background.
So for instance, I might have scenarios like:
Background:
Given I have subscribers
| Name | City | Network | Status | etc.
| Bob | Rome | ABC | Alive | ...
| Sam | Berlin | ABC | Dead | ...
| Sue | Berlin | DEF | Dead | ...
| Ann | Berlin | DEF | Alive | ...
| Jon | London | DEF | Dead | ...
Scenario: First level search
Given I'm on the search page
When I search for Subscribers who are in Rome
Then I should see Bob
But not Sue or Jon.
Scenario: Second level search
Given I'm on the search page
When I search for Subscribers in Berlin on the ABC network
Then I should see Sam
But not Sue or Ann
etc.
The full-system scenarios should be just enough to understand what's going on. Don't use BDD for regression. It can help with that, but scenarios will rapidly become slow and unmaintainable if you try to cover every case. Delegate to integration and unit tests where appropriate (see "the testing pyramid").

Naming Cucumber's Data Table

I am creating test cases on forms that could contains over 50 parameters, some of them would show up when a certain set of questions would be answered specifically.
The data tables were getting very long so I broke them into multiple data tables, each for a specific section of form.
I don't want to add every heading in the step so I want to use the data table's name instead.
Instead of:
Scenario:
.
.
.
When I fill in <title> <first name> <surname> ...
|title|first name|surname|...|
.
.
.
I want:
When I fill in <personal details>
And "personal details":
|title|first name|surname|...|
.
.
.
Is it possible to add and use the data table's name as the placeholder?
Note: I am working with Behave and Python.
It's definitely not possible using the <> syntax.
If you don't have many rows and your main concern is the readability of very wide tables then one option might be "transposing" the table like this:
When I fill in the personal details
| Field | Value |
| Title | Prof. |
| Surname | Einstein |
| ... | |
An other option could be to define the recurring set of properties in the Background like this:
Background:
Given the personal details for 'minimal personal details'
| Surname | First name |
| Doe | John |
And the personal details for 'insufficient personal details'
| First name |
| Jack |
And the personal details for 'all personal details'
...
...
When I fill in personal details using 'insufficient personal details'
The bindings of the background register their data in the context and the 'when' binding uses the data from the context.
In either case, you'll need a binding that will tolerate missing properties and catch unknown ones.
Am not sure about what you are asking but if you are using the same details in different scenarios then it is better to use Background option of Cucumber. So that it will be checked before executing every scenario.
Tables in Gherkin are a view on the real data (meaning a subset of columns and which rows are of interest). For readability reasons (and that somebody understands what you are doing), you should have at most 7 (plus/minus 2) columns. Maybe, the remaining data can be injected from configuration-files or config-profile database ?!? You basically use the provided Table columns as keys to be able select the configuration-row and to retrieve the remaining data from your configuration-profiles.

How to create a table like structure in drupal content type?

I am almost there with this but cannot seem to get this functionality going as planned.
I am creating a questionnaire using drupal content type. What I am trying to do is to create a table like structure as below in content type. The second and third column contain check boxes and first column data(i.e computer, internet) and first row(i.e Everyone have access , Nobody have access) are taxonomy terms . Is it possible to display like this in content type by using some modules in drupal? Anybody have any better suggestions?
| | Everyone have access | Nobody have access |
---------------------------------------------------------
| Computers | 1 | 2 |
---------------------------------------------------------
| Internet | 1 | 2 |
---------------------------------------------------------
| Fax | 1 | 2 |
---------------------------------------------------------
You can use the Term Level Field module. This module provides a field type for referencing terms with a level to an entity.
You may use Editable fields with Views module. Of course, if you didn't need such a display (table forms) you should use Views Bulk Operations modules.
If you need to do this in a node use Tableform module. But if you want to show nodes whike editing a node it is the same. A node should not be used for tasks just for content.

How do you know if your data is displayed semantically correct as a table or something else?

I have information from a database. It is one row. Now, it is old, and tables were used to display the data. It works but is ugly and hard to maintain. I'm "fixing" it. But, I don't know if it is considered tabular or not. It comes from database tables, but I don't know that what it means to be semantically correct in using a table for display.
I have several sections like this on a webpages. They are all calls to the same database, different sets of data, sectioned off in the webpage.
For example, one set is a general set of information, lastname, firstname, middle, other stats...
Next section might be address, etc.
A while back when I did asp.net forms there was a list view, I think that was similar to what I need to create (I'm using just straight html and a scripting language, no controls).
How should I be displaying the information to be semantically correct?
edit: It is one person that does not repeat.
edit: A single record, but displayed on the same page, just various SELECT statements to get that data all on the same page.
If it's tabular data (i.e. multiple records displayed underneath each other) then a <table> would probably be the best choice. If it's a view of a single record, maybe even aggregating data from multiple tables then the <table> shouldn't be your first choice.
Tabular data:
--------------------------------
| ID | Name | Description | Date |
--------------------------------
| 01 | ... | ... | ... |
| 02 | ... | ... | ... |
Not tabular data:
ID: ...
Name: ...
Description: .................
.................
.....
Date: ....

Asp.Net Localized SQL Content / How to define classes

I have made a lot of research about this subject and now I am asking for some advices :)
I am working on a multilingual intranet.
I am not talking about translating the UI (using resources etc..) but in translating the content.
I have several tables based on this format :
Product
-------------
IdProduct | DateCreation
ProductT
-------------
IdProduct | IdLanguage | ShortName
Question
-------------
IdQuestion | DateCreation
QuestionT
-------------
IdQuestion| IdLanguage | ShortName | Description
Language
-------------
IdLanguage | Culture
My question is now :
How to write the C# Classes for this Model. I am using Asp.Net MVC with a repository Pattern and Stored Procedures (No ORM like EF etc..) because we can't (not my decision)
For example for the Questions objects, I Will have to Display a correctly translated questions List in a page.
If the selected language version is not found for a question, display the English translation.
So how can I write down my classes to fit this need, and to be usable by my repositories, controllers and views
You need to create your custom ResourceProviderFactory. As example look at ASP.NET 2.0 Custom SQL Server ResourceProvider. I use constant string with PK for accessing translation.

Resources