مرفقات نوع النشاط

هذا هو الإرشاد الخامس في سلسلة الإرشادات الخاصة بإضافات Classroom.

في هذا الإرشاد، يمكنك تعديل المثال من خطوة الإرشاد السابقة لإنشاء مرفق من نوع نشاط. هذه هي أي مرفقات تتطلّب إرسال عمل الطالب، مثل ردّ مكتوب أو اختبار أو أي عنصر آخر من إنشاء الطالب.

من المهم التمييز بين المرفقات من نوع محتوى والمرفقات من نوع نشاط. تختلف المرفقات من نوع نشاط عن المرفقات من نوع محتوى بالطرق التالية:

  • يظهر زر "تسليم" في أعلى يسار إطار iframe الخاص بـ "عرض الطالب".
  • توفّر هذه المرفقات معرّفًا فريدًا لعمل الطالب.
  • تظهر بطاقة المرفق في واجهة مستخدم أداة وضع الدرجات في Classroom.
  • يمكنها ضبط درجة للواجب الذي تنتمي إليه.

يُرجى الاطّلاع على الإرشاد التالي لمناقشة وضع الدرجات. أثناء هذا الإرشاد، يمكنك إكمال ما يلي:

  • تعديل طلبات إنشاء المرفقات السابقة إلى Classroom API لإنشاء مرفق من نوع نشاط
  • تنفيذ مساحة تخزين مستمرة لعمليات إرسال الطلاب
  • تعديل مسار "عرض الطالب" السابق لقبول إدخالات الطالب
  • توفير مسار لعرض إطار iframe الخاص بـ "مراجعة عمل الطالب"

بعد الانتهاء، يمكنك إنشاء مرفقات من نوع نشاط في الواجبات من خلال واجهة مستخدم Google Classroom عند تسجيل الدخول بصفتك معلّمًا. يمكن للطلاب في الصف أيضًا إكمال النشاط في إطار iframe وإرسال ردّ. يمكن للمعلّم الاطّلاع على عمل الطالب في واجهة مستخدم وضع الدرجات في Classroom.

لأغراض هذا المثال، أعِد استخدام نموذج المرفق من الإرشاد السابق الذي يعرض صورة لمعلم مشهور وشرحًا يتضمّن اسم المعلم. يتألف النشاط من مطالبة الطالب بتقديم اسم المعلم.

تعديل طلب إنشاء المرفق

انتقِل إلى قسم الرمز الذي أنشأت فيه مرفقًا من نوع محتوى في الإرشاد السابق. العنصر الرئيسي هنا هو مثال على كائن AddOnAttachment، الذي حدّدنا فيه سابقًا teacherViewUri و studentViewUri وtitle للمرفق.

في حين أنّ جميع مرفقات الإضافة تتطلّب هذه الحقول الثلاثة، يحدّد وجود studentWorkReviewUri أو عدمه ما إذا كان المرفق من نوع نشاط أو من نوع محتوى. يصبح طلب CREATE يتضمّن studentWorkReviewUri مرفقًا من نوع نشاط، بينما يصبح طلب CREATE بدون studentWorkReviewUri مرفقًا من نوع محتوى.

التعديل الوحيد الذي يجب إجراؤه على هذا الطلب هو ملء حقل studentWorkReviewUri. أضِف مسارًا يحمل اسمًا مناسبًا هنا، وسيتم تنفيذه في خطوة لاحقة.

Python

في المثال الذي نوفّره، يكون هذا في طريقة create_attachments في ملف webapp/attachment_routes.py.

attachment = {
    # Specifies the route for a teacher user.
    "teacherViewUri": {
        "uri":
            flask.url_for(
                "load_activity_attachment",
                _scheme='https',
                _external=True),
    },
    # Specifies the route for a student user.
    "studentViewUri": {
        "uri":
            flask.url_for(
                "load_activity_attachment",
                _scheme='https',
                _external=True)
    },
    # Specifies the route for a teacher user when the attachment is
    # loaded in the Classroom grading view.
    # The presence of this field marks this as an activity-type attachment.
    "studentWorkReviewUri": {
        "uri":
            flask.url_for(
                "view_submission", _scheme='https', _external=True)
    },
    # The title of the attachment.
    "title": f"Attachment {attachment_count}",
}

إضافة مساحة تخزين مستمرة للمرفقات من نوع محتوى

سجِّل ردّ الطالب على نشاطنا. يمكنك البحث عنه لاحقًا عندما يعرض المعلّم العمل في إطار iframe الخاص بـ "مراجعة عمل الطالب".

