Sunday, April 15, 2007

موقع متعدد اللغات

المبرمج كريم كان اقترح فكرة إني اكتب مقال تقني مرة كل شهر واخترت يوم 15 عشان يكون موعده .. ولأني طبعاً لم يسبق لي كتابة موضوع كامل قبل كده فالبوست دا عبارة عن دردشة بصوت عالي ..

إحنا دلوقتي عايزين نعمل موقع بكذا لغة باستخدام ASP.net بحيث يكون واجهة الموقع بالشكل التالي


الاسمما علينا
الوظيفةمطور مواقع
العنوانمصر

الكلمات باللون الأخضر دي ثابتة في الصفحة والكلمات المقابلة حتيجي من داتا بيز وتتحط في Labels

طيب إحنا حنتكلم على نقطتين في الموضوع ده :

أول حاجة شكل قاعدة البيانات حيبقى عامل إزاي
إزاي حبني قاعدة البيانات بتاعتي لموقع متعدد اللغات هل حعمل الـ structure واحد لقاعدة بيانات وبعد كده اعمل قاعدة بيانات لكل لغة ولا اعمل نفس قاعدة البيانات واخلي فيها Fields مستقلة لكل لغة .. طبعاً الطريقة الأولانية حتكون اسهل كتير بالنسبة لي كمبرمج لأني عند استدعاء اي صفحة بأي لغة كل اللي حيختلف عندي ساعتها هو الـConnection String أما الكود اللي أنا كاتبه فحيفضل زي ما هو .. وممكن الـ Connection String يتنادى مرة واحدة بس في بداية الـ session أو في ال Constractor لو أنا عامل Class

وبالمرة حكون عامل بروجيكت لكل لغة عندي ويبقى الروابط زي ما بنشوفها في المواقع الـ ٍStatic

لو عايز تعرض الصفحة العربي يبقى

http://.......................com/arabic/index.aspx

ولو الإنجليزي يبقى

http://.......................com/English/index.aspx

ويبقى عندي على رووت الموقع فولدر بكامل الموقع لكل لغة

لكن الطريقة دي رغم إني مش حتعب كتير فيها كمبرمج إلا إني حدفع تمن داتا بيز زيادة ومالهاش لازمة وكمان حضاعف المساحة المستغلة .. ولأنك غالباً واخد من السيرفر اللي أنت عامل عليه هوست عدد محدد من الداتا بيز .. ولو إن دلوقتي السيرفرات بتدي عدد غير محدود من الداتا ييز .. لكن برضه الأفضل الأصل إن لكل مشروع ولكل موقع قاعدةبيانات واحدة بس .. وكمان لو فرضنا إن موقعك زاد عدد اللغات فيه فمش معقول لموقع واحد تعمل 5 أو 6 قواعد بيانات .. و5 أو 6 أضعاف المساحة

فعشان كده نلجأ للأسلوب التاني اللي حيكون فيها فكرة مختلفة شوية لأنك حتعمل كل جدول فيها Fields للعربي وللإنجليزي وحتخلي اسم الفيلد نهاية تعبر عن لغته ...

يعني مثلاُ لو قلنا عندنا جدول العملاء اللي باين في المثال فيه

CustomerID (index , Primary Key , Identity),

CustomerName_A (الاسم بالعربي), CustomerName_E(الاسم بالإنجليزي),

CustomerJob_A(الوظيفة بالعربي), CustomerJob_E(الوظيفة بالإنجليزي),

Address_A(العنوان بالعربي), Address_E(العنوان بالإنجليزي)

وطبعا الـ Fields العربي Unicode وعملية ال Insert حتكون باستخدام الـ Parameters وإلا حتلاقي الناتج على كتير من السيرفرات ؟؟؟؟؟؟؟؟؟

وحيكون لعبنا بالحرف الأخير لأنك حتحط session للغة


Session("langauge") = "A"

أو

Session("langauge") = "E"


في الـ Session start في البرنامج حتبدأ مثلاً بالعربي وفي زرار تغيير اللغة تبدأ تغير ما بين اللغتين

