היום קיבלתי דוא"ל, שכביכול נשלח מ-Facebook. רציתי להזהיר אתכם מפניו. הדוא"ל מכיל את התוכן הבא:
Dear user of facebook,
Because of the measures taken to provide safety to our clients, your password has been changed.
You can find your new password in attached document.
Thanks,
Your Facebook.
לדוא"ל מצורף קובץ zip המכיל קובץ exe בשם "Facebook_Password_4tf52.exe". קובץ exe בשביל שיחזור סיסמא? הממ… משהו מסריח פה. עוד מידע על פעולתו של הסוס הטרויאני הזה, תוכלו לקרוא כאן.
אוסיף עוד שורה וחצ על החשיבה הזהירה שצריכה להנחות את משתמש הדוא"ל הפשוט לפני שהוא מקליק פעמיים על קובץ שהולך למרר לו את החיים במשך שבוע (במקרה הטוב).
אם אין לכם חשבון Facebook (כמו שלי אין)… לא אוסיף עוד בנושא זה.
אל תאמינו ל"From" של הדוא"ל שקיבלתם, אלא כאשר התוכן ממוען ישירות אליכם, ואתם יודעים את זה. לרוב אנחנו באופן אוטומטי קוראים את התוכן ויודעים לסווג אותו כבטוח או כמסוכן. אל תתנו ל"מאת" כמו "Facebook" להטעות אתכם.
מי שמע על מערכת web 2 שמאפסת את הסיסמא שלך על דעת עצמה, וששולחת את הסיסמא בקובץ מצורף? יותר מידי מוזר, ומשתמש מחשב ממוצע צריך כבר לדעת לזהות את זה.
הכי הכי טוב – כל הסוסים הטרויאנים האלה, יוצאים מנקודת הנחה שמערכת ההפעלה שלי היא Windows. פתרון: לינוקס. הכי בטוח.
כל משתמש WordPress יודע – לא תמיד תוסף זקוק לתרגום לעברית. תוספים שהשימוש בהם פשוט מאוד, או תוספים שהשימוש שלהם אינו דורש כמעט טקסט – פשוט יכולים להשאר בשפת המקור, בתנאי שהיא, כמובן, אנגלית.
אך מה קורה כאשר השפה / המונחים מורכבים מדי למשתמש העברי הממוצע ב-Wordpress ? אז התרגום יכול להיות מאוד מבוקש.
ברשומה זאת נדבר על תרגום ב-Wordpress ועל תרגום תוספים בפרט.
I18n
הכותרת מרמזת על רעיון הבינאום (הפיכה לבינלאומי) והינה בעצם קיצור נחמד למילה Internationalization (שהיא i גדולה, 18 אותיות ואז n בסוף. חמוד, לא?). בקצרה, בינאום הינו שלב אחד לפני תרגום. כדי שאפשר יהיה לתרגם תוסף או אלמנט אחר ב-Wordpress, צריכה להמצא פונקציה שיודעת להבדיל בין קוד לטקסט שאפשר לתרגם אותו, ושתדע להיכן לגשת על מנת לשאוב את המחרוזות המתורגמות.
עכשיו התנצלות קטנה – אני לא מתכנן להקיף את כל מה שקשור לתחום הבינאום והתרגום ב-Wordpress. אני מנסה לתת כלים לתרגום, בלי התיאוריה. שלא תבינו לא נכון, היא מאוד חשובה להבנה נכונה של המערכת. אבל עשו את זה כבר טובים ממני (אמנם באנגלית, אבל לא הבטחתי לתרגם את זה (: ) - למעוניינים להרחיב – I18n for WordPress Developers. אתכם הסליחה.
אבל בכל זאת… קצת מושגים טכניים:
מחרוזת שאינה מוכנה לתרגום, נראית כך:
<code lang="php">echo "my wordpress plugin text";
</code>
על מנת לאפשר בעתיד תרגום של המחרוזת, יש לעטוף את המחרוזת בתוך אחת משתי פונקציות – _e() או __().
ההבדל ביניהן הוא שהראשונה מדפיסה את התוכן למסך (בעצם, תרגום ואז echo), והשנייה רק מתרגמת את המחרוזת. זה נראה הבדל קטן אבל עוד תגלו את השימושים לכל אחד מהם.
אותה מחרוזת שמוכנה לתרגום תיראה כך:
_e("my wordpress plugin text"(;
זוהי כל תורת הבנאום על רגל אחת, אבל בבקשה – אם אתם מגיעים לתוסף לא מוכן לתרגום (לא מבונאם), אל תעשו זאת רק על סמך מה שכתבתי כאן. קראו את כל המאמר על I18n באתר של WordPress, בקישור שלעיל. אנחנו מתמקדים כאן בתרגום ולא בבנאום.
שאלה – איך יודעים אם תוסף כבר מבונאם או לא?
תשובה א' – מחפשים קבצי pot, po ו-mo (עוד מעט ניתן הסבר עליהם, יש להם חשיבות)
תשובה ב' – במידה ואין, עדיין לא אומר שהוא לא מבונאם, פשוט אולי לא תרגמו אותו לשום שפה. פתחו קובץ php מרכזי בתוסף וחפשו מחרוזות שעטופות באחת משתי הפונקציות שהצגנו למעלה. אם יש כאלו, התוסף, ככל הנראה, מבונאם.
עוד כמה הגדרות לפני התרגום
קבצי po – קבצי ה-po הינם בעצם הקבצים המחזיקים את התרגום למחרוזות. כל קובץ מחזיק תרגום לשפה אחת, ואפשר לדעת לאיזו שפה, לפי השם. למשל myplugin-en_BR.po הינו תרגום לאנגלית בריטית, וmyplugin-he_IL.po הינו תרגום לעברית ישראלית. לאט לאט תכירו את השמות הרלוונטיים. קבצים אלו הם קבצים יחסית גדולים בנפח, אותם אפשר לראות בכל עורך טקסט.
קבצי mo - קבצי ה-mo הינם העתק של קבצי ה-po חוץ מעניין אחד קטן – קבצי ה-mo קטנים בהרבה בנפח, דבר שמקל על תעבורת המידע. מסיבה זו את קבצי הmo רק המכונה (מערכת התרגום) יודעת לראות. חשוב להבין שאין לזה ערך לערוך בעורך טקסט את קבצי ה-po ולשנות את התוכן, מכיוון שהם לא ישפיעו כך על קובץ ה-mo. יש רק דרך אחת לעשות זאת כמו שצריך (ואם תעקבו אחר המדריך שתיכף יתחיל, תדעו אותה גם אתם).
קבצי pot - קבצי pot הם בעצם קבצי po ריקים מתוכן מתורגם. עליהם נעשה כל תרגום חדש ולאחר מכן נשמר בתור קבצי mo ו-po חדשים.
Xgettext – תוכנה קטנה ליצירת קבצי pot מתוך קובץ php שבונאם.
1. מצאתי תוסף שזקוק לתרגום, ושכבר בונאם. איך גיליתי זאת? פתחתי את תקיית התוסף, וראיתי כי קיימים קבצי PO ו MO. היו כאלה אך רק בשפה האיטלקית.
תוסף בר-תרגום
2. התקנת xgettext (בubuntu 9.10 היא "באה לבד").
3. לפתוח טרמינל. להגיע לתקייה של התוסף, ולהקליד את הפקודה כמו שהיא מוסברת כאן. אפשר גם להעתיק את הפקודה מהתמונה של הטרמינל (שם היא ברורה יותר) התמונה מוכיחה שזה עובד, כיוון שהקובץ pot לא היה שם לפני התמונה. שימו לב.
ליצור קובץ pot
4. לפתוח את POedit ולטעון את קובץ הpot מהתקייה, דרך "קובץ" >> "קטלוג חדש מקובץ pot", להכניס את הפרטים המתאימים תחת הגדרות. הערה: בגדול, התעלמו מהטאבים "נתיבית", ו"מילות מפתח". הערה 2: ברוב התוספים אין צורך לגעת בצורות רבים, ועל כן לא אלאה אתכם בעניין. אם אתם לא התרגום הראשון לתוסף, בידקו מה כתוב תחת plural בקובץ ה-po של תרגום כלשהו.
פרטים בPOedit
5. לתרגם את המחרוזות משפת האם.
לתרגם את המחרוזות
6. לבדוק שב"עריכה">> "העדפות" >> תחת הטאב "עורך" – כפתור ה-checkbox ליד "הדר לקובץ mo בשמירה אוטומטית" מסומן ב-v.
7. לשמור את הקובץ, ולסגור את POedit. עתה תראו שהתוכנה יצרה את שני הקבצים (mo ו po) אך ללא המזהה של השפה הספציפית , תוכלו להוסיף את המזהה בעצמכם על ידי עריכת שם הקבצים.
שנה שם
זהו זה.
כמובן שיש איפה להסתבך, ויש עוד דברים כמו text-domain ואיך מעדכנים תרגום בלי לתרגם הכל מההתחלה, שלא דיברנו עליהם. אבל על הבסיס דיברנו.
כמובן שאם תהיה התעניינות, זה ידרבן אותי לכתוב בנושא יותר.
זה עבד טוב, עד שבגרסה 0.35 המעקף הפסיק לעבוד, כנראה בגלל שינויים משמעותיים במשתנים הגלובליים.
עכשיו הייתי צריך לעשות הכל מההתחלה, והחלטתי שהפעם אני אשתמש רק בשני קבצי CSS – לRTL ול-LTR.
קובץ ה-CSS הראשי (style.css) יהיה ה-LTR, וקובץ CSS שני יהיה ל-RTL (על אף שהייתי צריך RTL לשתיים השפות וLTR רק לאחת).
הבעיה הראשונה שנתקלתי בה נוצרה מכיוון שהWP הותקן בעברית, מה שגרם לwp_head לדרוש את הקובץ rtl.css בכל הפעלה. את האמת, לא ידעתי כל-כך איך לגשת ולהתנות את הוספת rtl.css ב-wp-head לפי השפות המשתנות של Transposh. אז החלטתי להתעלם ממנו (למחוק את הקובץ בכלל), וליצור קובץ חדש style-rtl.css. אני יודע שזה לא מאוד אלגנטי, אבל זה עושה את העבודה.
עכשיו רק הייתי צריך לגרום ל-head של התבנית הנבחרת להתנות את הופעת קובץ ה-style-rtl.css כאשר המשתמש מחליף את ה-Transposh לשפה שדורשת RTL (כמו עברית, או ערבית).
במערך גלובאלי שיצרו ברכיב, שמורות כל השפות שזקוקות לשינוי כיווניות (rtl-languages), ובמערך אחר (my_transposh_plugin) שמורה השפה שאיתה הרכיב עובד ברגע זה (target_language).
ניצור תנאי שאומר: אם השפה בה הרכיב עובד עתה מתאימה לאחת מהשפות במערך השפות שדורשות התאמת rtl, עשה משהו.
במקרה הזה, הפעולה היא להדפיס למסך את קישור טעינת ה-style-rtl.css, ובקובץ זה נמצאות ההגדרות החדשות שדורסות את ההגדרות הישנות של style.css על מנת להתאים לשפת ה-RTL.
החברים ב-bbPress החליטו שהם בונים פורום תואם WordPress אבל שאינו מותקן כתוסף, אלא מותקן בנפרד. בהתחשב בגודל מערכת ה-bbPress אפשר שזו החלטה נכונה. עם זאת, יש צורך להשקיע מחשבה בהטמעה של הפורום במערכת ה-WP, בעיקר עבור מנהלי אתר הדורשים ממשק ידידותי למשתמש.
המאמר יתחיל בהתקנת bbPress והתאמתו לעברית, ולאחר מכן יציג מספר תוספים שבעזרתם ההטמעה של הפורום באתר תגיע להשלמה.
התקנת bbPress:
ההתקנה היא פשוטה יחסית, אך עם זאת יש לשים לב לכמה דברים על מנת שה-cookie-יות של הפורום ושל מערכת ה-WordPress יתמזגו ויהיו ל-cookie-יה אחת.
2. יש להעלתו את bbPress (העדפה אישית בספרייה forum בתוך הספרייה הראשית של ה-WP) עם כל הקודים שמועתקים גם לwp-config של הwp.
3. לגשת לספרייה של הפורום (התקייה /forum, ב-URL הראשי של האתר שלכם), ולעקוב אחרי ההוראות. הערה: כדאי לבחור התקנה של הפורום על אותו מסד נתונים כמו של ה-WP, אין באמת סיבה לבחור אחרת.
4. במהלך ההתקנה, תתבקשו להזין שם וסיסמא של מסד נתונים, וכו' ובין השאר גם מספר קודים כמו auth, ו-log-in. את הקודים ניתן לייצר כאן. תתבקשו גם להוסיף קודים מהגדרה קיימת של מערכת ה-WP, שנקראים Salt. אותם אפשר למצוא ב-../wp-admin/options.php תחת ה-URL הראשי של האתר שלכם. את ה-Salt של secure auth לא בטוח תמצאו, וזה בסדר. השאירו אותו ריק. הערה: את כל הקודים שאתם מזינים יש להעתיק גם לקובץ wp-config של מערכת ה-WP שלכם (נמצא בספרייה הראשית). פשוט חפשו את המקום המתאים ביותר (יש אחד כזה שמחכה בדיוק לקודים הללו שלכם).
5. עתה נדאג לעברית של הפורום. מאתר התוסף (הקישור לעיל), יש להוריד שלושה קבצים:
he_IL.php, אותו מעלים לספרייה bb-include/languages בספרייה הראשית של הפורום. אם הספרייה languages לא קיימת, יש ליצור אותה.
he_IL.po ו-he_IL.mo, אותם מעלים לספרייה my-languages שבספרייה הראשית של הפורום. אם הספרייה my-languages לא קיימת, יש ליצור אותה.
שינוי אחרון שיש לעשות על מנת שהתרגום יקלט הוא לדאוג שהשורה הזאת מופיעה כך בקובץ class.bb-locale.php שבספרייה bb-include שבספרייה הראשית של הפורום:
var $text_direction = 'rtl';
עתה הפורום אמור להציג הכל בעברית, בכיווניות של ימין לשמאל. אם התבלגנתם, השאירו כאן תגובה, ואנסה לעזור.
6. חפשו את ההגדרות של bbPress integration. התוסף יבקש מכם את כתובת ההתקנה של האתר (גישה ישירה לשרת), את הכתובת הדומיין של האתר, וברירה בין WP לבין WPmu (אם אינך יודע מה לבחור, כנראה שאתה צריך לבחור WP). לאחר שתשמור את העדפות, התוסף ייצר קוד שגם אותו תצטרך להוסיף לwp-config.
7. הפעלת New bbPress Admin היא ממש פשוטה. פשוט להזין לשדה היחיד את הקישור הישיר לממשק הניהול של הפורום, שזה בעצם הקישור הישיר בצירוף הספרייה האחרונה /bb-admin.
8. הפעלת Embed-BBpress 0.8 היא דומה להפעלת New bbPress Admin – לגשת ללשונית "Embed-BBpress" שתחת התפריט "תוספים". במסך העריכה יש להזין את ה-URL הישיר לאתר, ואת רוחב וגובה חלון ההטמעה שאתם מעוניינים בו.
9. עכשיו יש אפשרות שתבנית הפורום תהיה רחבה מדי לחלון שבחרתם. על מנת להתמודד עם זה בקלות, בצעו את השלבים הבאים:
בממשק הניהול של הפורום, תחת "מראה" יש לבחור את תבנית ברירת המחדל kakumei.
להוריד את הקבצים הללו מכאן, ו"לדרוס" איתם את הקבצים בתקיית kakumei שב-bb-templates בקבצי הפורום. העיצוב החדש של הפורום, יתאים לכל רוחב חלון שמעל 450px, ואם זה לא מתאים לאתר שלכם עדיין, אז התבנית שבחרתם היא מאוד מוזרה.
עכשיו אפשר להוריד את קבצי ה-CSS שהעלתם הרגע, ולערוך אותם כרצונכם: צבעים, הדגשות וכו'. עיצוב CSS. לא נתעכב על זה.
9. עתה, צרו עמוד או רשומה חדשה, והטמיעו בה את הקוד [Embed-BBpress]. הפורום פשוט יופיע.
אני שונא WYAIWYG-ים. באמת שונא אותם. הם תמיד מחרבשים את הטקסט וזה אף פעם לא יוצא כמו שאתה רוצה.
אבל מה לעשות שמשתמשי הקצה לא יודעים לכתוב HTML ושהם מצפים שהכל יעבוד כמו בWord. העניין הוא שהם פשוט לא רואים, אבל גם בWord הכל בבלאגן אטומי. נסו לקחת קטע מWord ולהעתיק אותו לעורך וויזואלי ב-WP. תעבירו את העורך למצב HTML ותראו את הבלאגן ש-Word עושה.
אין ברירה. חייבים להצליח לעבוד איתם, עם ה-WYSIWYG-ים.
בעיה מעצבנת לאללה, שבדרך כלל לא משפיעה על הטקסט כשנשמר (וזה מפתיע באמת…) אבל בזמן העריכה זה מאוד מעצבן, וסבלנותם של משתמשי הקצה עשויה להגמר עוד לפני שיפרסמו את הטקסט הראשון שלהם, ויראו שבסוף זה לא נורא – חלון העריכה מיושר לשמאל (מכוון ללעז), וכמובן שאם לוחצים על ישור לימין, אז עדיין הסמן נמצא בתחילת השורה ולא במקום הראוי לו, והניקוד מופיע גם הוא בתחילת השורה.
הפתרון שעבד לי, בגירסת tinyMCE 3/2.4.1 (לקח לי מלא זמן למצוא את הגרסה, ואני אפילו לא בטוח שזה מעודכן כי זה מאיזו הודעה מהקרביים של קובץ ה-js… אין מה לעשות, התיעוד שלהם חרא), המותקנת לצרכי WordPress, הוא פשוט יחסית:
1. למצוא את קובץ ה-css, בספרייה wp-includes/js/tinymce/themes/advanced/skins/wp_theme, ולהוסיף לאלמנט Body mceContent ולאלמנט #tinyMCE (אם הוא לא קיים, אז ליצור אותו), את התכונה:
text-align:right;
2. היכן שהתוכנה קוראת לtinyMCE היא עושה זאת באמצעות המערך JavaScript שנקרא tinyMCE.init. למערך זה צריך להוסיף את הערך:
לקח לי יומיים בערך להפיק קובץ po ריק (שזה בעצם קובץ pot) מתוכנת שורת הפקודה gettext. יש הממממון חומר על זה באינטרנט, ורק 5% אחוזים באמת נותנים דוגמא ממשית (כי זה אמור כאילו להיות פשוט), אבל מה? ה-syntax הוא בלתי ניתן להבנה מהמדריך (רק בניסוי וטעיה) וההערות אודות הטעויות שהתוכנה מחזירה הן פשוט לא קשורות. כל חלק שהתוכנה לא מבינה היא מחזירה:
xgettext: error while opening "blablabla" for reading: No such file or directory
אז אולי יום אחד גם אפרסם מדריך מסודר וארוך על התוכנה הזאת. אבל בינתיים אני מציג כאן את ה-syntax שעבד לי בסופו של דבר, תחת מערכת אובונטו 8.10, עם gettext 0.17.
בטרמינל, הגעתי לספרייה הרלוונטית שבו נמצא הקובץ, ואז הקלדתי:
*שימו לב: לפני כל keyword יש שני מקפים, ולא אחד. מסיבה כלשהי שאינה מובנת לי, העורך הוויזואלי של WP הופך את שני המקפים למקף אחד. חשוב, כיוון שאחרת הפקודה לא תצליח.
זה עבד לי. אם גם לכם יש בעיות, ספרו לי כאן, ואנסה לעזור.
רוצים שכשידלק המחשב, תוכנה מסויימת תופעל אוטומטית? זה מאוד מאוד פשוט.
הולכים למערכת >> העדפות >> תצורת ההפעלה, ובלשונית (Tab) "תוכניות ההפעלה" לוחצים על "הוסף", ומקלידים את הפקודה שתפתח את התוכנה הרצויה (אם אתם לא בטוחים, נסו לפתוח מסוף, ולהקליד את שם התוכנה, 80% סיכוי שזאת היא הפקודה הבסיסית לפתוח את התוכנה).
זהו זה. פשוט, לא?
תוכניות ההפעלה
נבדק תחת אובונטו 8.10 (Intrepid Ibex), אבל אין ספק שזה לא שונה מאוד בכל ההפצות החדשות.
ראשית, כיוון שאינני איש PHP, הפתרונות שאציע לענייני תוספים ושאר ירקות ה-PHP כנראה לא יהיו מאוד טובים מבחינת איכות קוד. עם זאת, לדעתי אני מפצה על זה ביצירתיות, וכנראה שעם מעט ידע ב-PHP ו-mySQL, וניסוי וטעיה, אפשר לפצח דברים קטנים בסופו של דבר.
שנית, מאוד אשמח אם תצליחו להעזר במה כתוב כאן, אך השימוש הוא על אחריותכם בלבד, כמובן.
שלישית, יש לשים לב לגירסאות ולשמות אלמנטים שאני התמודדתי איתם, וזאת על מנת שלא תעבדו על הפתרון שעות ובסוף תגלו שהגירסה שלכם יותר עדכנית ולכן אותה שורת קוד לא נמצאת בדיוק במקום שציינתי. שימו לב – הרבה פעמים פונקציות בסיסיות של אלמנטים נשארות פחות או יותר אותו דבר, כך שגם אם האלמנטים שלכם שונים, עדיין אפשר להשתמש ברעיון הכללי, ולהתאים אותו למה שיש לכם.
אז גירסאות, בבקשה:
WordPress-he-IL 2.8.x, Transposh 0.3.3 (רכיב התרגום), תבנית deault של קובריק עם קובץ ה-rtl.css שמתאים לעברית.
המשימה שלי הייתה למצוא תוסף תרגום טוב, שידע להחליף יפה בין עברית, ערבית ואנגלית (שלוש שפות חשובות לאתרים בישראל). השאלה היא מה זה "יפה"?
ב"יפה" הכוונה היא שאם אני מחליף את השפה באתר מעברית לאנגלית ולערבית, וחזרה, משהו במראה גם צריך להשתנות. עברית היא שפה שכותבים בה מימין לשמאל (Right To Left), וכך גם ערבית, בעוד שאנגלית היא שפה שכותבים בה משמאל לימין (Left To Right).
בכל תבנית (תבנית עיצוב – theme) בוורדפרס, קיים קובץ סגנון. אם יצרו את התבנית במיוחד לעברית, אז ככל הנראה העיצוב העברי מוטמע בתוך הקובץ הראשי (style.css), אך אם התבנית היא מתורגמת מאנגלית (מה שברוב הפעמים נכון), בנוסף לקובץ הראשי מצרף המתרגם קובץ סגנון נוסף (rtl.css), שבו ישנן התאמות לעברית (ולכל שפת RTL אחרת) שדורסות את העיצוב מהקובץ הראשי.
Transposh 0.33 – תוסף תרגום
לא נאריך בהכרות עם תוסף זה. רק נאמר שההתקנה פשוטה (חוץ מהשדרוג שאנחנו עושים כאן), והייחודיות המופלאה שלו היא בממשק העבודה הנקי והפשוט. אך מה? התוסף מתוכנן כך שיוסיף את קובץ הסגנון rtl.css כשצריך אותו. בדקתי. זה לא קרה. זה לא עבד גם אחרי ששלחתי דוא"ל למפתח התוסף וסיפרתי לו על הבעיה. הוא שלח לי קטע קוד שהיה אמור לפתור את זה. לא עבד.
זאת ועוד, אני רציתי שהרכיב יחליף את קבצי הסגנון לכל שפה, כדי שאוכל לפתח עיצובים ספצייפים לכל שפה. דוגמא חשובה – בהרבה תבניות תמונות שונות המופיעות בתבנית מוגדרות בקובץ הסגנון. אם אני מעוניין למשל ליצור כותרת אתר מסוגננת, ועושה זאת באמצעות תמונה עם טקסט בתוכה, ולא כטקסט אינטרנט (מצב די נפוץ), הארכיטקטורה של התוסף מגבילה אותי מלהחליף את הכותרת הזו בין עברית לערבית, למשל, כי הן שתיהן שפות RTL.
אז החלטתי לעשות זאת בעצמי.
תכף אספר לכם איך, אך לפני כן, נתייחס "לסוס המנצח" שלנו – המשתנה lang$.
ב-Transposh הגדירו משתנה גלובאלי בשם lang$ שבעצם שומר את קוד השפה הנוכחית של האתר (en – לאנגלית, he – לעברית, וar- לערבית – במקרה שלנו, כמובן). קטונתי מלהרחיב על סוגי משתנים ב-PHP – יש מספיק אתרים שכותבים על זה. רק אומר שלצורך העניין, עצם קיומו של משתנה גלובלי זה הוא שאנו יכולים למשוך את המידע על השפה הנוכחית בכל מקום (כמעט) באתר. בדרך-כלל הטמעה של הקוד הבא:
תניב את הקוד המתאים (ראו פסקה קודמת) שתואמת לשפה הנוכחית. אז מה עושים עם זה?
לקרוא את קובץ הסגנון הנכון
לצורך ההבדלה בין השפות, יצרתי שלושה קבצי סגנון (CSS) שונים, לעברית (stylehe.css), לאנגלית (styleen.css) ולערבית (stylear.css). כך, בעתיד, יהיה ניתן לעשות שינויים ספציפיים לכל שפה (אם נאלץ לעשות זאת) ללא דאגה שהשינויים ישפיעו על קבצי הסגנון של שתי השפות האחרות. החיסרון הוא שאם צריך להוסיף משהו לקובץ הסגנון, צריך להעתיק אותו שלוש פעמים. אני חושב שהיתרונות עולים כאן על החסרונות.
עתה צריך לגרום לכך שכל פעם ששפה אחרת נבחרת, קובץ הסגנון משתנה למתאים לה.
בהתחלה חשבתי שאצטרך לכתוב פונקציה שתקרא את ה-URL הנוכחי, תוציא מתוכו בתמרון מחרוזת את קוד השפה (נניח, "en" לאנגלית), ואז תלביש את קוד השפה בטעינה של קובץ הסגנון. נשמע פשוט, אבל מסורבל.
אז חיפשתי קצת ומצאתי את המשתנה הגלובלי lang$, שכבר דיברנו עליו, וכך פתרון הרבה יותר אלגנטי נקרה בדרכנו. בקובץ header.php של התבנית, השורה שמציבה את קובץ הסגנון הנכון במקום הנכון היא:
פקודת ה-PHP מציבה את ספריית קבצי הסגנון בתוך תכונת הקישור (href=…) של תגית link זו. הטריק הוא פשוט, להשתמש במשתנה הגלובלי lang$, כך שכאשר הגולש יבחר את השפה העברית למשל (קוד השפה העברית הוא he), הקישור יפנה לקובץ הסגנון המתאים (קובץ הסגנון הוא stylehe.css). להלן הפתרון הפשוט עד מאוד:
מכיוון שקוד השפה העברית הוא he, ההשתלה החדשה תניב את הקישור הבא:
אם כך, הצלחנו לגרום לכך שבכל פעם שתבחר שפה אחרת, קובץ הסגנון ישתנה לקובץ המתאים לאותה שפה.
עתה הייתי צריך לגרום למערכת לא להציג את קובץ הסגנון rtl.css כאשר השפה הנבחרת היא אנגלית (כי היא היחידה ב-LTR).
דרך אחת, קצת מכוערת לטעמי, לעשות זאת היא להעתיק את תוכן הקובץ rtl.css לתוך הסגנונות של העברית והערבית, ופשוט למחוק את התנאי שמטמיע קובץ זה בתגית ה-head של האתר מראש. זאת אומרת לדאוג לכך שהמערכת לא תתייחס לקובץ זה בכלל.
אפשר לעשות את זה כך, אבל זה חבל. אחרי כמה פעמים שתנסו לשנות תכונה כלשהי בסגנון של כל אתרי ה-RTL, תבינו למה. את אותה חתיכת קוד, העתק מדויק לחלוטין, צריך להדביק בקובץ הסגנון של כל שפה. באתר עם המון תרגומים התנהלות עם כל-כך הרבה קבצי סגנון הופכת לעסק מסובך, ועל כן החלטתי להשאיר את היכולת לטעון את קובץ הסגנון rtl.css אך לדאוג שכאשר השפה הנבחרת היא שפה לא RTL-ית (נניח אנגלית, במקרה שלנו) המערכת פשוט לא תוסיף את קובץ הסגנון ל-RTL. לשם כך, השתמשנו עוד פעם במשתנה הגלובלי שלנו.
עריכת Theme.php
בקובץ theme.php מופיעות הרבה מן הפונקציות שמשחקות תפקיד בתבנית האתר ובקבצי העיצוב.
את הקובץ אפשר למצוא בתקייה wp-include שבספרייה הראשית.
בשורה 98 אפשר למצוא את התנאי הבא:
תנאי זה אחראי לבדוק מה הכיוון הטקסט של שפת ברירת המחדל באתר, ולבדוק האם קיים קובץ סגנון מתאים, לצורך התאמת המראה של האתר. הוספתי לתנאי בדיקה שמשווה את ערכו של lang לשפות שאני רוצה שבהן קובץ הסגנון rtl.css לא יופיע (במקרה שלנו, אנגלית בלבד).
כעת, כדי שהתנאי "יתרחש", על ערכו של lang$ להיות שונה מ"en". כך המערכת לא תטמיע את rtl.css בעת שהשפה האנגלית נבחרה, וכן העיצוב של השפה האנגלית לא ידרס ויישאר LTR.
סיכום
עשינו זאת. אולי זאת לא הדרך המתוחכמת ביותר שאפשר לעשות את זה בה, אבל זה בהחלט עובד.
תהנו.
במקומות רבים בג'ומלה — וגם במנועים אחרים — נתקלים בבעיה הזו, בעיקר בדפדפן פיירפוקס; רואים את זה כאשר מנסים להשתמש בקידוד UTF-8 ובמקביל מנסים לקצר מחרוזות, למשל: כדי להציג תקציר של תוצאות חיפוש.
ממה נגרמת הבעיה?
הבעיה נגרמת מכיוון שתווי UTF-8 הם תווים שכל אחד מהם תופס בזיכרון יותר מבייט אחד. כלומר, במחרוזת UTF-8 קונבנציונלית, כל אות בעברית תתפוס 2 מקומות; הפונקציה שמנסה לקצר את המחרוזת הזו (לרוב: פונקציית ה-PHP שנקראת substr, או משהו דומה), מתעלמת מכך (אין לה אפשרות לדעת), ומקצרת את המחרוזת עד ל"אמצע" של אות, ובכך משאירה קוד UTF שאינו שלם, ומופיע סימן השאלה.
לכאורה, היה ניתן לתקן זאת בפשטות באופן הבא:
היינו בונים פונקציה שמקצרת "רק בזוגות". ובכן — אין בזה שום פתרון, מהסיבה הפשוטה הבאה: עם קבלת ה-UTF-8 כתקן, התעקשו דוברי האנגלית כי אין סיבה ששפתם — המדוברת ביותר בעולם — תתפוס פי 2 מקום בזכרון "סתם כך", ועל-כן התווים באנגלית, גם במחרוזות UTF-8, תופסים רק מקום אחד. כמו-כן, מספרים ותווים "בינלאומיים" נוספים תופסים גם הם, לרוב, רק מקום אחד. אז הבעיה מחריפה: המחרוזת, שמבחינתנו בנויה מרצף סביר של אותיות ומספרים, בעצם בנויה מסדרה של מקומות בזכרון, שחלקם מביעים אות או מספר, וחלקם מביעים רק "חצי אות".
אז מה עושים?
מאחר וכבר ממילא נתקלתי בבעיות הללו ופתרתי אותן, אני אנסח בצורה מסודרת — בשביל לחסוך מאמץ משאר הנתקלים בבעיה — כיצד פותרים את הבעיה הזו בכל "מקום" בג'ומלה.
מנוע החיפוש של ג'ומלה
המקום הראשון שנתקלים בו בבעיה זו, לרוב, הוא ג'ומלה. הרעיון הוא כללי מאד, וניתן להכליל אותו בנקל למקרים נוספים בג'ומלה או בכלל.
ראשית, שמרו גיבוי של כל קובץ שאתם עובדים איתו. זה חשוב מאד, כי ג'ומלה הוא מנוע מאד מסורבל שמסתמך על המון פאצ'ים חיצוניים, ולעתים אין לדעת מה שינוי — הכי תמים שבעולם — יכול לעשות. שמרו גיבוי.
פתחו את הקובץ joomla.php שנמצא בספריה includes. הקובץ הוא קובץ ענק שמכיל המוני פונקציות של ג'ומלה. חפשו בתוכו את הפונקציה mosSmartSubstr. למרות שמה, הפונקציה אינה כל-כך חכמה, אך אל דאגה – אנחנו "נעלים" אותה, ונחליף אותה בפונקציה חכמה יותר.
ערכו את הפונקציה עצמה כך שתיראה, בסופו של דבר, כך:
שימו לב — מה שעשינו, בעצם, זה "להעלים" את כל תוכן הפונקציה, ובמקום זה להשאיר שורה אחת בלבד שקוראת לפונקציה אחרת. עלינו להוסיף את הפונקציה הזו, ונעשה זאת מיד לאחר הסוגריים של הפונקציה שערכנו זה עתה:
שימו לב: מה שהפונקציה הזו עושה הוא מאד מועיל: היא מקבלת את המחרוזת באופן רגיל לגמרי, כמו הפונקציה המקורית, אך לאחר מכן היא מפצלת אותה למילים, מעיפה את המילה האחרונה (שהיא המילה הבעייתית — זו שאולי קטועה בצורה לא יפה), מחברת את הכל יחד, ומייצרת מחרוזת חדשה, אותה היא מחזירה. כך הרווחנו שני דברים במכה: ראשית, לא יהיה סימן שאלה; שנית, לא יהיו מילים חצויות, ונקבל מחרוזת שיש בה רק מילים שלמות.
לאחר העדכון שעשיתם, שמרו את הקובץ והעלו אותו לשרת (לא לשכוח — לפני-כן — גיבוי!). הכל אמור לעבוד כמו שצריך עכשיו.
הערה: אם רוב המחרוזת שלכם היא בעברית, אתם עלולים לקבל (לא בגלל הפונקציה החדשה) מחרוזות שהן טיפה קצרות יותר ממה שרציתם. אין בעיה: שחקו עם המשתנה $length (פה, או במקום שקורא לפונקציה), וזה יהיה בסדר!
ב-SMF Bridge לג'ומלה
כן, גם שם אנו נתקלים בסימן השאלה השחור. באופן דומה לפתרון הקודם, גבו קודם כל קובץ שאתם מתכוונים לשנות. ג'ומלה פועל לעתים באופן לא צפוי. בספריה שבה התקנתם את הפורום עצמו (לא את הקומפוננטה של הגשר), יש תת-ספריה בשם Sources. בתוך הספריה הזו תמצאו קובץ בשם Subs.php; שוב, קובץ ענק. פתחו אותו, ובסביבות שורה 911 (אל תתפסו אותי על השורה, יש המון גרסאות…), אמורה להופיע השורה הבאה:
הפונקציה פועלת בדומה לפעולתה של הפונקציה אותה יצרנו קודם לכן: היא מפרידה את המחרוזת למילים, מעיפה את המילה האחרונה, ומחזירה מחרוזת המורכבת מהמילים שלפניה.
שימו לב, כפי שהערתי קודם לכן, ייתכן בהחלט — ואפילו סיכוי רב — שהמחרוזות אותם תקבלו בחזרה יהיו קצרות מדי (ולא בגלל השינוי). הפתרון לכך הוא קצת יותר מורכב מאשר במנוע החיפוש של ג'ומלה, והריני מפרטו כאן:
יש לעבור בכל אחד מן הקבצים הבאים, בכל אחת מן השורות המפורטות, ולהכפיל את המספר שרשום שם בתור האורך — דהיינו, בכל מקום שרשום 24 יש לרשום 48, אם רשום 25 יש לרשום 50 וכו'. המקומות הם:
Sources/Recent.php, lines 74, 130
Sources/BoardIndex.php, line 220
Sources/MessageIndex.php, lines 184, 268
Themes/default/MessageIndex.template.php, line 769
SSI.php, lines 289, 391
עד כאן; שמרו את כל הקבצים והעלו אותם לשרת. זה אמור לעבוד טוב כעת.
שוב ב-SMF: הפעם, ב-Recent Topics
גם במודול הנלווה Recent Topics אנו נתקלים בבעיה דומה. נבנה – בתוך המודול – פונקציה שעושה משהו דומה למה שראינו בבעיות הקודמות. לאחר שאתם מגבים כל קובץ שאתם מתכוונים לערוך, כמובן, ערכו את הקובץ של המודול, הקובץ בשם mod_smf_recenttopics.php (בספריה modules).
בתחילת הקובץ, ממש לאחר כל ה"הודעות" (בסביבות שורה 80), הוסיפו את הפונקציה הבאה:
function utfSubstr( $subject, $start, $len ) {
if (strlen($subject) <= $len)
return $subject;
זה יקרא לפונקציה שבנינו. כמו כן, שימו לב שהשתמשנו פה בפונקציה שמודדת את אורך המחרוזת לפי UTF-8 (כן, PHP יודע לעשות זאת!), אך הכפלנו את האורך של המחרוזת שאנחנו רוצים בסופו של דבר. נעשה דבר דומה שוב; בסביבות שורות 550-570, אמורה להופיע שורת הפלט, שנראית בערך כך:
שימו לב שביצענו הכפלה קטנה בסוף... שוב, בשביל לשמור על אורך מחרוזות הגיוני. שמרו, העלו את הקבצים, והכל אמור לעבוד היטב כעת.
בממבלוג
גם מנוע הבלוגים החביב יוצר את הבעיה של סימני השאלה השחורים, אך הוא עושה זאת מסיבה אחרת לגמרי; הסיבה היא פונקציה -- שאמורה להיות מועילה -- בשם safeStrip -- לא מזהה תו המקובל ע"י עורכי WYSIWYG שונים במקום "רווח" במקרים שבהם פסקה היא ריקה (או במקרים אחרים). התו מקודד באופן הבא: (ראשי תיבות: non-breaking space) -- והפונקציה הורסת אותו, וכך נוצר סימן השאלה החביב.
הפונקציה safeStrip נועדה -- במקור -- להבטיח שבתקצירים לבלוגים לא יהיו תגי HTML. אישית, איני מוצא סיבה לכך (מאחר ואת התגים הנ"ל ממילא רואים בדפי הבלוג הרגילים, שמשתמשים במנוע content של ג'ומלה להצגתם); כך הם נראים, בין היתר, ללא מעברי שורה. ולכן, הפתרון שאני מציע לבעיה זו הוא פשוט -- אנו נבטל את הקריאה ל-safeStrip, באופן הבא:
לאחר גיבוי מלא של הקבצים הקשורים, פתחו לעריכה את הקובץ showblogs.php שנמצא בתוך התיקייה הרגילה של הקומפוננטה. בסביבות שורה 459 נמצאת הפונקציה checkLength. כמה שורות לפני סוף הפונקציה, מופיעה השורה הבאה:
$text = safeStrip( $text );
סמנו שורה זו כ"הערה", באופן הבא:
// $text = safeStrip( $text );
כמו-כן, רצוי באותו הקובץ, בראשית הפונקציה decodeEntities, לסמן את השורה הבאה:
$string = html_entity_decode ($string, $opt);
כהערה גם-כן:
// $string = html_entity_decode ($string, $opt);
ובזה נגמר הסיפור.
שימו לב, גם, שתקצירי הבלוג ייראו עכשיו בהחלט טוב יותר.
יש מקום נוסף בממבלוג שיכול להוות בעיה: בדף שמציג באופן מרוכז תקצירים של בלוגים רבים. במקרה זה, הבעיה נמצאת בקובץ showblogs.php, בפונקציה checkLength - שוב המחבר מנסה להשתמש בפונקציה substr. כרגיל, נוסיף בתחילת הקובץ (בערך בשורה 14) את הפונקציה החדשה שבנינו:
function utfSubstr( $subject, $start, $len ) {
if (strlen($subject) <= $len)
return $subject;
שימו לב להכפלה הקטנה שעשינו! זה, כאמור, מכיוון שהאותיות בעברית "ארוכות יותר".
במנוע המתכונים Ricettario
כן, לא תאמינו – סימן השאלה הארור חודר לנו אפילו לאוכל. במנוע המתכונים Ricettario, אנו נתקלים בסימן השאלה השחור בתקצירים השונים של המזונות כאשר אנחנו באינדקס של קטגוריה.
איך פותרים? זוכרים את הפונקציה שהגדרנו, utfSubstr? ובכן, לשם הנוחות, נכתוב אותה גם פה, מחדש, אבל הפעם ניזהר שאנחנו לא מגדירים אותה פעם אחת יותר מדי: (הרגל טוב באופן כללי)
if (!function_exists("utfSubstr")) {
function utfSubstr( $subject, $start, $len ) {
if (strlen($subject) <= $len)
return $subject;
את הפונקציה הזו נרשום ממש בתחילת הקובץ common.php, ממש לאחר כל ההערות (למשל, בשורה 11). לאחר מכן, אנחנו רוצים לעדכן את המקום שמקצר את הטקסט. הפונקציה שדואגת לכך היא הפונקציה mc_get_article_title הנמצאת עתה בסביבות שורה 219.
לאחר העדכון, הפונקציה אמורה להיראות כך:
function mc_get_article_title($larticleid) {
$add_txt="";
$mc_rows=mc_SelQuery("Select title, id from #__content where id=$larticleid");
if ($mc_rows) {
$mc_i = 0;
foreach($mc_rows as $mc_row) { $ART[$mc_i] = $mc_row->title; }
/* if (strlen($ART[$mc_i]) < 35) { $add_txt = ""; }
if (strlen($ART[$mc_i]) > 35) { $add_txt = "..."; }
$art_txt = substr($ART[$mc_i], 0, 35) . $add_txt; */
$art_txt = utfSubstr($ART[$mc_i], 0, 70);
return $art_txt;
}
}
וזה הכל!
במנוע הקישורים com_weblinks
לפעמים הבעיה היא -- בעצם -- הרבה יותר פשוטה משנראה במבט ראשון... במנוע com_weblinks, למשל, בעיית סימן השאלה השחור נובעת לרוב בגלל שבמסד הנתונים עצמו השדה הרלוונטי מוגדר כקצר מדי.
הפתרון פשוט: נכנסים למסד הנתונים, לטבלה weblinks (או jos_weblinks, או איך שזה לא יהיה אצלכם), ומשנים את השדה description כך שיהיה באורך 500 תווים במקום 250, ו... זה אמור להספיק!
סיכום
הכתוב לעיל מסביר באופן מפורט למדי כיצד לפתור את הבעיה בכל אחד מן המקרים, אך יותר מכך – ניסיתי, כאן, להסביר באופן עקרוני ממה הבעיה נובעת, וכך לספק לכם כלי לנסות לפתור בעיות דומות (ויש אינסוף כאלה) ע"י הבנת הבעיה ויצירת פתרון משלכם.
אם בכ"ז נתקלתם בבעיית קידוד מסוג זה, ואינכם מצליחים להתמודד איתה, כתבו לי (דרך המייל באתר), וננסה לפתור אותה יחד. אם פתרתם אותה, שלחו לכאן את הפתרון, ותנו לכולם להרוויח מכך!
אני מבטיח לעדכן את הדף הזה במקרים נוספים, אם יצוצו.
איך פותרים את בעיית הקידוד, או: מה עושים עם ה- � (סימן שאלה על רקע שחור) המעצבן?
5 בדצמבר, 2008במקומות רבים בג'ומלה — וגם במנועים אחרים — נתקלים בבעיה הזו, בעיקר בדפדפן פיירפוקס; רואים את זה כאשר מנסים להשתמש בקידוד UTF-8 ובמקביל מנסים לקצר מחרוזות, למשל: כדי להציג תקציר של תוצאות חיפוש.
ממה נגרמת הבעיה?
הבעיה נגרמת מכיוון שתווי UTF-8 הם תווים שכל אחד מהם תופס בזיכרון יותר מבייט אחד. כלומר, במחרוזת UTF-8 קונבנציונלית, כל אות בעברית תתפוס 2 מקומות; הפונקציה שמנסה לקצר את המחרוזת הזו (לרוב: פונקציית ה-PHP שנקראת substr, או משהו דומה), מתעלמת מכך (אין לה אפשרות לדעת), ומקצרת את המחרוזת עד ל"אמצע" של אות, ובכך משאירה קוד UTF שאינו שלם, ומופיע סימן השאלה.
לכאורה, היה ניתן לתקן זאת בפשטות באופן הבא:
היינו בונים פונקציה שמקצרת "רק בזוגות". ובכן — אין בזה שום פתרון, מהסיבה הפשוטה הבאה: עם קבלת ה-UTF-8 כתקן, התעקשו דוברי האנגלית כי אין סיבה ששפתם — המדוברת ביותר בעולם — תתפוס פי 2 מקום בזכרון "סתם כך", ועל-כן התווים באנגלית, גם במחרוזות UTF-8, תופסים רק מקום אחד. כמו-כן, מספרים ותווים "בינלאומיים" נוספים תופסים גם הם, לרוב, רק מקום אחד. אז הבעיה מחריפה: המחרוזת, שמבחינתנו בנויה מרצף סביר של אותיות ומספרים, בעצם בנויה מסדרה של מקומות בזכרון, שחלקם מביעים אות או מספר, וחלקם מביעים רק "חצי אות".
אז מה עושים?
מאחר וכבר ממילא נתקלתי בבעיות הללו ופתרתי אותן, אני אנסח בצורה מסודרת — בשביל לחסוך מאמץ משאר הנתקלים בבעיה — כיצד פותרים את הבעיה הזו בכל "מקום" בג'ומלה.
מנוע החיפוש של ג'ומלה
המקום הראשון שנתקלים בו בבעיה זו, לרוב, הוא ג'ומלה. הרעיון הוא כללי מאד, וניתן להכליל אותו בנקל למקרים נוספים בג'ומלה או בכלל.
ראשית, שמרו גיבוי של כל קובץ שאתם עובדים איתו. זה חשוב מאד, כי ג'ומלה הוא מנוע מאד מסורבל שמסתמך על המון פאצ'ים חיצוניים, ולעתים אין לדעת מה שינוי — הכי תמים שבעולם — יכול לעשות. שמרו גיבוי.
פתחו את הקובץ joomla.php שנמצא בספריה includes. הקובץ הוא קובץ ענק שמכיל המוני פונקציות של ג'ומלה. חפשו בתוכו את הפונקציה mosSmartSubstr. למרות שמה, הפונקציה אינה כל-כך חכמה, אך אל דאגה – אנחנו "נעלים" אותה, ונחליף אותה בפונקציה חכמה יותר.
ערכו את הפונקציה עצמה כך שתיראה, בסופו של דבר, כך:
function mosSmartSubstr($text, $length=200, $searchword) {/* $wordpos = strpos(strtolower($text), strtolower($searchword));
$halfside = intval($wordpos - $length/2 - strlen($searchword));
if ($wordpos && $halfside > 0) {
return '...' . substr($text, $halfside, $length) . '...';
} else {
return substr( $text, 0, $length);
} */
return UTFSmartSubstr($text,$length,$searchword);
}
שימו לב — מה שעשינו, בעצם, זה "להעלים" את כל תוכן הפונקציה, ובמקום זה להשאיר שורה אחת בלבד שקוראת לפונקציה אחרת. עלינו להוסיף את הפונקציה הזו, ונעשה זאת מיד לאחר הסוגריים של הפונקציה שערכנו זה עתה:
// This is the new UTF-8 solution!function UTFSmartSubstr($text, $length=200, $searchword) {
$wordpos = strpos(strtolower($text), strtolower($searchword));
$halfside = intval($wordpos - $length/2 - strlen($searchword));
if ($wordpos && $halfside > 0) {
$output= substr($text, $halfside, $length);
$op_arr = explode(" ",$output);
array_shift($op_arr );
array_pop($op_arr );
$output = '...' . implode(" ",$op_arr) . '...';
} else {
$output= substr( $text, 0, $length);
$output= substr($text, 0, $length);
$op_arr = explode(" ",$output);
array_pop($op_arr );
$output = implode(" ",$op_arr) . '...';
}
return $output;
}
שימו לב: מה שהפונקציה הזו עושה הוא מאד מועיל: היא מקבלת את המחרוזת באופן רגיל לגמרי, כמו הפונקציה המקורית, אך לאחר מכן היא מפצלת אותה למילים, מעיפה את המילה האחרונה (שהיא המילה הבעייתית — זו שאולי קטועה בצורה לא יפה), מחברת את הכל יחד, ומייצרת מחרוזת חדשה, אותה היא מחזירה. כך הרווחנו שני דברים במכה: ראשית, לא יהיה סימן שאלה; שנית, לא יהיו מילים חצויות, ונקבל מחרוזת שיש בה רק מילים שלמות.
לאחר העדכון שעשיתם, שמרו את הקובץ והעלו אותו לשרת (לא לשכוח — לפני-כן — גיבוי!). הכל אמור לעבוד כמו שצריך עכשיו.
הערה: אם רוב המחרוזת שלכם היא בעברית, אתם עלולים לקבל (לא בגלל הפונקציה החדשה) מחרוזות שהן טיפה קצרות יותר ממה שרציתם. אין בעיה: שחקו עם המשתנה $length (פה, או במקום שקורא לפונקציה), וזה יהיה בסדר!
ב-SMF Bridge לג'ומלה
כן, גם שם אנו נתקלים בסימן השאלה השחור. באופן דומה לפתרון הקודם, גבו קודם כל קובץ שאתם מתכוונים לשנות. ג'ומלה פועל לעתים באופן לא צפוי. בספריה שבה התקנתם את הפורום עצמו (לא את הקומפוננטה של הגשר), יש תת-ספריה בשם Sources. בתוך הספריה הזו תמצאו קובץ בשם Subs.php; שוב, קובץ ענק. פתחו אותו, ובסביבות שורה 911 (אל תתפסו אותי על השורה, יש המון גרסאות…), אמורה להופיע השורה הבאה:
return $func['substr']($subject, 0, $len) . '...';"העלימו" את השורה הזו בעזרת סימן ה"comment", והוסיפו אחריה — במקום — את השורות הבאות (מה שמופיע להלן הוא כיצד זה אמור להיראות בסופו של דבר):
// return $func['substr']($subject, 0, $len) . '...';$output = $func['substr']($subject, 0, $len);
$op_arr = explode(" ",$output);
array_pop($op_arr );
$output = implode(" ",$op_arr) . '...';
return $output;
הפונקציה פועלת בדומה לפעולתה של הפונקציה אותה יצרנו קודם לכן: היא מפרידה את המחרוזת למילים, מעיפה את המילה האחרונה, ומחזירה מחרוזת המורכבת מהמילים שלפניה.
שימו לב, כפי שהערתי קודם לכן, ייתכן בהחלט — ואפילו סיכוי רב — שהמחרוזות אותם תקבלו בחזרה יהיו קצרות מדי (ולא בגלל השינוי). הפתרון לכך הוא קצת יותר מורכב מאשר במנוע החיפוש של ג'ומלה, והריני מפרטו כאן:
יש לעבור בכל אחד מן הקבצים הבאים, בכל אחת מן השורות המפורטות, ולהכפיל את המספר שרשום שם בתור האורך — דהיינו, בכל מקום שרשום 24 יש לרשום 48, אם רשום 25 יש לרשום 50 וכו'. המקומות הם:
עד כאן; שמרו את כל הקבצים והעלו אותם לשרת. זה אמור לעבוד טוב כעת.
שוב ב-SMF: הפעם, ב-Recent Topics
גם במודול הנלווה Recent Topics אנו נתקלים בבעיה דומה. נבנה – בתוך המודול – פונקציה שעושה משהו דומה למה שראינו בבעיות הקודמות. לאחר שאתם מגבים כל קובץ שאתם מתכוונים לערוך, כמובן, ערכו את הקובץ של המודול, הקובץ בשם mod_smf_recenttopics.php (בספריה modules).
בתחילת הקובץ, ממש לאחר כל ה"הודעות" (בסביבות שורה 80), הוסיפו את הפונקציה הבאה:
function utfSubstr( $subject, $start, $len ) {if (strlen($subject) <= $len)
return $subject;
$output = substr($subject, $start, $len);
$op_arr = explode(" ",$output);
array_pop($op_arr );
$output = implode(" ",$op_arr) . '...';
return $output;
}
עכשיו, במקומות המתאימים, נרצה לקרוא לפונקציה הזו; בסביבות שורה 275, מופיעה השורה הבאה:
‘short_subject’ => ...אנחנו רוצים להחליף אותה, בשורה הבאה:
'short_subject' => mb_strlen(un_htmlspecialchars($row['subject']),'UTF-8') > 25 ?htmlspecialchars(utfSubstr(un_htmlspecialchars($row['subject']), 0, 48)) : $row['subject'];
זה יקרא לפונקציה שבנינו. כמו כן, שימו לב שהשתמשנו פה בפונקציה שמודדת את אורך המחרוזת לפי UTF-8 (כן, PHP יודע לעשות זאת!), אך הכפלנו את האורך של המחרוזת שאנחנו רוצים בסופו של דבר. נעשה דבר דומה שוב; בסביבות שורות 550-570, אמורה להופיע שורת הפלט, שנראית בערך כך:
echo substr(...נחליף אותה, שוב, בשורה הבאה:
echo utfSubstr(html_entity_decode($post['subject']), 0, $int_num_char*3);שימו לב שביצענו הכפלה קטנה בסוף... שוב, בשביל לשמור על אורך מחרוזות הגיוני. שמרו, העלו את הקבצים, והכל אמור לעבוד היטב כעת.
בממבלוג
גם מנוע הבלוגים החביב יוצר את הבעיה של סימני השאלה השחורים, אך הוא עושה זאת מסיבה אחרת לגמרי; הסיבה היא פונקציה -- שאמורה להיות מועילה -- בשם safeStrip -- לא מזהה תו המקובל ע"י עורכי WYSIWYG שונים במקום "רווח" במקרים שבהם פסקה היא ריקה (או במקרים אחרים). התו מקודד באופן הבא: (ראשי תיבות: non-breaking space) -- והפונקציה הורסת אותו, וכך נוצר סימן השאלה החביב.
הפונקציה safeStrip נועדה -- במקור -- להבטיח שבתקצירים לבלוגים לא יהיו תגי HTML. אישית, איני מוצא סיבה לכך (מאחר ואת התגים הנ"ל ממילא רואים בדפי הבלוג הרגילים, שמשתמשים במנוע content של ג'ומלה להצגתם); כך הם נראים, בין היתר, ללא מעברי שורה. ולכן, הפתרון שאני מציע לבעיה זו הוא פשוט -- אנו נבטל את הקריאה ל-safeStrip, באופן הבא:
לאחר גיבוי מלא של הקבצים הקשורים, פתחו לעריכה את הקובץ showblogs.php שנמצא בתוך התיקייה הרגילה של הקומפוננטה. בסביבות שורה 459 נמצאת הפונקציה checkLength. כמה שורות לפני סוף הפונקציה, מופיעה השורה הבאה:
$text = safeStrip( $text );סמנו שורה זו כ"הערה", באופן הבא:
// $text = safeStrip( $text );כמו-כן, רצוי באותו הקובץ, בראשית הפונקציה decodeEntities, לסמן את השורה הבאה:
$string = html_entity_decode ($string, $opt);כהערה גם-כן:
// $string = html_entity_decode ($string, $opt);ובזה נגמר הסיפור.
שימו לב, גם, שתקצירי הבלוג ייראו עכשיו בהחלט טוב יותר.
יש מקום נוסף בממבלוג שיכול להוות בעיה: בדף שמציג באופן מרוכז תקצירים של בלוגים רבים. במקרה זה, הבעיה נמצאת בקובץ showblogs.php, בפונקציה checkLength - שוב המחבר מנסה להשתמש בפונקציה substr. כרגיל, נוסיף בתחילת הקובץ (בערך בשורה 14) את הפונקציה החדשה שבנינו:
function utfSubstr( $subject, $start, $len ) {
if (strlen($subject) <= $len)
return $subject;
$output = substr($subject, $start, $len);
$op_arr = explode(" ",$output);
array_pop($op_arr );
$output = implode(" ",$op_arr) . '...';
return $output;
}
עתה, בשורה הבעייתית, בפונקציה checkLength, (צריכה להיות בערך בשורה 477 עכשיו), נחליף את:
$text = substr( $newtext, 0, $maxchars ) . "...";
ות הבאות:
// $text = substr( $newtext, 0, $maxchars ) . "...";
$text = utfSubstr( $newtext, 0, $maxchars*2);
שימו לב להכפלה הקטנה שעשינו! זה, כאמור, מכיוון שהאותיות בעברית "ארוכות יותר".
במנוע המתכונים Ricettario
כן, לא תאמינו – סימן השאלה הארור חודר לנו אפילו לאוכל. במנוע המתכונים Ricettario, אנו נתקלים בסימן השאלה השחור בתקצירים השונים של המזונות כאשר אנחנו באינדקס של קטגוריה.
איך פותרים? זוכרים את הפונקציה שהגדרנו, utfSubstr? ובכן, לשם הנוחות, נכתוב אותה גם פה, מחדש, אבל הפעם ניזהר שאנחנו לא מגדירים אותה פעם אחת יותר מדי: (הרגל טוב באופן כללי)
if (!function_exists("utfSubstr")) {function utfSubstr( $subject, $start, $len ) {
if (strlen($subject) <= $len)
return $subject;
$output = substr($subject, $start, $len);
$op_arr = explode(" ",$output);
array_pop($op_arr );
$output = implode(" ",$op_arr) . '...';
return $output;
}
}
את הפונקציה הזו רושמים בתחילת הקובץ ricettario.php, ממש לאחר כל ההערות (למשל, בסביבות שורה 37).
לאחר מכן, אנחנו רוצים לעדכן את המקום שמדפיס את הטקסט המקוצר עצמו -- להודיע לו שישתמש בפונקציה החדשה. זאת אנחנו עושים באזור שורה 1,550 -- את השורה:
$text=substr ($row1->descr, 0, $ric_testolista);אנחנו מחליפים בשורה:
$text = utfSubstr($row1->descr, 0, (2*$ric_testolista));שימו לב, שוב הארכנו את המחרוזת המקוצרת, כי אנחנו מניחים שהיא כתובה בעיקר בעברית.
במנוע התגובות com_comment
הפתרון לבעיה זו דומה מאד לפתרון הבעיות הקודמות. הקובץ שמעניין אותנו הוא הקובץ common.php שנמצא בספריית הקומפוננטה באדמין.
זוכרים (שוב) את הפונקציה שהגדרנו, utfSubstr? ובכן, לשם הנוחות, נכתוב אותה גם פה, שוב, אך ניזהר שאיננו מגדירים אותה פעם אחת יותר מדי:
if (!function_exists("utfSubstr")) {
function utfSubstr( $subject, $start, $len ) {
if (strlen($subject) <= $len)
return $subject;
$output = substr($subject, $start, $len);
$op_arr = explode(" ",$output);
array_pop($op_arr );
$output = implode(" ",$op_arr) . '...';
return $output;
}
}
את הפונקציה הזו נרשום ממש בתחילת הקובץ common.php, ממש לאחר כל ההערות (למשל, בשורה 11). לאחר מכן, אנחנו רוצים לעדכן את המקום שמקצר את הטקסט. הפונקציה שדואגת לכך היא הפונקציה mc_get_article_title הנמצאת עתה בסביבות שורה 219.
לאחר העדכון, הפונקציה אמורה להיראות כך:
function mc_get_article_title($larticleid) {
$add_txt="";
$mc_rows=mc_SelQuery("Select title, id from #__content where id=$larticleid");
if ($mc_rows) {
$mc_i = 0;
foreach($mc_rows as $mc_row) { $ART[$mc_i] = $mc_row->title; }
/* if (strlen($ART[$mc_i]) < 35) { $add_txt = ""; }
if (strlen($ART[$mc_i]) > 35) { $add_txt = "..."; }
$art_txt = substr($ART[$mc_i], 0, 35) . $add_txt; */
$art_txt = utfSubstr($ART[$mc_i], 0, 70);
return $art_txt;
}
}
וזה הכל!
במנוע הקישורים com_weblinks
לפעמים הבעיה היא -- בעצם -- הרבה יותר פשוטה משנראה במבט ראשון... במנוע com_weblinks, למשל, בעיית סימן השאלה השחור נובעת לרוב בגלל שבמסד הנתונים עצמו השדה הרלוונטי מוגדר כקצר מדי.
הפתרון פשוט: נכנסים למסד הנתונים, לטבלה weblinks (או jos_weblinks, או איך שזה לא יהיה אצלכם), ומשנים את השדה description כך שיהיה באורך 500 תווים במקום 250, ו... זה אמור להספיק!
סיכום
הכתוב לעיל מסביר באופן מפורט למדי כיצד לפתור את הבעיה בכל אחד מן המקרים, אך יותר מכך – ניסיתי, כאן, להסביר באופן עקרוני ממה הבעיה נובעת, וכך לספק לכם כלי לנסות לפתור בעיות דומות (ויש אינסוף כאלה) ע"י הבנת הבעיה ויצירת פתרון משלכם.
אם בכ"ז נתקלתם בבעיית קידוד מסוג זה, ואינכם מצליחים להתמודד איתה, כתבו לי (דרך המייל באתר), וננסה לפתור אותה יחד. אם פתרתם אותה, שלחו לכאן את הפתרון, ותנו לכולם להרוויח מכך!
אני מבטיח לעדכן את הדף הזה במקרים נוספים, אם יצוצו.
תגים: com_comment, com_weblinks, Ricettario, SMF, ממבלוג, מנוע חיפוש, קידוד
שייך לקטגוריות ג'ומלה | אין תגובות »