יום חמישי, 22 באוגוסט 2013

תגית description בmasterPage

למה כל כך חשובה תגית הdescription ?
כי, זה מה שיראו במנוע חיפוש תחת הכותרת של הדף. דבר חשוב לכל הדעות.
 
הבעייה מתחילה כשהדף הראשי הוא מאסטרפייג, ואנחנו רוצים לתת לכל דף את הdescription הייחודי שלו.
לצורך כך, ישנן 2 אפשרויות:
 
בדף הCS של הASPX להוסיף את הקוד הזה:

protected void Page_Load(object sender, EventArgs e)
{
  HtmlMeta tag = new HtmlMeta();
  tag.Name     = "description";
  tagKeyword.Content  = "תיאור של הדף";
  Header.Controls.Add(tagKeyword );
}

טוב, הקוד הזה נראה טוב, אבל לא עוזר כשאני בונה במערכת שלי דפי ASPX, הוא בונה רק את הדף עצמו ובלי הדף CS,
לכן נשתמש בהוספת התגית MetaDescription, בדיוק כמו שהtitle של הדף נקבע בתגית <%Page%>

בצורה שכזו:

<%@ Page Title=שם הדף'
Language='C#'
MasterPageFile='~/SiteM.master'
MetaKeywords="מילות מפתח"
MetaDescription="תיאור הדף" %>




 

יום רביעי, 14 באוגוסט 2013

“unrecognized escape sequence” בביטוי regex

רציתי להסיר את כל התווים המיוחדים במחרוזת, ולהשאיר את הרווחים, לכך השתמשתי בביטוי הרגולרי:
 
[^\w\d+ ]
שמשמעותו: ^ - לשלילה
w\ - כולל כל האותיות (word), גם העבריות
d\ - כולל כל הספרות (digit)
+ - הוספה של תו
 " " - ריווח

למעשה, הוא תופס את כל התווים המיוחדים, למעט רווח, שהוא משאיר.

בפועל, הקוד
string regExp = @"[^\w\d+ ]";
onlyText = Regex.Replace(onlyText,regExp, "");

למה הוספתי @?
כי זו השגיאה שקיבלתי בלעדיו  unrecognized escape sequence (רצף לא מזוהה).

נ.ב. בודק regex מעולה, הרבה אפשרויות, כולל מילון עם רצפים מוכנים

יום שלישי, 6 באוגוסט 2013

הוספת שדה לאובייקט מסוג JSON

נניח קיבלנו אובייקט מסוג JSON ונרצה להוסיף לו שדה נוסף, לפני שליחה שלו אל השרת.
 