If Session("langauge") = "A" then

Session("langauge") = "E"

Else

Session("langauge") = "A"

End if

لو عايز تجيب البيانات باللغة العربي يبقى الـQuery بالشكل ده حتجيب dr اللي هو عبارة عن datarow لل Record المطلوب عرضه

Lbl_CustomerName.text = dr("CustomerName_" & Session("langauge"))

Lbl_CustomerJob.text = dr("CustomerJob_" Session("langauge"))

Lbl_Address.text = dr("Address_" Session("langauge"))

دا شكل كودك .. شكل موحد يختلف حسب الـ session


تاني حاجة
بالنسبة للكلمات اللي باللون الأخضر في المثال واللي هي حتتغير حسب اللغة المختارة فببساطة فيه كذا حل ليها ..

الأول .. إنك تعمل جدول في الداتا بيز لكلمات التصميم بحيث يتم استدعائها .. شايفها طريقة غريبة جداً .. وحمل زائد بدون داعي على الداتا بيز وما ذكرتش الطريقة إلا لأني اعلم شركة خارج مصر تستخدمها وتؤكد على أفضليتها على باقي الطرق

الطريقة الثانية أن تضاعف محتويات كل صفحة فكل كونترول للغة العربية له نظيره في الإنجلزية ويتم التبادل بين ظهور كل منهما عبر زر تغيير اللغة .. وهنا يظهر نفس السؤال .. ماذا لو كان عندنا أكثر من لغتين ..

الطريقة الثالثة المفضلة عندي ... وهي استخدام namespace اسمها Resources ونقوم بالخطوات التالية :
1- انشأ ملف Resourc وليكن اسمه Langauge_A وآخر Langauge_E وبطريقة كتابة الـ XML ادخل نفس المفاتيح في كلا الملفين ولكن بقيم مختلف كمثل التالي

في العربي :

<data name="CN">

<value>الاسم : value>

<data>

في الإنجليزي

<data name="CN">

<value>Name :value>

</data>

2- في كود صفحتك إنشأ object من الـ namespace المذكورة وليكن كالتالي

Public SafLang As System.Resources.ResourceManager
SafLang = New System.Resources.ResourceManager("Ma_3lina.Langauge" & Session("Langauge"), System.Reflection.Assembly.Load("Ma_3lina"))

نلاحظ أن الـ object سيختار الـ Resource الخاص باللغة الذي سيستعمله من الـ session وحسب حالتها Ma_3lina هي الـ NameSPace الذي نعمل تحته

أيضاً لا حظ أن الـ object اللي سمناه
SafLang سماحيته Public .. لماذا ؟؟؟

3- في صفحات الديزين يمكن وضع الـ object المسمى SafLang والحصول على القيم داخله

<td><%=SafLang.GetString("CN")%></td>


ففي حالة الحصول على البيانات من ملف العربي تظهر الكتابة بالعربي وفي حالة الإنجليزي تظهر بالإنجليزي يمكن عندها إضافة عدد كبير من ملفات الـ Resource وسيبقى الكود كما هو .. لن يتغير إلا زر تغيير اللغة فقط بعد إضافة Fields للغات في الداتا بيز

ياريت تعذروني لو الموضوع متلخبط شوية بس أرجو أن يكون فيه فايدة ولا تبخلوا علينا بالنصح

12 comments:

خالد وليس بخالد said...

رغم ان مجال دراستي بعيد جدا جدا عن البرمجة والكمبيوتر
الا انني احب البرمجة واتمنى ان اصبح مبرمجا

انا حاولت السنة اللي فاتت اتعلم لغة بي اتش بي
مع نفسي
لاقيتها مملة
انما الحمد لله اتعلمت هتمل مع نفسي ومبتدئ في الفلاش
وبصراحة الاي اس بي
دي خطيرة
بس مشكلتها يا باشمهندس -على ما سمت-
ان الاسكربتات والتجهيزات بتاعتها غير مجانية

الوقتي انا عايز استشيرك
اتعلم بي اتش بي ولا اي اس بي؟؟
وفقكم الله