اضبط مخطط قاعدة بيانات لـ Submission. يتوقّع المثال الذي نوفّره من الطلاب إدخال اسم المعلم المعروض في صورة. لذلك، يحتوي Submission على السمات التالية:

  • attachment_id: معرّف فريد للمرفق. يتم تعيينه من قِبل Classroom ويتم عرضه في الردّ عند إنشاء مرفق.
  • submission_id: معرّف لعمل الطالب. يتم تعيينه من قِبل Classroom ويتم عرضه في الردّ getAddOnContext في "عرض الطالب".
  • student_response: الإجابة التي قدّمها الطالب.

Python

وسِّع نطاق تنفيذ SQLite وflask_sqlalchemy من الخطوات السابقة.

انتقِل إلى الملف الذي حدّدت فيه الجداول السابقة (models.py إذا كنت تتّبع المثال الذي نوفّره). أضِف ما يلي في أسفل الملف.

# Database model to represent a student submission.
class Submission(db.Model):
    # The attachmentId is the unique identifier for the attachment.
    submission_id = db.Column(db.String(120), primary_key=True)

    # The unique identifier for the student's submission.
    attachment_id = db.Column(db.String(120), primary_key=True)

    # The student's response to the question prompt.
    student_response = db.Column(db.String(120))

استورِد فئة Submission الجديدة إلى ملف الخادم الذي يتضمّن مسارات معالجة المرفقات.

تعديل مسار "عرض الطالب"

بعد ذلك، عدِّل مسار عرض الطالب السابق لعرض نموذج صغير وقبول الإدخالات من الطالب. يمكنك إعادة استخدام معظم الرمز من الإرشاد السابق.

حدِّد رمز الخادم الذي يوفّر المسار لـ "عرض الطالب". هذا هو المسار المحدّد في حقل studentViewUri عند إنشاء مرفق. التغيير الأول الذي يجب إجراؤه هو استخراج submissionId من الـ getAddOnContext ردّ.

Python

في المثال الذي نوفّره، يكون هذا في طريقة load_activity_attachment في ملف webapp/attachment_routes.py.

# Issue a request to the courseWork.getAddOnContext endpoint
addon_context_response = classroom_service.courses().courseWork(
).getAddOnContext(
    courseId=flask.session["courseId"],
    itemId=flask.session["itemId"]).execute()

# One of studentContext or teacherContext will be populated.
user_context = "student" if addon_context_response.get(
    "studentContext") else "teacher"

# If the user is a student...
if user_context == "student":
    # Extract the submissionId from the studentContext object.
    # This value is provided by Google Classroom.
    flask.session["submissionId"] = addon_context_response.get(
            "studentContext").get("submissionId")

قد تحتاج أيضًا إلى إرسال طلب للحصول على حالة عمل الطالب. يحتوي الردّ على قيمة SubmissionState، التي تشير إلى حالات مثل ما إذا كان الطالب قد فتح المرفق أو سلّمه. قد يكون ذلك مفيدًا إذا أردت منع إجراء تعديلات على عمل تم تسليمه، أو إذا كنت مهتمًا بتقديم إحصاءات للمعلّم حول تقدّم طلابه:

Python

في المثال الذي نوفّره، هذا هو استمرار لطريقة load_activity_attachment أعلاه.

# Issue a request to get the status of the student submission.
submission_response = classroom_service.courses().courseWork(
).addOnAttachments().studentSubmissions().get(
    courseId=flask.session["courseId"],
    itemId=flask.session["itemId"],
    attachmentId=flask.session["attachmentId"],
    submissionId=flask.session["submissionId"]).execute()

أخيرًا، استرجِع معلومات المرفق من قاعدة البيانات واعرض نموذج إدخال. يتألف النموذج في المثال الذي نوفّره من حقل إدخال سلسلة وزر إرسال. اعرض صورة المعلم واطلب من الطالب إدخال اسمه. بعد أن يقدّم الطالب ردًا، سجِّله في قاعدة البيانات.

Python

في المثال الذي نوفّره، هذا هو استمرار لطريقة load_activity_attachment أعلاه.

# Look up the attachment in the database.
attachment = Attachment.query.get(flask.session["attachmentId"])

message_str = f"I see that you're a {user_context}! "
message_str += (
    f"I've loaded the attachment with ID {attachment.attachment_id}. "
    if user_context == "teacher" else
    "Please complete the activity below.")