var jsonObj = {
    user:
    {
                user1: "1",
                user2: "2",
                user3: "3"
      }
כך נוסיף שדה נוסף של משתנה בשם action עם הערך addUser:

jsonObj ["action"] = "addUser";

נוק אאוט עם Knockout.js

ספריה חמודה שמקצרת הרבה עבודה שחורה בחיבור בין הUI ל JS היא Knockout.js.

בשתי מילים מה היא עושה?
יש לנו בדף המון אלמנטים, במקום שכל פעם ניגש אליהם דרך getelementbyid פשוט נגדיר להם בתוך תגית HTML שם ע"י האלמנט data-bind, בטעינת הדף נטען את כל האלמנטים לתוך הDOM וככה נוכל בקלות לגשת, לשנות, לשלוח, למחוק.

בגדול, זה כמו מערך ששומר את כל הנתונים, אבל החוזק שאפשר לקבוע את היחס בין "המערך נתונים" לבין הדף:
ש"המערך" ישפיע על הHTML, אבל לא להיפך.
שהדף HTML ישפיע על "המערך", אבל לא להיפך.
קשר דו-כיווני, כל שינוי של אחד הצדדים, ישנה את הערך בצד השני.

היופי של Knockout.js שהיא מייעלת הרבה עבודה, לדו':
יש לנו טופס, שכל השדות שלו מוגדרים בdata-bind, הספרייה תוכל לעשות גם ולידציה של כל הנתונים בשורת קוד אחת (ע"י ספרייה נוספת בשם knockout.validation.min), וגם שליחה לשרת את כל הנתונים בשורה שנייה.
 
איך מתקדמים?
א. יש כמה פוסטים נהדרים של הרב דוטנט.
חשוב מאוד. זה לא מודגש בכל הפוסטים שלו (כי זה דבר מאוד הגיוני, אבל...) כשיוצרים את האובייקט שמכיל את כל האלמנטים בדף, צריך לצרף את האובייקט עצמו ע"י הפקודה  ko.applyBindings בעת טעינת הדף. ככה:
 

$(document).ready(function () {
    ko.applyBindings(viewModel);
});
 


ב. דוגמאות מגניבות באתר של Knockout.js

וכמו תמיד יש לי רצון עז לכתוב על זה המון פוסטים. בדיוק כפי שרציתי לכתוב המון על JS ועל C# ולא הצלחתי...
 



 

יום ראשון, 4 באוגוסט 2013

הוספת תמונה לחיפוש בגוגל

לשם הוספת תמונה בחיפוש בגוגל, צריך שני דברים:
א. חיבור מגוגל+ אל האתר:
      כניסה אל עריכת חשבון "ערוך את הפרופיל שלך" >  כניסה אל כותרת "קישורים" > "כותב גם באתרים" ושם הכנסה של כתובת הקישור.
      
ב. חיבור מהאתר אל גוגל+:
    הוספה לקוד של האתר (לא משנה היכן) את כתובת הגוגל+ בתוספת האלמנט rel="author"
 
<a href="https://plus.google.com/107150528670070620829" rel="author"></a>

במקום המספר שמופיע כאן, שנה למספר שלך.

טוב, מה עכשיו?
מחכים בין יום לשבוע, וגוגל אמורה להוסיף את התמונה שהגדרת בפרופיל של גוגל+ אל תוצאות החיפוש.

רוצה לבדוק שאכן הקישור עובד?
כאן לקישור כאן, כתוב את האתר ושם תוכל לראות איזה נתונים "שואב" גוגל מהאתר שלך.

ועוד, משהו קטן. חובה שהתמונה תהיה פרצוף, ולא לוגו.
מניסיון, לוגו לא יופיע בתוצאות. ראה פרטים נוספים פה

יום ראשון, 21 ביולי 2013

הפיכת מסמכי PDF לתמונה

פוסט זה נכתב לאחר שיטוט מסיבי באינטרנט למציאת פתרון, קודם אני אסביר את הבעיה:
ספריות רבות יוצרות מסמכי PDF, הבעייה שכדי שמסמך PDF יהיה תמונה הוא צריך להתרנדר כולו - וזה דבר שאין ספרייה שמטפלת בו. ספריות מפורסמות כמו iText או PDFsharp אינן יכולות לעשות זאת.
למרות ש PDFsharp מציעה את האפשרות הנחמדה לייצא מתוך הקובץ PDF תמונות.

ישנן ספריות חינמיות שטוענות שהן יכולות, אבל אני לא הצלחתי לעשות איתן כלום, כדו' 
 PDFClown, PdfRenderer. בנוסף התיעוד שלהם איננו מפותח מדי, וצריך לחפש פרוייקטים שמפורסמים באינטרנט כדי להבין כיצד לעבוד איתן.

ישנן ספריות שעולות מאות דולרים שמציעות פתרון, כמו soliddocuments
כמובן שלא בדקתי אותם.

וישנו פתרון נוסף, ברמת השרת. הספרייה GHOSTSCRIPT עושה זאת בצורה יפה.
נייבא לפרוייקט את הספרייה, מופיע בNuGet , ונעשה בקוד עצמו הפניה לספרייה עצמה gsdll32.dll
גם בספרייה זו ישנם מספר מוטציות של אותו קוד,שכולם מסמתמכות על אותו כותב.
הקוד שלי הצליח נמצא כאן או דוגמא נוספת כאן

 

יום שלישי, 9 ביולי 2013

קבלת קורדינאטות של מיקום בGoogle Map

לאחר שפתחנו חשבון מפתחים ב"גוגל מפתחים", ניכנס לAPI CONSOLE
נרשמנו, לאחר כמה זמן נקבל אישור ונקבל מספר מפתח, ובקטגוריהAPI ACCESS
נבחר את המחרוזת הארוכה שיש ב API key.
עכשיו ניתן להוסיף באתר שלנו תיבת חיפוש של מפות (במידה ונעבור את 25,000 חיפושים ביום או חצי מיליון בכלל, נצרך לשלם ולקבל חשבון עיסקי. די לצרה בשעתה...)
 
נוסיף את הסקריפט הזה באתר שלנו (החליפו את ה$$$$ ב api key)

 
<script src="https://maps.googleapis.com/maps/api/js?key=$$$$&sensor=false"></script>


וכל פעם תקבלו משתנה  google.maps שהוא מנהל את כל ההתנהלות שלכם מול הAPI של המפות.
(תוכלו לראות שנוספו לכם המון קבצי JS, הידד!)
נ.ב. אלו המשתנים והפונקציות שאנחנו מקבלים בעת קבלת האובייקט אצלנו 
google.maps

לצורך העניין בנינו תיבה שבה המחפש רושם את המקום שלו, ואנחנו רוצים להמיר אותה לקורדינטות - כדי שבפעם הבאה נוכל להציג למשתמש מפה, מבלי לחפש. ככה נוכל לחסוך את החיבור לגוגל והרבה תעבורת רשת. אם רוצים לקבל מפה קבועה.
 
var adress_map = $.trim($("#sMap").val());
var point = new Array("jb", "kb");

point = getCodeAddress(adress_map);
 
function getCodeAddress(address) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
  var point = new Array(results[0].geometry.location.jb, results[0].geometry.location.kb);
  return (point);
} else {
alert("אין אפשרות לקבל את הקודינאטות של המפה, תקלה: " + status)
}
});
}