Mohamed A. Ghaffar said...

كلام كبير سصعب على امثالى فهمه

عصفور المدينة said...

كله كويس وطريقتك في الشرح كويسة مش زي ما انت قلت في الأول انك مش حتعرف تشرح
بس فيه عيب ف الطريقة وهي ان التصميم حيكون كله بأسماء الريسورس
فاحنا بنفضل دايما ان يبقى فيه كود موحد يلف على الصفحة ويستبدل الشروحات من جدول أو xml
وذلك للسبب المذكور والسبب الثاني هو تكرار استخدام الكلمات كثيرا فوجود مصدر موحد للترجمة يوفر ذلك
مع اضافة مهمة تقوم باسترجاع جميع الكلمات ووعها في الجدول أو
xml المذكور
واضح؟؟؟؟؟؟؟؟

عصفور المدينة said...

أخانا الدكتور خالد
بالله عليك ركز في الطب والعلوم الشرعية إلى جانب ذلك
master of everything master of nothing
نحن محتاجون كما تعلم إلى أطباء ملتزيمن أكفاء
وكما تعلم أن العالم مليء بالمبرمجين ومصممي المواقع

Ma-3lina said...

ايه ؟؟؟

عصفور المدينة said...

مش واضح؟
مبدئيا كلمة جدول= database table | XML file
تخيل انت ملف الريسورس ده بيخدم على موقع فيه 200 صفحة فمتوقع من طريقتك أني أضع إنتري لكل عنصر باللغتين
الاقتراح وهو ما نستخدمه فعلا أن يتم عمل جدول يكون التعامل معه عن طريق قيمة الكلمة المطلوب ترجمتها مرة واحدة يعني كلمة الاسم تكون مثلا موجودة في عدة صفحات في نفس الموقع فأنا لما أصمم أصمم بالعربي ويكون فيه فنكشن في أول عرض الصفحة تقوم بالمرور على جميع العناصر وترجمة القيم المحتملة من جدول الترجمة

وإذا كان الراجل بيعرض الموقع بالعربي ما اعملش حاجة خالص لأنه حيشتغل طبيعي

وكمكمل لذلك يكون فيه فنكشن يتم استعاؤها وقت اللزوم تقوم باسترجاع الكلمات ووضعها في الجدول استعدادا لترجمتها

عصفور المدينة said...

translation table (ar_text text,en_text text)

function retrieve_strings
-loops on all controls and appends records to translation table by filling the ar_text for values that don't exist

function translate_page
called only in English mode
loops on all controls and seeks value in the translation table of the Arabic text then replaces the text with corresponding English text
if the arabic text not found in the table append it for future translation

call translate_page function in every page load

so that way is easy cus u design the page and write text values not asp.net code in text values and the code at runtime translate the page and adjust other display properties that may differ in english from arabic like orientation or display formats etc.

أمــانــى said...

انا ولا فاهمة ولا حاجة مش لازم افهم
يعنى احنا هانفهم فى كل حاجة ولا ايه الحكاية ؟!
:D
انا بأحس عالم الكمبيوتر زى عالم المحيطات ههه
تحياتى لك ولكل المبرمجين وربنا يوفقكم يــااااااااارب لاننا من غيركم كنا هنستخدم الكمبيوتر ازاى

سكتم بكتم said...

أية الحلاوة دي...بس علي رأي حكيم في الأغنية بتاعتة الي مش فاكرها دلوقتي الي بيقول فيها الكلام ده كبير الكلام ده خطير....
الحمد لله بعد مقريت البوست دة عرفت أن أنا والكرسي الي قاعد علية شئ واحد أنا وهوا مش فاهمين حاجة
بس الكرسي مريحني وأنا مش مريح حد

khaled said...

عزيزى ما علينا
اخى العزيز
اود
ان اقدم لك جذيل الشكر و الامتنان لتقديمك مثل هذه المواضيع التخصصية و كمان بتنظيمها بالنقاط و المشاكل و الرد عليها و حلها لكن اخى لى مجموعة نصائح صغيرة

