From 09c351083c0baef275ff62a39fca9660771d7cd1 Mon Sep 17 00:00:00 2001 From: iu5git Date: Thu, 14 Nov 2024 14:33:04 +0300 Subject: [PATCH] arabic tutorials --- README.md | 4 +- tutorials/lab1-design/arabic.md | 521 +++++++++++++++++++++++++++++++ tutorials/lab1-py/arabic.md | 538 ++++++++++++++++++++++++++++++++ 3 files changed, 1061 insertions(+), 2 deletions(-) create mode 100644 tutorials/lab1-design/arabic.md create mode 100644 tutorials/lab1-py/arabic.md diff --git a/README.md b/README.md index 32ca57ac..20b1bfba 100644 --- a/README.md +++ b/README.md @@ -81,9 +81,9 @@ В приложении должны быть использованы стили, для каждого элемента списка подгружается свое изображение. Изображения `услуг` отображатся на всех трех страницах. Изображения хранятся в `Minio`, наименование изображение совпадает с id `услуги`, но хранится в модели отдельным полем. Разработать стиль приложения, который будет применяться далее в последующих лабораторных по фронтенду. `CSS` вынести в отдельный файл. -* [Методические указания](/tutorials/lab1-design/README.md) по верстке и дизайну Figma. [Видеоуроки](https://www.youtube.com/watch?v=DWicd2qo2pk) по Figma +* [Методические указания](/tutorials/lab1-design/README.md) по верстке и дизайну Figma [arabic Figma](/tutorials/lab1-design/arabic.md). [Видеоуроки](https://www.youtube.com/watch?v=DWicd2qo2pk) по Figma * [Инструкция по работе c Python](/tutorials/python/python.md) -* [Методические указания Django](/tutorials/lab1-py/lab1_tutorial.md) +* [Методические указания Django](/tutorials/lab1-py/lab1_tutorial.md) / [arabic Django](/tutorials/lab1-py/arabic.md) * [Методические указания Golang](/tutorials/lab1-go/README.md) * [Установка и администрирование Minio](https://github.com/iu5git/Networking/tree/main/S3) diff --git a/tutorials/lab1-design/arabic.md b/tutorials/lab1-design/arabic.md new file mode 100644 index 00000000..a459cad2 --- /dev/null +++ b/tutorials/lab1-design/arabic.md @@ -0,0 +1,521 @@ +# إرشادات منهجية لإنشاء التصميم في Figma والتنسيق باستخدام HTML و CSS + +## الخطة +1. [البدء باستخدام Figma](#البدء-باستخدام-figma) +2. [إنشاء إطار](#إنشاء-إطار) +3. [إنشاء بطاقة](#إنشاء-بطاقة) +4. [HTML](#html) +5. [CSS](#css) +6. [تنسيق صفحة البطاقات](#تنسيق-صفحة-البطاقات) +7. [تنسيق البطاقة](#تنسيق-البطاقة) + + +## البدء باستخدام Figma + +(فيجما) Figma هو محرر رسومي عبر الإنترنت للتصميم التعاوني. يُستخدم Figma بشكل أساسي لإنشاء نماذج أولية للمواقع والتطبيقات. +يمكنك العمل مع Figma عبر [الموقع الإلكتروني](https://www.figma.com/) أو [تطبيق سطح المكتب](https://www.figma.com/downloads/) (بالنقر على "Desktop app for macOS" +أو "Desktop app for Windows"). بعد ذلك، يجب تسجيل الدخول إلى الحساب أو إنشاء حساب جديد. + +بعد تسجيل الدخول، ستظهر الصفحة الرئيسية حيث تُعرض المشاريع في الوسط. على الجانب الأيسر توجد لوحة للتنقل إلى المشاريع الحديثة، المسودات، المفضلة، ومشاريع الفرق (يمكن إنشاء فرق للعمل على مشاريع مشتركة وتعديلها معًا). +![Alt text](assets/главная.png) + +لإنشاء مشروع، نضغط على "Drafts" في اللوحة اليسرى، ثم "Design file" في اللوحة العلوية.
+يمكن تقسيم الواجهة إلى أربع مناطق: +1. على اليسار - الطبقات +2. في الوسط - مساحة العمل +3. على اليمين - تحرير خصائص العناصر +4. في الأعلى - الأدوات + +![Alt text](assets/проект.png) + +## إنشاء إطار +الإطار هو العنصر الأساسي للتصميم في Figma. يُعد الإطار وثيقة مكتملة يمكن أن تكون صفحة لموقع ويب أو شاشة لتطبيق جوّال. يجمع الإطار العناصر المختلفة داخله. + + +![Alt video](assets/frame.gif) + +لإضافة لون إلى الصفحة، نضغط على الإطار، ثم ننتقل إلى علامة التبويب "Fill" في اللوحة اليمنى - وهي المسؤولة عن تعبئة اللون، ثم نضغط على المربع. يمكننا اختيار اللون باستخدام شريط التمرير أو إدخال رمز اللون يدويًا. + + +## إنشاء بطاقة +ستعرض البطاقة صورة، اسمًا، وصفًا مختصرًا، سعرًا، وزرًا للانتقال إلى صفحة وصف المنتج التفصيلية. +نحتاج إلى - 2 مستطيل، صورة، و3 كتل نصية. + +لإنشاء مستطيل، اختره من لوحة الأدوات أو اضغط على المفتاح R، ثم أنشئ مستطيلًا بحجم عشوائي في مساحة العمل أثناء الضغط على زر الفأرة الأيسر. +في علامة التبويب الخاصة بالمستطيل، يمكنك اختيار خط، سهم، شكل بيضاوي، مضلع، نجمة، أو صورة. + +![Alt video](assets/квадрат.gif) +سننشئ مستطيلًا آخر، ونضيف صورة وعناصر نصية. عند إنشاء عناصر داخل الإطار، يتم إنشاؤها تلقائيًا في لوحة الطبقات داخل هذا الإطار. + + + +### خصائص العناصر +يتم ضبط خصائص العناصر في اللوحة اليمنى. + +خصائص النص: +1. **الخط**. يمكنك اختيار الخط من موقع [Google Fonts](https://fonts.google.com/). اضغط على Filters <- Language. اختر Cyrillic لاختيار خط يدعم اللغة الروسية. +
+2. النمط - اجعل الوصف المختصر وزر الضغط بخط Medium، والعنوان والسعر بخط SemiBold.
+3. الحجم - عادةً ما تكون أحجام النصوص على المواقع 14px، لذا سنجعل الوصف المختصر والزر بهذا الحجم، بينما سيكون حجم العنوان والسعر 16px، ليتميزوا عن باقي النصوص. +
+ + +نختار عنصر النص، في علامة التبويب Text نضغط على اسم الخط، ثم نبحث عن الخط المطلوب، ونقوم بتعيين النمط وحجم الخط أدناه. إذا قمت بالنقر على الثلاث نقاط، ستظهر جميع إعدادات الخط.
+ + + +سنجري نفس الشيء على عناصر النص الأخرى. + +خصائص العناصر الهندسية: +1. **اللون**. نحن نعرف كيفية القيام بذلك بالفعل. +2. **تدوير الزوايا**. +لنستعرض معًا إعدادات هذه العلامة: X و Y - إحداثيات العنصر داخل الإطار، W و H - العرض والارتفاع، رمز الزاوية - زاوية دوران العنصر، وتدوير الزوايا.
+سنقوم بتدوير الزوايا للبطاقة والصورة بمقدار 20px، بينما ستكون الزوايا في الزر بمقدار 10px. + + + +3. **الإطار**. سنضيف إطارًا للزر ونتخلص من التعبئة. +لذلك، في قسم Stroke نضغط على "+", وسنضيف إطارًا. يمكننا ضبط اللون، السماكة، والجهات التي نريد إضافة الإطار لها. في قسم Fill، نضغط على "-" لإزالة اللون. + +**خصائص الصورة:**
+لتغيير الحجم، يجب سحب حدود الصورة، مع الضغط على مفتاح Shift لتغيير الأبعاد بشكل متناسب.
+إذا كنت بحاجة إلى قص الصورة، انتقل إلى علامة التبويب Fill واضغط على الصورة. في النافذة التي ستظهر، ستجد قائمة منسدلة فوق الصورة، اختر منها Crop وقم بتغيير الحدود. إذا كنت ترغب في استبدال الصورة، قم بالتحريك على الصورة في هذه النافذة، وستظهر لك زر "Choose image".
+ + + +### تنسيق عناصر البطاقة و Auto Layout +لقد أعددنا جميع العناصر، والآن سنقوم بتنسيقها.
+أولاً، دعنا نجمع الزر. اختر المستطيل والنص الخاص بالزر مع الضغط على مفتاح Shift، في اللوحة اليمنى في أول علامة تبويب، يمكنك ضبط المحاذاة. نحتاج إلى محاذاة العناصر بالنسبة لبعضها البعض عموديًا وأفقيًا، اضغط على الأيقونتين 2 و 5، ثم اضغط على Ctrl+G (لتجميع العناصر). + +[رابط الصورة](https://github.com/ssofiica/Design-tutorial/assets/91909561/60044485-36dd-43af-821f-07cb02d2d0b8) + + + +الآن سنقوم بتجميع البطاقة، وننقل العناصر إلى المستطيل الذي يشكل خلفية البطاقة، ونقوم بمحاذاة العناصر، ونجعل السعر والزر في نفس المستوى ثم نقوم بتجميعها. إذا كانت عدة عناصر مجمعة، فعند النقر مرة واحدة على عنصر، سيتم تحديد المجموعة بأكملها، لذلك يجب النقر مرتين على العنصر لتحديده فقط. + +في Figma، هناك أداة تُعرف باسم Auto Layout. هذه الأداة تسمح بإنشاء حاويات يمكن أن تحتوي على عناصر واجهة مستخدم أخرى، ثم يمكن ضبط قواعد الترتيب، مثل المحاذاة أو المسافة بين العناصر. يمكن مقارنة Auto Layout بـ flex في CSS. +نحدد جميع عناصر البطاقة، بما في ذلك الخلفية، وفي اللوحة اليمنى نجد علامة التبويب Auto Layout، ونضغط على الزر الإضافي. + +
+نختار الترتيب العمودي، والpadding الداخلي 20px، والمسافة بين العناصر 10px.
+نقوم بنسخ البطاقة وتغيير المحتوى. +
+ +النتيجة: + + +## صفحة التفاصيل + +سنجعل الصورة والوصف في كتل منفصلة. + +## HTML + +تعريف لغه (HTML) - هي لغة ترميز تُستخدم لتحديد هيكل صفحات الويب التي يزورها المستخدمون. تتكون HTML من مجموعة من العناصر التي تستخدمها لتغطية أو لف أو وضع علامات على أجزاء مختلفة من المحتوى، بحيث يكون له مظهر محدد أو يعمل بطريقة معينة. + +العنصر = علامة بداية + المحتوى + علامة نهاية
+```

Hello world!

``` + +علامة البداية: تتكون من اسم (تسمية) العلامة، الموضوعة داخل أقواس الزاوية. تعمل هذه العلامة كمؤشر لبداية العنصر، ومن هذه اللحظة تؤثر العلامة على المحتوى الذي يليها
+علامة النهاية: تبدو مثل علامة البداية، ولكنها تحتوي على شريط مائل قبل اسم العلامة
+المحتوى: يشمل نصًا أو عناصر أخرى
+ +دعونا نلقي نظرة على العلامات التي نحتاجها: + +
+ +
  • <div>..</div>. يستخدم لتنظيم المحتوى على صفحة الويب ووضع المحتوى في كتل منفصلة. ينشئ عنصر div كتلة تمتد بشكل افتراضي عبر عرض المتصفح بالكامل، ويتم نقل العنصر التالي إلى سطر جديد.
  • +
  • <p>..</p>. يمثل فقرة نصية، ويُستخدم للفصل بين كتل النصوص بمسافات أو خطوط فارغة.
  • +
  • <h1-6>..</h1-6>. يمثل ستة مستويات من العناوين للأقسام. <h1> هو أعلى مستوى، و<h6> هو الأدنى. بشكل افتراضي، تبدأ عناوين العناصر في سطر جديد وتحتل كامل العرض المتاح في الكتلة المحتوية.
  • +
  • <img/>. يضيف صورة. السمة src ضرورية وتحتوي على مسار الصورة (سواء كان مسار ملف أو رابط من الإنترنت)، وتحتوي السمة alt على النص البديل. محركات البحث تستخدم النص البديل لفهرسة الصورة، وإذا كان هناك مشكلة في عرض الصورة، يظهر النص البديل. يمكن تعديل إعدادات الصورة من خلال css.
    + مثال: <img src="./img/sun.png" alt="Картинка солнца"/>
  • +
  • <a>..</a>. يُستخدم مع السمة href لإنشاء رابط تشعبي إلى صفحات ويب، ملفات، عناوين بريد إلكتروني، مواقع داخل نفس الصفحة، أو أي عنصر يمكن الوصول إليه عبر URL.
  • + +
    + + + +لمزيد من المعلومات حول [العلامات](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/). + +## CSS +تعريف لغه (CSS) (؛Cascading Style Sheets؛) - هي لغة جداول الأنماط، لغة لوصف مظهر صفحة الويب. +من خلال HTML نقوم بإنشاء العناصر، ومن خلال CSS نقوم بتعيين الخصائص لها. +لنفترض أننا أنشأنا تخطيطًا باستخدام HTML. الآن نريد أن نجعل مظهر الصفحة جميلاً، لذلك نحتاج إلى وصف كيف يجب أن يبدو كل عنصر. لهذا، يجب وصف مجموعة من قواعد تنسيق العنصر أو ببساطة النمط. + +مجموعة القواعد = محدد {خاصية: قيمة;} + +```css +div { + background: #EFEFEF; +} +``` +### CSS + +**المحددات** - اسم العنصر الذي سيتم تعيين نمط له +**الخصائص** - ما نريد تغييره +**القيمة** - واحدة من المضاهر الممكنة للخاصية + +### المحددات + +| نوع المحدد | css | html | يحدد القواعد ل | +|------------------|---------------------------------------|-------------------------------------------------|-----------------------------------------------------------------------------------------------------------| +| عنصر | p {
    color: #ffffff;
    } | ```

    ``` | لجميع عناصر p | +| معرف | #my-id {
    color: #ffffff;
    } | ```

    ``` | العنصر الذي يحمل هذا المعرف. يجب أن تكون كل قيمة معرف فريدة في الصفحة | +| فئة | .title {
    color: #ffffff;
    } | ```

    ``` | لجميع العناصر التي تحمل الفئة المحددة. يمكن أن يكون هناك عدة أمثلة للفئة في الصفحة | +| فئة زائفة | p:hover {
    color: #252525;
    } | ```

    ``` | العنصر المحدد في الحالة المحددة. في هذا المثال ```

    ```، يغير اللون عند تمرير الماوس | + + +### الخصائص + +يوجد عدد هائل من الخصائص وقيمها، دعونا نستعرض جزءًا صغيرًا منها، والتي لا يمكن الاستغناء عنها، يمكنك دراسة الباقي عند الحاجة. + + +### 1. الأحجام والمسافات + +

    +width - يحدد عرض العنصر. يمكن تحديده بوحدات البكسل (px)، النسب المئوية (%)، em، rem، vw، vh (مزيد من التفاصيل أدناه).
    +height - يحدد ارتفاع العنصر.
    +border - إطار حول العنصر. يمكن تخصيص سمك الإطار، نوعه ولونه. مثال: `border: 1px solid black`.
    +border-radius - يجعل زوايا العنصر مستديرة ويحدد ذلك بوحدات البكسل أو النسب المئوية بالنسبة لحجم العنصر.
    +margin - حجم المسافة الخارجية حول العنصر، يُحدد بوحدات px، %، auto، وغيرها.
    +padding - حجم المسافة الداخلية داخل العنصر، يُحدد بوحدات px، %، auto، وغيرها.
    +
    + + + + + + +### كيف تحدد الهوامش (margin) والهوامش الداخلية (padding)؟ + +1. اللاحقات: top, right, left, bottom. على سبيل المثال: { margin-top: 10px; padding-left: 2%; } +2. عدد القيم: + + + + + + + + +### 2. وضع العلامات +
    +display - عرض العناصر.
    +القيم:
    +- block - يبدأ العنصر بسطر جديد ويشغل كامل عرض الحاوية.
    +- inline - يتم وضع العنصر داخل العنصر الأب ولا يشغل سطرًا منفصلًا.
    +- none - العنصر لا يظهر.
    +- grid - يظهر العنصر في شكل شبكة.
    +- flex - مرن.
    +
    + + +
    +

    +display: flex +
    + +الفكرة الأساسية - توزيع مرن للمساحة بين العناصر، ترتيب مرن، محاذاة، وإدارة مرنة. + + + + +### الخصائص التي سنستخدمها: +
    +- justify-content - محاذاة العناصر داخل الحاوية على المحور الرئيسي.
    +- flex-direction - اتجاه ترتيب العناصر (في صف، في عمود، وما إلى ذلك).
    +- align-items - محاذاة العناصر داخل الحاوية على المحور العرضي.
    +
    + + +تستخدم هذه الخصائص فقط عند تحديد ```{ display: flex; }```. + +مثال: +```css +.container{ + display: flex; +/* العناصر مرتبة في عمود */ + flex-direction: column; +/* الفواصل متساوية بين العناصر */ + justify-content: space-between; +} +``` +### المزيد عن [القيم](https://doka.guide/css/flexbox-guide/) لهذه الخصائص. + +
    +display: grid +
    + +### الشبكة (Grid) + +على عكس حاوية الفليكس التي تعمل بعدد واحد فقط من الأبعاد، تتيح الشبكات (grids) العمل مع بعدين في وقت واحد: الأفقي والعمودي. يمكنك دمج خلايا فردية، وتغيير أحجام الصفوف والأعمدة، وضبط الهوامش بينها. + +### الخصائص التي سنستخدمها: +
    - grid-template-columns و grid-template-rows - +تحدد أبعاد وعدد الأعمدة أو الصفوف في الشبكة. +
    + +```css +.container { + display: grid; +/* سيتم إنشاء 3 أعمدة */ + grid-template-columns: 150px auto 40%; +/* سيتم إنشاء صفين */ + grid-template-rows: 200px 250px; +} +``` +إذا كنت بحاجة إلى أعمدة أو صفوف متساوية، يمكنك استخدام دالة `repeat()`. بالنسبة للشبكة، هناك وحدة قياس خاصة بها وهي `fr`، التي تُحسب تلقائيًا. + +```css +grid-template-columns: repeat(3, 1fr) /* ثلاثة أعمدة، كل منها سيشغل 1/3 من عرض العنصر الأب */ +grid-template-columns: repeat(3, 250px); /* ثلاثة أعمدة بارتفاع 250 بكسل */ +``` + +
    +gap - يحدد المسافات الفاصلة. القيمة الأولى هي المسافات بين الصفوف، والقيمة الثانية هي المسافات بين الأعمدة. + gap: 50px 20px; +
    + + +لمزيد من المعلومات حول [الشبكة](https://doka.guide/css/grid-guide/). + +### 3. النص واللون + +
    +background-color - لون خلفية العنصر
    +color - لون النص
    +font-family - خط النص
    +font-size - حجم الخط
    +font-weight - نمط الخط
    +text-align - محاذاة النص داخل العنصر
    +
    + + + +### 4. الصور +
    +background-image - صورة الخلفية
    +object-fit - تغيير حجم الصورة وتحديد مكانها داخل الحاوية
    +
    + + +## وحدات القياس: + +
    +- em — تعادل حجم خط العنصر الأب. إذا كان حجم خط الأب يساوي 16px، فإن 1em سيكون مساويًا 16px. هذا مفيد عندما تحتاج إلى أن يتغير العنصر مع حجم خط الأب.
    +- rem — تعادل حجم خط العنصر الجذري (html). هذا مفيد لتلك العناصر التي يجب أن ترتبط بحجم خط html، بدلاً من حجم خط أب معين.
    +- vw و vh تُستخدم لتعيين الأحجام كنسب مئوية من عرض أو ارتفاع نافذة المتصفح. إنها مفيدة لإنشاء تصميمات مرنة تتكيف مع أحجام الشاشات المختلفة. 1vw يساوي 1% من عرض نافذة المتصفح، و 1vh يساوي 1% من ارتفاع النافذة. +
    + + + +## تصميم صفحة مع بطاقات + + + +أولاً، سنقوم بإنشاء التخطيط، ثم سنقوم بكتابة الأنماط. +نقوم بإنشاء ملف `index.html` و `style.css`، ونكتب في `index.html`. + + +```html + + + + + + + Магазин + + + +
    +
    +
    +
    + + +``` +داخل عنصر `body`، سنقوم بإنشاء `div` باسم `space`، والذي سنقوم بترتيب عناصر الصفحة داخله. تم تقسيم الصفحة إلى جزئين: الرأس والحاوية. يمكنك إضافة اسم الشركة، وشريط التنقل في الرأس. ستكون البطاقات داخل الحاوية. + +**ملف style.css** + +عند إنشاء البطاقة في Figma، كان من الضروري اختيار خط من موقع [Google Fonts](https://fonts.google.com/). الآن على صفحة الخط، يجب الضغط على "Get Font" -> "Get embed code" -> التبديل إلى `@import` -> نسخ الكود. نضيف هذا `import` في بداية ملف `style.css`. + +![Alt video](assets/шрифт.gif) + +```css +@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap'); +*{ + margin: 0; + padding: 0; + font-family: 'Montserrat', sans-serif; + color: #000000; +} +body{ + background: #EFEFEF; +} +.space{ + width: 80%; + margin-left: auto; + margin-right: auto; +} +`` +ماذا فعلنا من خلال الأنماط؟ +- قمنا بتعيين خلفية للصفحة بالكامل +- الحاوية التي تحتوي على جميع العناصر تشكل 80% من عرض الشاشة ومركزة في المنتصف بسبب ذلك + + +**أنماط الحاوية** +دع البطاقات تتوزع بواقع 4 بطاقات في الصف والمسافة بينها 20 بكسل. + +```css +.container{ + display: grid; + grid-template-columns: repeat(4,1fr); + gap: 20px; +} +``` + +## تصميم البطاقة + +تتكون البطاقة من صورة، عنوان، وصف، سعر وزر. سنستخدم ```div class="card"``` الذي يجمع جميع العناصر معًا.
    +سنضيف ذلك داخل فئة الحاوية + +```html +
    + +

    LA ROCHE-POSAY effaclar

    +

    Крем-гель для проблемной кожи

    +

    1348 ₽

    + Подробнее +
    +``` +الآن لدينا على الصفحة صورة بسيطة وعناصر نصية. + +### الأنماط + +**أنماط للخلفية**
    +في Figma، نرى ما هي خصائص خلفية البطاقة: +- لون الخلفية - #FFFAFA +- تقوس الحواف - 20px +- الحشوة الداخلية 20px، ولكن دعنا نجعلها كنسبة مئوية - 10% + +```css +.card{ + border-radius: 20px; + background-color: #FFFAFA; + padding: 10%; + display: flex; + flex-direction: column; + justify-content: space-between; +} +``` +لكي تتغير أبعاد البطاقة مع المحتوى ويمكننا التحكم في ترتيب العناصر، سنجعلها حاوية فليكس، يجب أن تكون العناصر في عمود مع مسافة متساوية بينها. + + +**أنماط الصورة**
    +سنأخذ الارتفاع والتدوير من فيغما. +خاصية **object-fit** - تتحكم في تغيير حجم الصورة وترتيبها
    +القيم: +
    +- cover - يتم تغيير حجم الصورة بحيث تملأ العنصر الأب بالكامل، مع الحفاظ على النسب، ولكن كل ما لا يتناسب مع حجم العنصر سيتم قصه
    +- contain - يتم تغيير حجم الصورة بشكل متناسب لتناسب تمامًا داخل العنصر الأب، في هذه الحالة قد تحتوي الصورة على مناطق فارغة على الجوانب أو من الأعلى أو من الأسفل
    +- fill - تملأ الصورة المساحة المتاحة بالكامل للعنصر، وقد تتشوه نسبها
    +- none - ستظهر الصورة بأحجامها الطبيعية، متجاهلة أحجام العنصر الأب
    +- scale-down — هذه القيمة تحدد تلقائيًا وتختار القيمة الأنسب بين none و contain، أي إذا كانت أبعاد الصورة أكبر من أبعاد العنصر الأب، فسيتصرف scale-down مثل contain، وإلا فسيتصرف مثل none +
    +**** + +```css +.image{ + width: 100%; + height: 211px; + border-radius: 20px; + object-fit: cover; +} +``` +ستشغل الصورة 100% من العرض المتاح لها، حيث أن البطاقة تحتوي على padding بنسبة 10%، وبالتالي ستملأ الصورة 80% من عرض البطاقة وستكون في المنتصف. + + + + +**أنماط العنوان**
    +حجم الخط - 16px، النمط - bold (يمكن أيضًا تحديده بالأرقام، bold - 700). دعونا نضيف أيضًا هامشًا من الأعلى بمقدار 16px. + +```css +.title{ + margin-top: 16px; + font-size: 16px; + font-weight: bold; +} +``` + +**أنماط الوصف**
    +حجم الخط - 14px، النمط - Medium، دعونا نضيف هامشًا من الأعلى والأسفل بمقدار 10px، وأن يكون النص مليئًا بعرض 100% من المساحة المتاحة له. + +```css +.short-description{ + font-size: 14px; + font-weight: 500; + width: 100%; + margin-top: 10px; + margin-bottom: 10px; +} +``` + +**أنماط الزر**
    +يتم تعيين خط تحت نص الروابط بشكل افتراضي، ويمكن إزالته باستخدام ```text-decoration: none;``` +بالنسبة لـ padding، يتم تحديد قيمتين، فلنتذكر أن القيمة الأولى هي للهامش العلوي والسفلي، والثانية هي للهامش الأيمن والأيسر. + +```css +.card-button{ + padding: 8px 10px; + border-radius: 10px; + border: 1px solid #000000; + text-decoration: none; + font-size: 14px; + font-weight: 500; +} +``` +دعونا نرى ما حصلنا عليه:
    + + +الآن سنجمع الصورة والعنوان والوصف في div واحد، والسعر والزر في div آخر. + +```html +
    +
    + +

    LA ROCHE-POSAY nutritic intense riche

    +

    Питательный крем для глубокого восстановления сухой кожи

    +
    +
    +

    1915 ₽

    + Подробнее +
    +
    +``` + +سنكتب نمطًا لعنصر ```down``` بحيث يتم وضع السعر والزر في صف واحد، ويكون السعر على الحافة اليسرى، والزر على الحافة اليمنى. للقيام بذلك، سنجعل ```down``` حاوية مرنة وسنقوم بتعيين ```justify-content: space-between;```، بينما يتحكم ```align-items``` في المحاذاة.
    +لتحديد كعلامة داخل الفئة، يمكنك القيام بذلك على النحو التالي: ```.<اسم الفئة> <اسم العلامة>```. بالنسبة للسعر، نقوم بتحديد حجم الخط والأسلوب. + +```css +.down{ + display: flex; + justify-content: space-between; + align-items: center; +} +.down p{ + font-size: 16px; + font-weight: 700; +} +``` +في النهاية نحصل على بطاقة مثل هذه + + +بعد إضافة المزيد من البطاقات واسم الشركة في الرأس، أصبح الشكل كالتالي: + diff --git a/tutorials/lab1-py/arabic.md b/tutorials/lab1-py/arabic.md new file mode 100644 index 00000000..1111271e --- /dev/null +++ b/tutorials/lab1-py/arabic.md @@ -0,0 +1,538 @@ + +# الإرشادات المنهجية لتنفيذ العمل المخبري رقم 1 + +لتنفيذ هذا العمل المخبري، ستحتاج إلى [VS Code](https://code.visualstudio.com) أو [PyCharm Professional](https://www.jetbrains.com/pycharm/download/). + +## إنشاء المشروع محليًا +مثال لـ PyCharm: +اذهب إلى New Project -> File +في قائمة ...،New Project +اختر Django، ثم حدد مسار المشروع في Location +وأدخل اسم التطبيق في Application name. + +![إنشاء المشروع](assets/1.png) + +## إنشاء المشروع على الجهاز الافتراضي (عن بُعد) +للاتصال بالجهاز الافتراضي وإنشاء المشروع عليه، اتبع الخطوات التالية: +- افتح VS Code وثبت إضافة **Remote Development**. + +![الاتصال بالمضيف البعيد](assets/14.png) + +**ملاحظة: في هذه الخطوة، يجب أن يكون الجهاز الافتراضي مشغلاً بالفعل!** +- بعد تثبيت الإضافة، سيظهر رمز في الزاوية السفلية اليسرى، اضغط عليه. + +![الاتصال بالمضيف البعيد](assets/15.png) + +- اختر **...Connect to Host** + +### كيفية معرفة IP الجهاز الافتراضي +أدخل الأمر **ifconfig** على الجهاز الافتراضي، وابحث عن واجهة ،Ethernet في هذه الحالة - enp0s3، وراجع IP في السطر الثاني مقابل .inet يرجى ملاحظة أن نوع الاتصال في إعدادات "الشبكة" للجهاز الافتراضي يجب أن يكون مضبوطاً على "الجسر الشبكي" (Bridge Network). + +![IP](assets/27.png) + +![نوع الاتصال](assets/16.png) + +- ستكون صيغة الاتصال كالتالي - **user_name@remote_host_ip** + +![صيغة الاتصال](assets/17.png) + +- في الخطوة التالية، حدد المكان الذي سيتم وضع مشروعك فيه. يُفضل إنشاء دليل مخصص للمشاريع، على سبيل المثال **pythonProjects**. + +![دليل المشاريع](assets/18.png) + +- اضغط على **OK** وأدخل كلمة المرور. +- إذا تم الاتصال بنجاح، ستظهر النتيجة التالية: + +![اتصال ناجح](assets/19.png) + +### إنشاء مشروع Django +- أنشئ مجلدًا بالاسم المطلوب للمشروع وانتقل إليه. + +![إنشاء مجلد للمشروع](assets/20.png) + +- أنشئ بيئة افتراضية باستخدام أداة **venv** وقم بتفعيلها. + +![بيئة افتراضية](assets/21.png) + +- بعد تفعيل البيئة الافتراضية، قم بتثبيت Django (في وقت كتابة هذا الدليل، النسخة المتاحة هي 4.2.4). + +![تثبيت Django](assets/22.png) + +- أنشئ المشروع باستخدام الأمر ` .` + +![إنشاء مشروع Django](assets/23.png) + +- بعد إنشاء المشروع، انتقل إلى ملف **settings.py** وأضف علامة النجمة **\*** إلى **ALLOWED_HOSTS**. + +![](assets/24.png) + +- شغّل المشروع باستخدام الأمر `python manage.py runserver 0.0.0.0:8000` **ملاحظة:** لتكون الخدمة متاحة من النظام الأساسي، يجب تشغيلها على عنوان البث **0.0.0.0**. يمكن أن يكون المنفذ أي رقم، وفي هذه الحالة هو 8000. + +![](assets/25.png) + +- أجرِ طلبًا من النظام الأساسي، وذلك بإدخال عنوان الجهاز الافتراضي + المنفذ الذي حددته عند تشغيل المشروع في المتصفح. + +![](assets/26.png) + +باقي العمل يُنفذ بنفس الطريقة كما في الجهاز الأساسي. + + +هيكل المشروع +في مجلد المشروع bmstu: +
    + settings.py - إعدادات المشروع، ويمكن أن يحتوي المشروع على عدة تطبيقات. +
    +
    + urls.py - توجيه الروابط إلى المعالجات (views). +
    + + + +في المجلد bmstu_lab: +
    + views - معالجة التطبيق +
    +
    + templates - مجلد القوالب (ملفات HTML). +
    + + + +![هيكل المشروع](assets/2.png) + +تشغيل التطبيق +اضغط على زر Run في القائمة اليمنى لتشغيل التطبيق. + + +![تشغيل](assets/3.png) + +في هذه الحالة، يجب أن تعرض وحدة التحكم سجل تتبع حول التطبيق الذي يعمل على **localhost** على المنفذ **:8000** +![وحدة التحكم](assets/4.png) + +يجب أن تظهر الصفحة القياسية لتطبيق Django في المتصفح على العنوان `http://127.0.0.1:8000/`. + +![المتصفح](assets/5.png) + +## كيفية العمل مع View وUrls +`views.py` +```python +from django.http import HttpResponse + +def hello(request): + return HttpResponse('Hello world!') +``` + +`urls.py` +```python +from bmstu_lab import views + +urlpatterns = [ + path('admin/', admin.site.urls), + path('hello/', views.hello), +] +``` + +بعد تشغيل الخادم على المسار `http://127.0.0.1:8000/hello/` يجب أن ترى + +![مرحبا بالعالم!](assets/6.png) + +وبالتالي، سيتم استدعاء كود **hello** عند الوصول إلى الخادم عبر URL **/hello**. + +## القوالب + +القالب هو ملف نصي عادي، وغالبًا ما يكون بتنسيق HTML، يحتوي على متغيرات وعلامات. +يتم استبدال هذه التركيبات أثناء عرض القالب بالبيانات التي يقدمها المستخدم كمعلمات للقالب. +في النهاية، نحصل على ملف HTML يمكن عرضه في متصفح المستخدم. + +للشروع، سنقوم بتقديم صفحة HTML ثابتة للمستخدم، ولن تحتوي على أي تركيبات من نظام القوالب. + +لننشئ ملف HTML في الدليل ‘templates’. + + +`index.html` +```html + + + + + BMSTU + + + Hello BMSTU students! + + +``` + +لإرشاد Django إلى مكان البحث عن القوالب، تحقق من ملف settings.py. يجب أن يحتوي الحقل DIRS داخل المتغير TEMPLATES على المسار المؤدي إلى قوالبك. + + + + + + + +```python +TEMPLATES = [ + { + # ... + "DIRS": [BASE_DIR / "bmstu_lab/templates"], + # ... + }, +] +``` + +لإرجاع الملف الذي تم إنشاؤه للمستخدم، استخدم طريقة `render`. +على سبيل المثال، يُرجع هذا الكود الصفحة `index.html`، التي تم إنشاؤها في مجلد `templates`. + + +`views.py` +```python +from django.shortcuts import render + +def hello(request): + return render(request, 'index.html') +``` + +بعد تشغيل الخادم على المسار `http://127.0.0.1:8000/hello/` يجب أن ترى + +![Привет студенты!](assets/7.png) + +## المتغيرات في القوالب + +في القالب، يظهر المتغير بالشكل: `{{ some_variable }}`. +عندما يقوم نظام القوالب بعرض الصفحة ويعثر على متغير، +فإنه يستبدله بالنتيجة التي يتم حسابها في هذا المتغير. + +لنقم بإضافة متغيرات إلى الصفحة الثابتة. + +`index.html` +```html + + + + + BMSTU + + + Hello BMSTU students! + Today is {{ current_date }} + + +``` + +لتمرير قيمة المتغير من الكود: + +`views.py` +```python +from datetime import date + +def hello(request): + return render(request, 'index.html', { + 'current_date': date.today() + }) +``` + +إذا لم يتم تمرير قيمة المتغير، فسيتم استبداله بسلسلة فارغة. +لا يمكن أن تحتوي أسماء المتغيرات على مسافات أو علامات ترقيم. + +بعد تشغيل الخادم على المسار `http://127.0.0.1:8000/hello/` يجب أن ترى + + +![Привет студенты!](assets/8.png) + +يمكن أن يكون المتغير قاموسًا، وبالتالي يمكن الوصول إلى الحقول الفرعية عبر النقطة. + + +```python +def hello(request): + return render(request, 'index.html', { 'data' : {'current_date': date.today()}}) +``` + +```python + Today is {{ data.current_date }} +``` + +## العلامات في القوالب + +في القالب، تبدو العلامات بالشكل `{% tag %}`. +باستخدام العلامات، يمكنك تنفيذ الشروط، والحلقات، ومنطقك الخاص. يجب أن يتم إغلاق معظم العلامات: +`{% tag %} المحتوى {% endtag %}` + +افترض أننا بحاجة إلى عرض قائمة بالعناصر. للقيام بذلك، سنستخدم `{% for %}` + + +`index.html` +```html + + + + + BMSTU + + + Hello BMSTU students! + Today is {{ data.current_date }} +
      + {% for var in data.list %} +
    • We like {{ var }}
    • + {% endfor %} +
    + + +``` + +`views.py` +```python +from datetime import date + +def hello(request): + return render(request, 'index.html', { 'data' : { + 'current_date': date.today(), + 'list': ['python', 'django', 'html'] + }}) +``` + +بعد تشغيل الخادم على المسار `http://127.0.0.1:8000/hello/` يجب أن ترى + + +![Привет студенты!](assets/9.png) +
    + For تقوم بتكرار القائمة، ويمكن الوصول إلى العناصر من خلال المتغير المُنشأ، في هذه الحالة var. +
    + + + + + +`{% if variable %}` يتيح لك عرض محتوى الكتلة إذا كانت قيمة المتغير "صحيحة" (أو إذا كانت القيمة موجودة، أو إذا كانت القائمة غير فارغة). +يمكن استخدام `{% elif %}` و`{% else %}` مع هذه العلامة. + + +`index.html` +```html +
      + {% for var in data.list %} + {% if var == 'python' %} +
    • We like {{ var }}
    • + {% elif var == 'django' %} +
    • We like {{ var }} a lot!
    • + {% else %} +
    • We do not like {{ var }}
    • + {% endif %} + {% endfor %} +
    +``` + +بعد تشغيل الخادم على المسار `http://127.0.0.1:8000/hello/` يجب أن ترى + +![Привет студенты!](assets/10.png) + + في علامة **if** يمكن استخدام: +
    +- and +
    +
    + - or +
    +
    + - not +
    + +-مشغلات المقارنة +
    +- in (للتحقق مما إذا كانت القيمة موجودة في القائمة) +
    + + +## وراثة القوالب + +تسمح وراثة القوالب بإنشاء قالب أساسي يحتوي على العناصر المشتركة، +بينما ستقوم القوالب الفرعية بتجاوز الأماكن المحددة. +تُحدد الأماكن التي يمكن تجاوزها بعلامات `{% block %}`. + +افترض أن هناك قالبًا أساسيًا باسم `base.html`: + +`base.html` +```html + + + + + {% block title %}{% endblock %} + + + Hello BMSTU students! + {% block content %}{% endblock %} + + +``` +هنا يتم تحديد الجزء الذي سيكون موجودًا في كل صفحة ترث منه. +سنقوم بإنشاء قالب فرعي باسم `orders.html` الذي سيعرض قائمة الطلبات: + +`orders.html` +```html +{% extends 'base.html' %} + +{% block title %}Список заказов{% endblock %} + +{% block content %} +
      + {% for order in data.orders %} +
    • {{ order.title }}
    • + {% empty %} +
    • Список пуст
    • + {% endfor %} +
    +{% endblock %} +``` + +`views.py` +```python +def GetOrders(request): + return render(request, 'orders.html', {'data' : { + 'current_date': date.today(), + 'orders': [ + {'title': 'Книга с картинками', 'id': 1}, + {'title': 'Бутылка с водой', 'id': 2}, + {'title': 'Коврик для мышки', 'id': 3}, + ] + }}) +``` + +لدى كل منتج، أضفنا رابطًا إلى صفحته الفردية بصيغة `{% url 'order_url' order.id %}`. + +في ملف `urls.py`، يجب تحديد URL باسم 'order_url' الذي سيستقبل معرف الطلب: + + +`urls.py` +```python +urlpatterns = [ + path('admin/', admin.site.urls), + path('', views.GetOrders), + path('order//', views.GetOrder, name='order_url'), +] +``` + +سنقوم بإنشاء قالب لصفحة المنتج `order.html` وعرضها. + +`order.html` +```html +{% extends 'base.html' %} + +{% block title %}Заказ №{{ data.id }}{% endblock %} + +{% block content %} +
    Информация о заказе №{{ data.id }}
    +{% endblock %} +``` + +`views.py` +```python +def GetOrder(request, id): + return render(request, 'order.html', {'data' : { + 'current_date': date.today(), + 'id': id + }}) +``` + +بعد تشغيل الخادم على المسار `http://127.0.0.1:8000/` يجب أن ترى + +![Привет студенты!](assets/11.png) + +على المسار `http://127.0.0.1:8000/order/2` يجب أن ترى + +![Привет студенты!](assets/12.png) + +## Include في القوالب + +يسمح بعرض قالب آخر في مكان استخدام العلامة. + +`orders.html` +```html +{% extends 'base.html' %} + +{% block title %}Список заказов{% endblock %} + +{% block content %} +
      + {% for order in data.orders %} + {% include 'order_element.html' with element=order %} + {% empty %} +
    • Список пуст
    • + {% endfor %} +
    +{% endblock %} +``` + +`order_element.html` +```html +
  • {{ element.title }}
  • +``` +
    +with يسمح بتغيير السياق. أي في قالب order_element.html، لن يكون الوصول متاحاً فقط لـ order وorders، ولكن أيضًا لـ element. +
    + +## إضافة الملفات الثابتة + +في `settings.py`، يتم تحديد المسار إلى الملفات الثابتة. + +```python +STATIC_URL = '/bmstu_lab/static/' +``` + +```python +STATICFILES_DIRS = [ + BASE_DIR / "static", +] +``` + +في التطبيق، نقوم بإنشاء مجلد ونضع فيه الملفات: + +![Привет студенты!](assets/13.png) + +نضع ملفات `.css` في مجلد منفصل `static/css`. + +قبل استخدام الرابط إلى ملف ثابت، في القالب: + +```html +{% load static %} +``` + +نستخدم الرابط: +```html + +``` + +مثال على `.css` +```css +.order-text { + font-size: 40px; +} +``` + +مثال على قالب مع `css` + +```html +
    Информация о заказе №{{ data.id }}
    +``` +## الحصول على البيانات من الطلب، input + +لإرسال البيانات من المتصفح إلى خادم Django، يجب إضافة نموذج، وزر، وحقول إدخال إلى قالبنا. + +```html +
    + {% csrf_token %} +

    + +
    +``` + +أضف إلى `urls.py` معالج طلب POST الخاص بنا `views.sendText` للرابط [/sendText]() +```python +path('sendText', views.sendText, name='sendText'), + +```python +def sendText(request): + input_text = request.POST['text'] + ... +```