form = activity_form_builder()

if form.validate_on_submit():
    # Record the student's response in our database.

    # Check if the student has already submitted a response.
    # If so, update the response stored in the database.
    student_submission = Submission.query.get(flask.session["submissionId"])

    if student_submission is not None:
        student_submission.student_response = form.student_response.data
    else:
        # Store the student's response by the submission ID.
        new_submission = Submission(
            submission_id=flask.session["submissionId"],
            attachment_id=flask.session["attachmentId"],
            student_response=form.student_response.data)
        db.session.add(new_submission)

    db.session.commit()

    return flask.render_template(
        "acknowledge-submission.html",
        message="Your response has been recorded. You can close the " \
            "iframe now.",
        instructions="Please Turn In your assignment if you have " \
            "completed all tasks."
    )

# Show the activity.
return flask.render_template(
    "show-activity-attachment.html",
    message=message_str,
    image_filename=attachment.image_filename,
    image_caption=attachment.image_caption,
    user_context=user_context,
    form=form,
    responses=response_strings)

للتمييز بين المستخدمين، ننصحك بإيقاف وظيفة الإرسال وعرض الإجابة الصحيحة بدلاً من ذلك في "عرض المعلّم".

إضافة مسار لإطار iframe الخاص بـ "مراجعة عمل الطالب"

أخيرًا، أضِف مسارًا لعرض إطار iframe الخاص بـ "مراجعة عمل الطالب". يجب أن يتطابق اسم هذا المسار مع الاسم المقدَّم لـ studentWorkReviewUri عند إنشاء مرفق. يفتح هذا المسار عندما يعرض المعلّم عمل الطالب في واجهة مستخدم وضع الدرجات في Classroom.

تتلقّى مَعلمة طلب البحث submissionId عندما يفتح Classroom إطار iframe الخاص بـ "مراجعة عمل الطالب". استخدِمها لاسترجاع عمل الطالب من قاعدة البيانات المحلية:

Python

في المثال الذي نوفّره، يكون هذا في ملف webapp/attachment_routes.py.

@app.route("/view-submission")
def view_submission():
    """
    Render a student submission using the show-student-submission.html template.
    """

    # Save the query parameters passed to the iframe in the session, just as we did
    # in previous routes. Abbreviated here for readability.
    add_iframe_query_parameters_to_session(flask.request.args)

    # For the sake of brevity in this example, we'll skip the conditional logic
    # to see if we need to authorize the user as we have done in previous steps.
    # We can assume that the user that reaches this route is a teacher that has
    # already authorized and created an attachment using the add-on.

    # In production, we recommend fully validating the user's authorization at
    # this stage as well.

    # Look up the student's submission in our database.
    student_submission = Submission.query.get(flask.session["submissionId"])

    # Look up the attachment in the database.
    attachment = Attachment.query.get(student_submission.attachment_id)

    # Render the student's response alongside the correct answer.
    return flask.render_template(
        "show-student-submission.html",
        message=f"Loaded submission {student_submission.submission_id} for "\
            f"attachment {attachment.attachment_id}.",
        student_response=student_submission.student_response,
        correct_answer=attachment.image_caption)

اختبار الإضافة

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

أكمِل الخطوات التالية لاختبار مرفق النشاط:

  • سجِّل الدخول إلى Google Classroom بصفتك أحد مستخدمي الاختبار الطلاب في الصف نفسه الذي ينتمي إليه مستخدم الاختبار المعلّم.
  • انتقِل إلى علامة التبويب الواجب الدراسي ووسِّع الواجب التجريبي.
  • انقر على بطاقة مرفق الإضافة لفتح "عرض الطالب" وإرسال ردّ على النشاط.
  • أغلِق إطار iframe بعد إكمال النشاط. يمكنك اختياريًا النقر على الزر تسليم.

يجب ألا يظهر أي تغيير في Classroom بعد إكمال النشاط. اختبِر الآن إطار iframe الخاص بـ "مراجعة عمل الطالب":

  • سجِّل الدخول إلى Classroom بصفتك مستخدم الاختبار المعلّم.
  • ابحث عن عمود الواجب التجريبي في علامة التبويب الدرجات. انقر على اسم الواجب التجريبي.
  • ابحث عن بطاقة مستخدم الاختبار الطالب. انقر على المرفق في البطاقة.

تأكَّد من ظهور العمل الصحيح للطالب.

تهانينا! أنت مستعد للانتقال إلى الخطوة التالية: مزامنة درجات المرفقات.