اولا

واضح من توجيهك البوست ده انه متوجه لفئة وحيدة من زوار مدونتك و همه مش المبرمجين و مطورى المواقع و لكن لمستخدمى لغة
ASP.Net
بالتحديد
يعنى حتى مش
VB
و الا
سى شارب
او اى حاجة
و ده اخى العزيز سبب وجود بعض التعليقات اللى بينت عقدة هؤلاء ووضحت مدى صعوبة فهم هذه المسائل فما بالك بتعلمها او حتى محاولة اخذ فكرة و لو بسيطة عنها

ثانيا

من المفروض او المتعارف انك عندما تبدأ بشرح مجال معين و لو حتى ان كان متخصص جدا ان تبدأ بالتعريف عن هذه اللغة و اصلها و كيفية ترجمتها و ما هى البرامج المطلوبة فى نبذة مختصرة و ده ما يمنعش انك تعملها على حلقات
مش مجرد مرة و عدت

ثالثا

اود ان اسأل من باب الفضول اخى عصفور المدينة
هو انت شغال ايه؟
عجبنى تجاوبك مع الموضوع و حرصك الجميل على التوضيح و الرد عليه
شكرا ليك
اما اخى الدكتور خالد
فانا باحب لغة بي اتش بي و اتعلمتها حبا فيها و هى جميلة و ميزتها انها مجانية و تناسب جيوبنا جميعا
و يجعله عامر
:)

رابعا

اخى ما علينا
انا باقترح لو تنظم الحاجات دى فى مواضيعك و تشرفنى بمشاركاتك دى فى مدونتى تعليم قلى لو حابب و انا اشيرهالك بس يا ريت تسهل على الناس شوية
:)
انا باتكلم بجد و لازم تفكر كويس و اهه ايدنا مع بعض نعمل خير للناس ينفعنا يوم القيامة و بلاش اليأس السريع ده انت ان شاء الله هاتكتب يعنى هاتكتب
:)

خامسا

انا كان نفسى اطبق بس معلش الكمبيوتر الاحمق بتاعى رافض ينزل ال
IIS
السفيه لمشكلة فى مايكروزفت شبابيك
هاصلحه و اتابع معاك
جزاك الله خيرا
و قوم نام بقى لاحسن الكلام ما بيخلصش لما نتلم على بعض
:)

khaled said...

معلش يا ابو مريم باشا هاتعبك معايا
ما تعرفش برنامج خارجى غير
IIs
اللعين ده يعنى
third party
زى اباتشى كده بيشغل اكستنشن
ASP
او حتى اضافة للاباتشى؟
انا محتاجه ضرورى
لو عندك يا ريت تقوللى
اصل انا بينى و بين ما يكروسوفت النصابةدى طار
و مخى طار
مع انى متعلم حاجات كتير من عندها لكن برضه باكرهها
و مع ال بى اتش بى للنهاية
و تحيا الجافا و الاتش تى ام ال و اكس ام الى و تحيا نفق السويس
:)

عصفور المدينة said...

أخي ما علينا اسمح لي بعد اذنكم ار رين سريعين ولو فيها تهجم

أخي خالد أنا مهندس كمبيوتر 40 سنة وأحترم الحياة الزوجية :)
واعمل مدير تطوير في شركة برمجيات
يعني مدير مبرمجين
وعلى فكرة معرفو عني منذ تخرجي إني عدو ميكروسوفت ولكن البورصة تتكلم يا عزيزي
ثانيا لو حتستخدم إي إس بي يبقى 2005 ميكروسوفت عملت تسهيلات كثير فيها وهذه التسهيلات أغلبها ليس من قبيل التطوير للماضي بل جديد فبالتالي لو بدأت ب 2003 مثلا مش حيكون تطور طبيعي
وايضا موضوع التجربة والشغل مش محتاج سرفر هي بتحتوي على ويب سرفر بيشتغل وقت اللزوم

أخي ما علينا حاسس أني لم اوضح الفكرة التي طرحتها بخصوص الملتي لنجوال؟