חדש באתר: תעודות סיום קורס

13/01/2023

שתי הודעות משמחות להיום - קודם כל למדתי איך עובדים עם PDF-ים ב Ruby, ודבר שני הוספתי לאתר מנגנון שמאפשר לכם להוריד תעודה אחרי שסיימתם קורס. ועכשיו הפרטים.

1. איך עובדים עם PDF ב Ruby

בשנים שהאתר הזה באוויר הרבה אנשים מכל מיני סיבות ביקשו לקבל איזשהו אישור על קורסים שסיימו פה. תקופה מאוד ארוכה לא אהבתי את הרעיון. תעודות נראו לי (ועדיין נראות) כמו שריד מיושן מהעבר, כמו משהו שצריך היה לעבור מזמן מהעולם. לימוד הוא הגמול של עצמו ואם מישהו רוצה להוכיח מיומנות אז תיק עבודות איכותי שווה יותר מכל תעודה.

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

class CertificatesController < ApplicationController
  def show
    @bundle = Bundle.find_by(slug: params[:b])
    authorize! :graduate, @bundle

    if current_user.name_on_certificate.blank? || current_user.certificate_gender.blank?
      return redirect_to(edit_user_registration, flash: t('notifications.missing_certificate_info'))
    end

    pdf = Prawn::Document.new
    pdf.font Rails.root.join('certificates', './Alef-Regular.ttf')
    pdf.bounding_box([140, 554], width: 300, height: 100) do
      pdf.text current_user.name_on_certificate, direction: :rtl, size: 24
    end
    pdf.bounding_box([80, 370], width: 500, height: 100) do
      pdf.text @bundle.name, size: 24
    end
    pdf.bounding_box([374, 242], width: 50, height: 100) do
      pdf.text @bundle.recommended_duration_in_hours, size: 16
    end

    # get the existing pdf
    template = CombinePDF.load Rails.root.join('certificates', "certificate_template_#{current_user.certificate_gender}.pdf")
    user = CombinePDF.parse pdf.render

    template.pages[0] << user.pages[0]

    send_data template.to_pdf, filename: "tocode_#{@bundle.slug}.pdf", type: "application/pdf"
  end
end

וכמו שאני אוהב בואו נעשה קצת Code Review כדי ללמוד קצת על רובי ועל ה Trade Offs בפיתוח פיצ'רים:

  1. דבר ראשון שאני לא אוהב בקוד זה שכל הקוד כתוב בפונקציה אחת ארוכה. בעולם מושלם הייתי לוקח את כל החלק המרכזי ומוציא אותו לפונקציה אחרת בקלאס אחר. יום אחד זה כנראה יקרה בסבב Refactoring כלשהו, אבל אני חושב שבקוד שאינו תשתיתי במערכת אין בעיה להתחיל עם משהו שעובד ולהתקדם משם.

  2. החלק הראשון של הפונקציה מורכב מ-5 השורות הראשונות. הוא בודק שאתם יכולים לייצר תעודה, כלומר שסיימתם את הקורס ושאני יודע איך קוראים לכם. הפונקציה t של ריילס היא הדרך לטעון הודעה מקובץ תרגום, ובאופן כללי כל הטקסטים באתר שמורים בקובץ תרגום בצד בפורמט yml.

  3. החלק השני של הפונקציה יוצר את התעודה בפורמט PDF בעזרת שתי ספריות: prawn ו combine_pdf. שתיהן לא הכי מתוחזקות אבל עובדות. בשביל שהתעודה תצא יפה יצרתי שני קבצי PDF בתור תבנית (אחד לבנים עם המילה "השתתף" והשניה לבנות עם המילה "השתתפה") ושמרתי אותם בתיקיית הפרויקט. בקוד אני נותן ל prawn לייצר PDF חדש רק עם החלקים הדינמיים בתעודה, כלומר שם המשתמש, שם הקורס וכמה שעות הקורס. אחרי זה אני משתמש ב combine_pdf כדי לשלב את החלקים הדינמיים עם התבנית ולקבל קובץ תעודה עם הנתונים. שווה לשים לב שכל העבודה מבוצעת בזיכרון בלי קבצים זמניים, וכך לא צריך להמציא שמות ולהתמודד עם התנגשויות.

  4. השורה האחרונה שולחת את התעודה חזרה לדפדפן.

2. איך להוריד תעודה בקורס שסיימתי

אם אתם מנויים לאתר ורוצים לראות איך נראית תעודה, כל מה שאתם צריכים לעשות הוא לסיים לצפות באיזשהו קורס (מקווה שכבר עשיתם את זה), ואז במסך תוכן העניינים של הקורס תופיע לכם תיבה חדשה משמאל לרשימת השיעורים עם אפשרות להוריד את התעודה.

3. תקלות? שאלות? דברו איתי

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