היומן של סילבר הארוך - יומן
היבטים: מדריך להצגת פוסט אחרון של כל משתמש
אני רוצה לכתוב הפעם מדריך שיגע בבעיה מסוימת שנתקלתי בה. אנחנו נסקור כמה פתרונות, חלקם נכונים ואחד שגוי. אבל גם דרך הדרך השגויה נלמד כמה כלים חשובים.
להקל על הקוראים אני מקדים רשימה של תחומים שאגע בהם במדריך:
- הֶקשרים (RELATIONSHIPS)
- עיצוב שדות על ידי הUI של VIEWS.
- אַחֵד לפי (group by)
- הצגת שדה פעם אחת (Distinct)
- הדפסת VIEW עם משתנים (arguments או FILTERS contextual)
הנושא הפעם הוא views (היבטים). אני אסביר איך לעשות דברים בהיבטים 3, ומדי פעם אעיר הערות על 2. הסיבה המאד פרוזאית היא שמהר מאד עברתי ל3, אז שם יותר קל לי להדגים.
למי שלא יודע, היבטים הם בעצם UI שמאפשר לנו לבנות שאילתות SQL ולהציג אותם. לשלוף נתונים ממסד הנתונים- ולהציג אותם בדרכים שונות.
טוב, כל עוד מה שאנחנו עושים בהיבטים הוא להציג, נניח, את כל הכתבות האחרונות, זה קל ופשוט, יחסית.
לדוגמה: להציג את כל הפוסטים האחרונים בבלוגים, בלי הבדל דת גזע ומשתמש. מה אנחנו עושים במקרה כזה?
פותחים היבט רגיל של תוכן, הולכים לADD FILTER -מספר 1 בתמונה 1- ומוסיפים מסנן: תוכן:סוג, ומסמנים שרק דפים מסוג בלוג יופיעו. יופי, יש לנו רשימה של כל הבלוגים האחרונים. כמובן, נעביר את הצג (display - 2) למצב "שדות", ונבחר אלו שדות אנחנו רוצים: כותרת, גוף הבלוג וכו'
מה יקרה אם אנחנו רוצים להוסיף לכל בלוג את תמונת המשתמש? זה פחות קל. אם ננסה להוסיף שדה (FIELD) של תמונת המשתמש נגלה שהיבטים לא מציע לנו את זה ברשימת שדות. למה?
כי היבטים שולף מידע מטבלה (אבסטרקציה של טבלה, למעשה), ובטבלת התוכן (nodes) אין את התמונה של המשתמש. במקרה זה אנחנו צריכים להפעיל את RELATIONSHIPS (הֶקשרים). מה זה הקשרים?
הקשרים, למי שקצת מדבר אסקיואלית מצויה, הם הJOINS של היבטים. אני לוקח נתון מטבלה מסויימת (במקרה שלנו,לוקח מטבלת תוכן את הID של מחבר הבלוג- UID) ובאמצעותו שולף תוכן מטבלה אחרת, במקרה שלנו תמונת המשתמש מטבלת משתמשים.
JQUERY בDRUPAL 7
לחסוך זמן שלי בוזבז בניסיון לפתור את הבעיה:
בדרופל 7, JQUERY הוגדר כך שהמשתנה $ איננו מתייחס תמיד לJQUERY. כל סקריפט של JQUERY שמשתמש ב$ צריך להכניס לתוך:
(function ($) {
// Original JavaScript code.
})(jQuery);הסבר אפשר למצוא כאן
VIEWS ARGUMENTS
בVIEW (מכאן ואילך אקרא לזה "היבטים") ישנה תכונה שנקראת ARGUMENTS (משתנים).
איך משתמשים במשתנים?
קודם נבין את העיקרון.
בSORT הרגיל של היבט, אני יכול לבחור שדה מסויים, ולבחור מה הוא שווה (דוגמה קלאסית היא שאני בוחר את השדה: סוג הNODE, ובוחר, נניח בלוג). באופן הזה היבטים יציג לי דף עם כל הדפים מסוג בלוג, ואך ורק אותם. מה אני עושה אם אני רוצה ליצור היבט באותו עקרון שמראה את כל הדפים מסוג STORY? לעבוד שוב? לעשות CLONE? ליצור DISPLAY שונה?
כל הפתרונות האלו מסורבלים. מה קורה אם אני רוצה להציג את כל הפוסטים מחודש מסויים? אני אצור היבט לכל חודש?
דרך אחת היא EXPODED FILTERS. לא ניגע בה כרגע.
דרך אחרת היא משתנים. משתנים פועלים באותו עיקרון כמו FILTER, אבל מאפשרים גמישות רבה יותר. למי שמכיר קצת מושגים- זה כמו דף שמציג פלט על פי GET (לא מדוייק, כי בעצם 99% מהדפים בדרופל הם כבר בGET).
איך אני מוסיף משתנה?
בVIEWS2 יש לי משבצת שנקראת ARGUMENTS. אני מוסיף בה ממש כמו שמוסיפים בFILTER. נניח נוסיף משתנה מסוג Created month. (אם הבנתי נכון, בVIEW3 זה נקרא CONTEXTUAL FILTERS במקום ARGUMENTS)
כעת, ההיבט יציג לנו כל פעם את כל התכנים שנוצרו בחודש מסויים, לפי מה שנכתוב לו... רגע, איפה?
להוסיף מסנן מסוג משתנה לא מספיק. צריך לקבוע לו גם מקום בו יופיע המשתנה. את זה עושים באפשרות של היבטים לגבי הנתיב: PATH.
בכל DIPLAY מסוג דף אני צריך גם לקבוע את הנתיב בו הVIEW יופיע. נניח MYVIEW. כדי להוסיף ארגומנט, אני פשוט מוסיף בשדה של הPATH בהיבט / ואחריו סימן %
ביחד:
MYVIEW/%
ואז, כשאכנס לדף MYVIEW/04, הוא יציג לי את כל הפוסטים שנוצרו ברביעי. MYVIEW/5 הוא יציג לי את הפוסטים שפורסמו בחמישי וכו'
אפשר גם ליצור כתובת כזו MYVIEW/%/WOW. כלומר, ה% לא חייב להיות בסוף.
אם מוסיפים יותר ממשתנה אחד, צריך להוסיף עוד סימני %, מופרדים בסימני /.
מקרה מעניין שדבר כזה יעזור (עלה בפורום לפני כמה שבועות) אם אני רוצה השתמש בהיבט בתוך כך שיוצג על פי נתון מההיבט הראשון (NID נניח), אני יכול לקבוע בשני (הפנימי) משתנה, ולהעביר לו את המשתנה מהNODE של ההיבט הראשון, על ידי VIEWS_EMBED_VIEW או על ידי VIEWFEILD
קטן ומעצבן- שורה לבנה בתחילת העמוד, ללא סיבה
בעיה ופתרונה, לחסוך למישהו את הזמן שלי התבזבז:
אני עסוק בשבוע האחרון (בין השאר) בלעזור להעביר אתר על מערכת קודמת לדרופל.
משהו שתקע אותי מאד, היה רווח מעצבן שמקורו לא ברור, בין תחילת העמוד לבין התחלת דף האינטרנט כמו שתכננו אותו. (בין הבודי לפייג').
מבחינת מבנה הדום- לא היה שום דבר בין BODY לPAGE.
עברתי על כל מיני כללי CSS, ולא נמצאה בהם סיבה לזה.
התעקשתי הלאה: ביטלתי את כל הCSS (בCHROME). תוצאה - נאדה. ביטלתי ג'אוה סקריפט-שום דבר.
חשדתי שאולי php מדפיס משהו לפני שנפתח הBODY, אבל גם במקרה כזה מה שמודפס אמור להופיע בבודי.
עבודת מחקר מאומצת גילתה שמדובר במודול שלי שעושה את הבעיות. אלא שלא היה בו שום דבר שאמור לגרום בעיה כזו.
התחלתי לחקור שיטתית את קובץ המודול. הורדתי פונקציה ועוד אחת-
הגעתי למצב האבסורדי בו נשארה רק התוית הפותחת >?PHP ועדיין הבעיה קיימת. כשהמודול מופעל- הרווח קיים. כשהוא מבוטל- הרווח נעלם.
מסקרנות הורדתי גם את התגית עצמה, ופתאום הבעיה נפתרה. הרווח נעלם גם כשהמודול הופעל.
מה??
אור אדום נדלק במוח: רגע, אז מה שקורה הוא-
נכנסתי לעורך הקובץ, העברתי את הקידוד מ:
UTF8+BOM
ל:
UTF סתם,
ובא לציון גואל.
(וחבל שלא נפל לי האסימון קודם)
לפרטים נוספים:
php and utf+bom
פקודות PHP בדפי תבנית- למתחילים (7)
הצילו! המסך שלי פתאום לבן עם הודעה מפחידה!!!
(פתירת שגיאות בסיסיות)
ברגע שהתחלנו להתעסק עם קוד הPHP, ולו באופן הכי בסיסי, רוב הסיכויים שמתישהו כשננסה להכנס לדף באתר ונראה מסך לבן ובו הודעת שגיאה.
להקדים תרופה למכה
אז קודם כל: גיבוי, כמובן.
לא מתחילים להתעסק בשום דבר בערך בלי לגבות.
וכמובן: לא עורכים ניסויים על גבי אתר באויר. אתם לא רוצים שהגולשים שלכם ייתקלו בהודעות שגיאה, בטח שלא ייתקעו מול מסך לבן.
אם אתם חייבים לעשות משהו באתר פעיל כבר, תורידו אותו מהאויר לכמה שעות (admin/settings/site-maintenance).
בלי פאניקה: מדריך קצרצר לבעיות בסיסיות שתתקלו בהן
אם אתם טורחים לקרוא את המדריך הזה, רוב הסיכויים שהבעיות שתתקלו בהן הן בעיות כאלו שנובעות מתחביר שגוי: שכחנו לכתוב איזה תו חיוני.
הודעות כאלו של הדפדפן מתחילות בדרך כלל ב"Parse error: syntax error, unexpected". זאת אומרת שהדפדפן מספר לנו על בעיית תחביר, ושהוא מצא משהו בלתי צפוי. בהמשך הוא מספר לנו באיזה קובץ קרתה השגיאה, ובאיזה שורה- אלו הנתונים שחשובים לנו בעיקר.
ברמה הבסיסית בה מטפל המדריך הזה, ישנן כמה סיבות עיקריות לשגיאת תחביר:
א. ניסינו להדפיס כמה משתנים/מחרוזות ביחד, ושכחנו לחבר אותם על ידי נקודה.
<?
echo $vv"ddd";
?>במקרה כזה הדפדפן יאמר לי " unexpected T_CONSTANT_ENCAPSED_STRING, expecting ',' or ';' in E:\xampp\htdocs\nis.php on line 2 "
או להפך:
<?
echo "ddd"$vv;
?>במקרה זה השגיאה תהיה:" unexpected T_VARIABLE, expecting ',' or ';' in E:\xampp\htdocs\nis.php on line 2"
יש עוד כל מיני שגיאות כאלו: שכחנו לשים סימן דולר לפני משתנה (אאל"ט זה לא יעשה מסך להן אלא את הודעות השגיאה האדומות הללו), לא סגרנו סוגריים וכו' המשותף בין כולן שברוב המקרים, השגיאה תהיה בשורה אותה מציינת הודעת השגיאה.
ב. שכחנו לשים ; אחרי פקודה של PHP.
בכל "שורה" של השפה מותרת רק פקודה אחת, בPHP, כאשר מבחינת המחשב בכל פעם שיש ; מסתיימת שורה. (לא לבלבל עם ספירת השורות שמתבצעת על פי מעברי שורה) לכן, אם נשכח לשים ; וננסה לעשות עוד פקודה (למשל echo) הדפדפן יזהה שגיאת תחביר.
במקרה הזה:
<?php
echo $fff
echo $ggg;
?>- חברי האתר יכולים לשלוח תגובה - כניסה , הצטרפות.
- הצג את ההמשך
פקודות PHP בדפי תבנית- למתחילים (6)
ריצה על פני מערכים: foreach- פרק לפני אחרון, ממש מתקדם, כמעט לתכנת...
בתבניות מסויימות, (view-fields, לדוגמה) אנחנו מקבלים מערך שכולל הרבה אלמנטים, שמן הסתם את כולם נרצה להדפיס בדרך דומה מאד.
בשביל זה יש לנו את הפקודה foreach.
הפקודה foreach היא בעצם פקודה לPHP שאומרת- תעבור על כל המשתנים שבמערך, ותעשה את הפעולה הבאה שוב ושוב.
"הפעולה הבאה" הן כל הפקודות שבאות בתוך סוגריים מסולסלים.
נתחיל שוב, לאט לאט. פקודת הforeach עצמה עובדת כך.
<?php
foreach ($myArray as $key=>$value)
?>אנחנו קודם כל כותבים foreach, פותחים סוגריים עגולות.
ואז: המשתנה הראשון הוא המערך שעליו אנחנו רוצים שPHP יעשה את כל הפקודות שלנו.
אחר כך כותבים as, ומגדירים שני משתנים שלא היו קיימים קודם. אפשר לכתוב איזה שם שתרצו, עדיף לכתוב $key ו$value כמו שכתבתי למעלה.
שוב, key הוא השם של המשתנה, וvalue הוא הערך של המשתנה. בשני המשתנים האלה נשתמש בתוך הforeach, כשנאמר לPHP מה אנחנו רוצים שהוא יעשה עם כל משתנה במערך.
למה זה טוב לנו? נדגים
נניח שיש לי רשימה של שדות (fields) ואני רוצה להדפיס כל אחד מהם בתוך div משלו, עם אותו קלאס לכולם, ועם id שיזהה אותו על פי שם השדה.
מהמידע שיש לי על הדף "views-view-fields.tpl.php" אני יודע ש:
" $fields: an array of $field objects".
כלומר במערך השדות יש לי מספר לא ידוע של משתנים, שכל אחד מהם הוא אובייקט שנקרא שדה (field).
אם אעשה קצת ניסויים אני אגלה שהשם של כל משתנה במערך השדות הוא שם השדה. נניח, אם יש לי שדה שקראתי לי wave, השם שלו בתוך מערך השדות יהיה wave. או ליתר דיוק (במקרה של שדה שנוצר בCCK), השם יהיה field_wave
אני אכתוב כך:
<?php
foreach ($fields as $key=>$value){
?>
<div class="field_container" id=" <?php echo $key; ?>" >
<?php echo $value->content; ?>
</div>
<?php } ?>נעבור על מה שנעשה כאן שורה- שורה.
שורה מספר 1 היא תגית הפתיחה של PHP.
בשורה מספר 2 אני מתחיל להריץ את המערך על ידי foreach. הגדרתי את ששם המשתנה בתוך הforeach ייוצג על ידי $key והערך על ידי $value.
- חברי האתר יכולים לשלוח תגובה - כניסה , הצטרפות.
- הצג את ההמשך
פקודות PHP בדפי תבנית- למתחילים (5)
מערכים ואובייקטים.
לא כל משתנה בדרופל הוא בעל ערך בודד (מחרוזת, מספר או בולאן). לפעמים משתנה הוא קבוצה של משתנים, שמסודרים כאובייקט או כמערך (array).
במסגרת המדריך הפשוט הזה כמובן שלא נכנס לנושא כולו (מה ההבדל בין מערך לאובייקט?), רק נדון מה שלענייננו.
אם אקח מערך ואנסה להדפיס אותו (echo), המחשב פשוט יכתוב לי על הדף "Array". אם אנסה להדפיס אוביקט, PHP ידפיס הודעת שגיאה.
להדפיס מתוך מערך או אובייקט, אפשר רק ערך בודד מתוכו (בתנאי שהוא מחרוזת או מספר).
הדרך להגיע לערך בודד במערך היא כזו:
$myarray['mykey']ונסביר.
נניח שיש לי מערך ששמו users, ולערך בתוכו קוראים 'Name'. שימו לב, 'Name' איננו המחרוזת עצמה, זה רק השם שלה (key). הערך של 'Name' (המחרוזת עצמה) הוא 'Tom'. כמו שאני יכול שיהיה לי משתנה בשם title$ שהערך שלו הוא "A lot of letters", כך גם יש לי משתנה בתוך המערך שהשם (key) שלו הוא "Name" והערך הוא "Tom".
אם אני רוצה להדפיס על הדף 'Tom', אני אכתוב:
<?php
print $users['Name'];
?>המחשב ידפיס Tom.
מבחינתנו, אותו עקרון עובד גם על אובייקט, אלא שבמקום סוגריים מרובעות נכתוב חץ בודד "<-" ואת השם של הערך (key) לא נקיף במרכאות, כך:
.
<?php
print $users->Name;
?>גם כאן, המחשב ידפיס Tom.
עקרונית, משתנה בתוך מערך או אובייקט יכול להיות גם הוא מערך או אובייקט. כך, בתוך האובייקט users, הערך name יכול להיות אובייקט של שם פרטי ושם משפחה, ואז כדי להדפיס "Tom", נצטרך לכתוב:
.
<?php
print $users->Name->firstName;
?>הערך name יכול להיות גם מערך שמורכב משם פרטי ושם משפחה, ואז נכתוב
.
<?php
print $users->Name['firstName'];
?>וכולי וכולי, כל שילוב שתעלו על דעתכם בין מערכים לאובייקטים.
מה עושים עם המידע הזה?
קודם כל, מעכשיו כשנכנס לדף תבנית ונראה סמנים מוזרים של "$" ו"<-" וסוגריים מרובעות, לא נחטוף פיק ברכיים ונחזור לגדל צנוניות.
דבר שני, ברגע שאנחנו מבינים איך קוראים לערך שנמצא בתוך אובייקט או מערך, ניתן להשתמש בשלל המשתנים שכבר נתונים לנו בדפי התבנות.
ש: איך מגלים מבנה של מערך או אובייקט?
ת: כדי לראות את המבנה השלם של מערך או אובייקט, אפשר להשתמש בפקודה ()print_r
אם אכתוב:
פקודות PHP בדפי תבנית- למתחילים (4)
תְנאים
בתבנות ,הדבר החשוב הבא לדעת, אחרי משתנים והדפסתם, הם תנאים.
תנאי נועד למצב שבו אתה רוצה להדפיס משהו , רק אם משהו מסויים קורה.
כל תנאי נפתח כמובן ב if.
if (condition)כאשר בתוך הסוגריים נמצא התנאי שלנו. אם הוא יהיה נכון, המשך הקוד יבוצע.
מה נקרא "נכון"?
טוב, אם אני אכתוב תנאי כזה:
if (1==1)ברור לכולנו שהוא נכון.
ואם נכתוב
if ($one==1)כאשר המשתנה $one הוא מספר שבמקרה גם שווה אחד, זה גם יהיה נכון.
המקרים שיותר מעניינים אותנו הם שניים:
מחרוזת:
כל מחרוזת שמוכנסת ל if נחשבת כ"נכון"
if ("foo")יהיה נכון.
גם
if ("no")יהיה נכון, כי לא אכפת למחשב מה כתוב במחרוזת, על עוד זו מחרוזת.
וגם
if ($links)יהיה נכון, בתנאי ש$link הוא איזו מחרוזת.
אבל, וזו הנקודה החשובה, אם $link לא שווה כרגע כלום, התנאי יחזיר "לא נכון".
אחד התנאים שחוזרים הכי הרבה בתבניות הוא, לדוגמה, התנאי:
<?php
if ($logo){
print $logo}
?>מה שהתנאי הזה אומר, במילים פשוטות הוא: אם המשתנה $logo מוגדר (שורה מספר 2), תדפיס אותו (שורה מספר 3).
בפועל בדרך כלל מוסיפים סביב ה$logo תגיות html כרצוננו.
if ( $logo )
{ print "<div class='logo'>" . $logo . "</div>"; }ואז מה שקורה הוא שאם המשתנה לוגו קיים, כל הdiv יודפס. אם לא, PHP ידלג על החלק הזה וימשיך הלאה.
בולאן
יש עוד סוג תנאי נפוץ, הוא תנאי בעזרת בולאן.
קודם אמרנו שיש משתנה שנקרא בולאן, ויכול להיות או כן או לא. אי אפשר להדפיס אותו: הוא קיים רק בשביל תנאים.
מה זה עוזר לנו?
לדוגמה, בכל page.tpl.php יש בולאן שנקרא $is_front. המשתנה הזה כשמו כן הוא. אם דרופל מציג כרגע את הדף הראשי, $is_front יהיה "נכון" (true). אם לא, $is_front יהיה "לא נכון". (false)
איך זה עוזר לי?
נניח שאני רוצה שהלוגו שלי יוצג רק בדף הראשי. למה? קריזה של הלקוח. אני יכול לכתוב תנאי כזה.
if ( $is_front )
{print $logo;}PHP יגיע לשורות האלו ויבדוק: אם הדף הוא הדף הראשי, הוא ידפיס את הלוגו. אם לא, לא.
עוד שלוש נקודות חשובות, בטרם נמשיך:
- חברי האתר יכולים לשלוח תגובה - כניסה , הצטרפות.
- הצג את ההמשך
פקודות PHP בדפי תבנית- למתחילים (3)
איך מדפיסים משתנה אל תוך הדף בPHP?
יש שתי פקודות להדפסה: echo ו print. לענייננו אין הבדל ביניהן.
אפשר הדפיס איתן מחרוזת:
<?php
echo "foo";
?>כששמתי את המילה "foo" בתוך גרשים, בעצם אמרתי לPHP שיש כאן מחרוזת, ולכן הוא ידפיס על הדף foo. (נכון יפה מצידו?)
אבל, אפשר להדפיס גם משתנים שהם סטרינג (או מספר). לכן, אם אנחנו פוגשים שורה כמו:
<?php
print $title;
?>אנחנו יכולים להניח שכאן מודפס המשתנה $title. מה הוא ידפיס בפועל?
אם הכותרת שלי היא "שלום" הוא ידפיס שלום, אם היא "go away" זה בדיוק מה שהמחשב ידפיס. בחור טוב בסך הכל.
לפעמים אנחנו רוצים להדפיס שתי מחרוזות ביחד. בphp זה נעשה על ידי הסימן נקודה (".") . אם אני רוצה להדפיס את הכותרת ולאחריה את מספר הnode אני כותב:
<?php
print $title . $nid;
?>שימו לב ששמתי רווח לפני ואחרי הנקודה. זה עוזר לקריאוּת של הקוד.
אני יכול גם לחבר משתנים עם מחרוזות:
<?php
print $title ."foo" . $nid;
?>טוב, עכשיו כשסגרנו את עניין כתיבת המשתנים, נוכל לגשת לכל מקום שכתוב print או echo ולנסות להבין מה קורה.
רק עוד שתי הערות:
א. שימו לב שבסוף כל שורת קוד, אני מוסיף את הסימן ";". זה הכרחי עבור PHP לדעת כשנגמרה שורה, כדי לא ליצור בעיות קומפילציה.
ב. ניתן גם להדפיס פונקציות, אבל זה כבר למדריך מתקדם יותר...
פקודות PHP בדפי תבנית- למתחילים (2)
שלב ראשון: מהו variable?
(מתוך שיעור ראשון במגמת מחשבים בתיכון)
משתנה, או variable היא יחידה בסיסית בכל שפת תכנות.
לענייננו, משתנה זה יכול להיות:
- מספר (שלם או שבר):
במספרים אפשר לעשות פעולות חשבונית או הדפסה: לכתוב אותם לתוך דף הHTML.
-
מחרוזת (string)- רצף של תווים:
אפשר לחבר אותה למחרוזת אחרת, למספר, או, כמובן, להדפיס אותה על הדף. -
בולאן:
משתנה שיכול להיות או כן או לא. (True or False). אי אפשר להדפיס בולאן, אפשר להשתמש בו רק בדרכים שנזכיר להלן. -
אובייקט או מערך: יוסברו מאוחר יותר.
כללי אצבע
- הכלל החשוב הראשון בphp הוא שכל מה שמתחיל בסימן $ הוא משתנה. $content, $title וכו'
- הכלל החשוב השני הוא שבדרך כלל (בתבניות דרופל), לכל משתנה יהיה שם הגיוני. $title היא כותרת (מחרוזת), $content (כנ"ל) הוא תוכן וכן הלאה.
- כלל ג' אומר שלמרות כלל ב', לעיתים שמות של משתנים עלולים להטעות. לדוגמה, אני בזבזתי זמן בחיפוש אחר משתנה בשם $Author שהוא, כך הנחתי, שם מחבר הNode. בסוף התברר שהמשתנה נקרא בכלל $name.
