سرور مجازی

  • ۰
  • ۰

نحوه انجام جستجوی تمام متن در MongoDB

ورود به سایت

معرفی

پرس‌و‌جوهای MongoDB که داده‌ها را با جستجوی تطابق دقیق، استفاده از مقایسه‌های بیشتر یا کمتر یا با استفاده از عبارات منظم فیلتر می‌کنند، در بسیاری از موقعیت‌ها به اندازه کافی خوب کار می‌کنند. با این حال، وقتی صحبت از فیلتر کردن فیلدهای حاوی داده های متنی غنی می شود، این روش ها کوتاهی می کنند.

تصور کنید “دستور پخت قهوه” را در یک موتور جستجوی وب تایپ کرده اید، اما فقط صفحاتی را که حاوی همان عبارت هستند، باز می گرداند. در این مورد، ممکن است دقیقاً چیزی را که به دنبال آن بودید پیدا نکنید، زیرا اکثر وب سایت های محبوب با دستور پخت قهوه ممکن است عبارت دقیق «دستور پخت قهوه» را نداشته باشند. اگر بخواهید این عبارت را در یک موتور جستجوی واقعی وارد کنید، ممکن است صفحاتی با عناوینی مانند «نوشیدنی های قهوه عالی (با دستور پخت!)» یا «نوشیدنی ها و خوراکی های کافی شاپ که می توانید در خانه درست کنید» پیدا کنید. در این مثال‌ها، کلمه «قهوه» وجود دارد، اما عناوین حاوی شکل دیگری از کلمه «رسپی» هستند یا آن را به طور کامل حذف می‌کنند.

این سطح از انعطاف در تطبیق متن با یک عبارت جستجو برای موتورهای جستجوی متن کامل که در جستجوی داده های متنی تخصص دارند، معمول است. چندین ابزار منبع باز تخصصی برای چنین برنامه هایی در حال استفاده وجود دارد که ElasticSearch یک انتخاب بسیار محبوب است. با این حال، برای سناریوهایی که به ویژگی های جستجوی قوی موجود در موتورهای جستجوی اختصاصی نیاز ندارند، برخی از سیستم های مدیریت پایگاه داده همه منظوره قابلیت های جستجوی متن کامل خود را ارائه می دهند.

در این آموزش، شما به عنوان مثال یاد خواهید گرفت که چگونه یک نمایه متن در MongoDB ایجاد کنید و از آن برای جستجوی اسناد در پایگاه داده در برابر پرس و جوها و فیلترهای جستجوی متن کامل استفاده کنید.

پیش نیازها

برای دنبال کردن این آموزش، شما نیاز دارید:

  • سروری با کاربر معمولی و غیر روت با امتیازات sudo و فایروال پیکربندی شده با UFW. این آموزش با استفاده از سروری که اوبونتو 20.04 را اجرا می کند تأیید شده است، و شما می توانید با دنبال کردن این آموزش اولیه راه اندازی سرور برای اوبونتو 20.04 سرور خود را آماده کنید.
  • MongoDB روی سرور شما نصب شده است.
  • نمونه MongoDB سرور شما با فعال کردن احراز هویت و ایجاد یک کاربر مدیریتی ایمن می شود
  • آشنایی با پرس و جو مجموعه های MongoDB و فیلتر کردن نتایج.

مرحله 1 – آماده سازی داده های تست

برای کمک به یادگیری نحوه انجام جستجوی متن کامل در MongoDB، این مرحله نحوه باز کردن پوسته MongoDB برای اتصال به نمونه MongoDB نصب شده محلی خود را شرح می دهد. همچنین نحوه ایجاد یک مجموعه نمونه و درج چند سند نمونه در آن را توضیح می دهد. این نمونه داده در دستورات و مثال‌هایی در سراسر این راهنما استفاده می‌شود تا به توضیح نحوه استفاده از MongoDB برای جستجوی داده‌های متنی کمک کند.

برای ایجاد این مجموعه نمونه، به عنوان کاربر مدیریتی خود به پوسته MongoDB متصل شوید. این آموزش از قراردادهای آموزش امنیتی MongoDB پیش نیاز پیروی می کند و فرض می کند که نام این کاربر مدیریتی AdminSammy و پایگاه داده احراز هویت آن admin است. مطمئن شوید که این جزئیات را در دستور زیر تغییر دهید تا تنظیمات خود را نشان دهد، اگر متفاوت است:

mongo -u AdminSammy -p –authenticationDatabase admin

رمز عبوری را که در حین نصب تنظیم کرده اید وارد کنید تا به پوسته دسترسی پیدا کنید. پس از ارائه رمز عبور، درخواست شما به علامت بزرگتر از تغییر خواهد کرد:

>

برای درک اینکه چگونه جستجوی متن کامل را می توان برای اسناد در MongoDB اعمال کرد، به مجموعه ای از اسناد نیاز دارید که بتوانید آنها را فیلتر کنید. این راهنما از مجموعه ای از اسناد نمونه استفاده می کند که شامل نام و توضیحات چندین نوع مختلف نوشیدنی قهوه است. این اسناد همان فرمت سند نمونه زیر را دارند که نوشیدنی قهوه کوبایی را توصیف می کند:

Example Cafecito document

{
    "name": "Cafecito",
    "description": "A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam."
}

این سند شامل دو فیلد است: نام نوشیدنی قهوه و توضیحات طولانی تر که اطلاعات پس زمینه ای در مورد نوشیدنی و مواد تشکیل دهنده آن ارائه می دهد.

متد insertMany() زیر را در پوسته MongoDB اجرا کنید تا مجموعه‌ای به نام recipes ایجاد کنید و در همان زمان، پنج سند نمونه را در آن قرار دهید:

db.recipes.insertMany([
{“name”: “Cafecito”, “description”: “A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam.”},
{“name”: “New Orleans Coffee”, “description”: “Cafe Noir from New Orleans is a spiced, nutty coffee made with chicory.”},
{“name”: “Affogato”, “description”: “An Italian sweet dessert coffee made with fresh-brewed espresso and vanilla ice cream.”},
{“name”: “Maple Latte”, “description”: “A wintertime classic made with espresso and steamed milk and sweetened with some maple syrup.”},
{“name”: “Pumpkin Spice Latte”, “description”: “It wouldn’t be autumn without pumpkin spice lattes made with espresso, steamed milk, cinnamon spices, and pumpkin puree.”}
])

 

این متد لیستی از شناسه‌های شی اختصاص داده شده به اشیاء تازه درج شده را برمی‌گرداند:

 

Output

{
        "acknowledged" : true,
        "insertedIds" : [
            ObjectId("61895d2787f246b334ece911"),
            ObjectId("61895d2787f246b334ece912"),
            ObjectId("61895d2787f246b334ece913"),
            ObjectId("61895d2787f246b334ece914"),
            ObjectId("61895d2787f246b334ece915")
        ]
}

می توانید با اجرای متد find() در مجموعه دستور العمل ها بدون آرگومان بررسی کنید که اسناد به درستی درج شده اند. با این کار تمام اسناد موجود در مجموعه بازیابی می شود:

db.recipes.find()

 

Output

{ "_id" : ObjectId("61895d2787f246b334ece911"), "name" : "Cafecito", "description" : "A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam." }
. . .

با داده های نمونه در محل، آماده شروع یادگیری نحوه استفاده از ویژگی های جستجوی متن کامل MongoDB هستید.

مرحله 2 – ایجاد یک فهرست متن

برای شروع استفاده از قابلیت‌های جستجوی متن کامل MongoDB، باید یک فهرست متنی در مجموعه ایجاد کنید. ایندکس ها ساختارهای داده خاصی هستند که تنها زیر مجموعه کوچکی از داده ها را از هر سند در مجموعه ای جدا از خود اسناد ذخیره می کنند. انواع مختلفی از نمایه هایی وجود دارد که کاربران می توانند در MongoDB ایجاد کنند، که همگی به پایگاه داده کمک می کنند تا عملکرد جستجو را هنگام جستجو در مجموعه بهینه کند.

با این حال، نمایه متنی، نوع خاصی از نمایه است که برای تسهیل بیشتر جستجوی فیلدهای حاوی داده های متنی استفاده می شود. هنگامی که کاربر یک فهرست متنی ایجاد می کند، MongoDB به طور خودکار هر کلمه توقف خاص زبان را از جستجو حذف می کند. این بدان معنی است که MongoDB رایج ترین کلمات برای زبان داده شده (در انگلیسی، کلماتی مانند “a”، “an”، “the” یا “this”) را نادیده می گیرد.

MongoDB همچنین نوعی پسوند stemming را در جستجوها پیاده سازی خواهد کرد. این شامل شناسایی قسمت ریشه عبارت جستجو شده توسط MongoDB و استفاده از سایر اشکال دستور زبان آن ریشه (که با افزودن پسوندهای رایج مانند “-ing”، “-ed” یا شاید “-er” ایجاد شده است) را به عنوان معادل ریشه برای کلمه جستجو می کند.

به لطف این ویژگی‌ها و سایر ویژگی‌ها، MongoDB می‌تواند با انعطاف‌پذیری بیشتری از پرسش‌های نوشته شده به زبان طبیعی پشتیبانی کند و نتایج بهتری ارائه دهد.

شما فقط می توانید یک فهرست متنی برای هر مجموعه MongoDB ایجاد کنید، اما این فهرست را می توان با استفاده از بیش از یک فیلد ایجاد کرد. در مجموعه مثال ما، متن مفیدی در هر دو قسمت نام و توضیحات هر سند ذخیره شده است. ایجاد یک فهرست متنی برای هر دو فیلد می تواند مفید باشد.

متد ()createIndex زیر را اجرا کنید که یک فهرست متنی برای دو فیلد ایجاد می کند:

db.recipes.createIndex({ “name”: “text”, “description”: “text” });

برای هر یک از دو فیلد، نام و توضیحات، نوع فهرست روی متن تنظیم می‌شود و به MongoDB می‌گوید یک فهرست متنی متناسب با جستجوی متن کامل بر اساس این فیلدها ایجاد کند. خروجی ایجاد ایندکس را تایید می کند:

 

Output

{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}

اکنون که نمایه را ایجاد کرده اید، می توانید از آن برای ارسال عبارت های جستجوی متن کامل در پایگاه داده استفاده کنید. در مرحله بعد، یاد خواهید گرفت که چگونه کوئری هایی را که شامل تک کلمه و چند کلمه هستند اجرا کنید.

مرحله 3 – جستجو برای یک یا چند کلمه جداگانه

شاید رایج ترین مشکل جستجو جستجوی اسنادی باشد که حاوی یک یا چند کلمه جداگانه هستند.

به طور معمول، کاربران انتظار دارند که موتور جستجو در تعیین محل نمایش عبارات جستجوی معین انعطاف پذیر باشد. به عنوان مثال، اگر بخواهید از هر موتور جستجوی وب محبوبی استفاده کنید و عبارت «قهوه شیرین تند» را تایپ کنید، احتمالاً انتظار نتایجی را ندارید که حاوی این سه کلمه به همان ترتیب باشد. احتمال بیشتری وجود دارد که انتظار داشته باشید لیستی از صفحات وب حاوی کلمات “قهوه”، “شیرین” و “ادویه” باشد اما لزوماً بلافاصله در نزدیکی یکدیگر نیستند.

همچنین این روشی است که MongoDB هنگام استفاده از نمایه های متنی به پرس و جوهای جستجوی معمولی نزدیک می شود. در این مرحله توضیح داده می شود که MongoDB چگونه پرس و جوهای جستجو را با چند مثال تفسیر می کند.

برای شروع، بگویید که می‌خواهید نوشیدنی‌های قهوه را با ادویه در دستور غذا جستجو کنید، بنابراین با استفاده از دستور زیر کلمه spiced را به تنهایی جستجو کنید:

db.recipes.find({ $text: { $search: “spiced” } });

توجه داشته باشید که نحو هنگام استفاده از جستجوی تمام متن کمی با پرس و جوهای معمولی متفاوت است. نام فیلدهای فردی – مانند نام یا توضیحات – در سند فیلتر ظاهر نمی شوند. در عوض، کوئری از عملگر $text استفاده می‌کند و به MongoDB می‌گوید که این کوئری قصد دارد از فهرست متنی که قبلا ایجاد کرده‌اید استفاده کند. لازم نیست بیشتر از آن مشخص باشید، زیرا همانطور که به یاد دارید، یک مجموعه ممکن است فقط یک فهرست متنی داشته باشد. در داخل سند جاسازی شده برای این فیلتر، اپراتور $search است که عبارت جستجو را به عنوان مقدار آن در نظر گرفته است. در این مثال، پرس و جو یک کلمه است: spiced.

پس از اجرای این دستور، MongoDB لیستی از اسناد زیر را تولید می کند:

 

Output

{ "_id" : ObjectId("61895d2787f246b334ece915"), "name" : "Pumpkin Spice Latte", "description" : "It wouldn't be autumn without pumpkin spice lattes made with espresso, steamed milk, cinnamon spices, and pumpkin puree." }
{ "_id" : ObjectId("61895d2787f246b334ece912"), "name" : "New Orleans Coffee", "description" : "Cafe Noir from New Orleans is a spiced, nutty coffee made with chicory." }

دو سند در مجموعه نتایج وجود دارد که هر دو حاوی کلماتی شبیه عبارت جستجو هستند. در حالی که سند قهوه نیواورلئان دارای کلمه تند در توضیحات است، سند Pumpkin Spice Late چنین نیست.

صرف نظر از این، به لطف استفاده MongoDB از stemming، همچنان با این کوئری بازگردانده شد. MongoDB کلمه spiced را به صرف ادویه حذف کرد، ادویه را در فهرست جستجو کرد و همچنین آن را ریشه‌یابی کرد. به همین دلیل، کلمات ادویه و ادویه در سند Pumpkin Spice Late با عبارت جستجو با موفقیت مطابقت داشت، حتی اگر هیچ یک از آن کلمات را به طور خاص جستجو نکردید.

حالا، فرض کنید به نوشیدنی های اسپرسو علاقه خاصی دارید. سعی کنید اسناد را با یک پرس و جوی دو کلمه ای، اسپرسوی تند، جستجو کنید تا به دنبال قهوه ای تند و مبتنی بر اسپرسو بگردید.

db.recipes.find({ $text: { $search: “spiced espresso” } });

لیست نتایج این بار طولانی تر از قبل است:

 

Output

{ "_id" : ObjectId("61895d2787f246b334ece914"), "name" : "Maple Latte", "description" : "A wintertime classic made with espresso and steamed milk and sweetened with some maple syrup." }
{ "_id" : ObjectId("61895d2787f246b334ece913"), "name" : "Affogato", "description" : "An Italian sweet dessert coffee made with fresh-brewed espresso and vanilla ice cream." }
{ "_id" : ObjectId("61895d2787f246b334ece911"), "name" : "Cafecito", "description" : "A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam." }
{ "_id" : ObjectId("61895d2787f246b334ece915"), "name" : "Pumpkin Spice Latte", "description" : "It wouldn't be autumn without pumpkin spice lattes made with espresso, steamed milk, cinnamon spices, and pumpkin puree." }
{ "_id" : ObjectId("61895d2787f246b334ece912"), "name" : "New Orleans Coffee", "description" : "Cafe Noir from New Orleans is a spiced, nutty coffee made with chicory." }

هنگام استفاده از چندین کلمه در یک عبارت جستجو، MongoDB یک عملیات OR منطقی را انجام می دهد، بنابراین یک سند فقط باید با یک قسمت از عبارت مطابقت داشته باشد تا در مجموعه نتایج گنجانده شود. نتایج حاوی اسنادی است که هم دارای ادویه و هم اسپرسو یا هر یک از آنها به تنهایی است. توجه داشته باشید که تا زمانی که کلمات در جایی در سند ظاهر می شوند، لزوماً نیازی نیست که در نزدیکی یکدیگر ظاهر شوند.

در این مرحله، یاد گرفتید که چگونه از یک یا چند کلمه به عنوان جستجوی متنی استفاده کنید، چگونه MongoDB چندین کلمه را با یک عملیات OR منطقی به هم متصل می کند، و چگونه MongoDB stemming را انجام می دهد. در مرحله بعد، از یک عبارت کامل در یک عبارت جستجوی متنی استفاده می‌کنید و شروع به استفاده از استثناها برای محدود کردن بیشتر نتایج جستجو می‌کنید.

مرحله 4 – جستجوی عبارات کامل و استفاده از موارد استثنا

جستجوی کلمات جداگانه ممکن است نتایج بسیار زیادی را به همراه داشته باشد، یا ممکن است نتایج به اندازه کافی دقیق نباشد. در این مرحله، از جستجوی عبارت و حذف برای کنترل دقیق‌تر نتایج جستجو استفاده می‌کنید.

فرض کنید شیرینی دارید، بیرون گرم است، و قهوه ای که روی آن بستنی ریخته شده است، به نظر یک خوراکی خوب است. سعی کنید یک قهوه بستنی را با استفاده از عبارت جستجوی اولیه همانطور که قبلا ذکر شد پیدا کنید:

db.recipes.find({ $text: { $search: “ice cream” } });

پایگاه داده دو دستور پخت قهوه را برمی گرداند:

 

Output

{ "_id" : ObjectId("61895d2787f246b334ece913"), "name" : "Affogato", "description" : "An Italian sweet dessert coffee made with fresh-brewed espresso and vanilla ice cream." }
{ "_id" : ObjectId("61895d2787f246b334ece911"), "name" : "Cafecito", "description" : "A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam." }

در حالی که سند Affogato با انتظارات شما مطابقت دارد، Cafecito با بستنی درست نمی شود. موتور جستجو با استفاده از عملیات منطقی OR، نتیجه دوم را فقط به این دلیل پذیرفت که کلمه کرم در توضیحات آمده است.

برای اینکه به MongoDB بگویید که به دنبال بستنی به عنوان یک عبارت کامل هستید و نه دو کلمه جداگانه، از عبارت زیر استفاده کنید:

db.recipes.find({ $text: { $search: “\”ice cream\”” } });

به علامت‌های معکوس قبل از هر یک از نقل‌قول‌های دوگانه اطراف عبارت: \”ice cream\” توجه کنید. عبارت جستجویی که اجرا می‌کنید «ice cream» است، با دو نقل قول نشان‌دهنده عبارتی است که باید دقیقاً مطابقت داشته باشد. اسلش‌های معکوس (\) از گیومه‌های دوتایی فرار می‌کنند، بنابراین به عنوان بخشی از نحو JSON در نظر گرفته نمی‌شوند، زیرا می‌توانند در مقدار عملگر $search ظاهر شوند.

این بار، MongoDB یک نتیجه را برمی گرداند:

 

Output

{ "_id" : ObjectId("61895d2787f246b334ece913"), "name" : "Affogato", "description" : "An Italian sweet dessert coffee made with fresh-brewed espresso and vanilla ice cream." }

این سند دقیقاً با عبارت جستجو مطابقت دارد و نه خامه و نه یخ به تنهایی برای به حساب آوردن یک مسابقه کافی نیست.

یکی دیگر از ویژگی های مفید جستجوی متن کامل، اصلاح کننده حذف است. برای نشان دادن نحوه عملکرد، ابتدا پرس و جو زیر را اجرا کنید تا لیستی از تمام نوشیدنی های قهوه موجود در مجموعه بر اساس اسپرسو دریافت کنید:

db.recipes.find({ $text: { $search: “espresso” } });

این پرس و جو چهار سند را برمی گرداند:

 

Output

{ "_id" : ObjectId("61895d2787f246b334ece914"), "name" : "Maple Latte", "description" : "A wintertime classic made with espresso and steamed milk and sweetened with some maple syrup." }
{ "_id" : ObjectId("61895d2787f246b334ece913"), "name" : "Affogato", "description" : "An Italian sweet dessert coffee made with fresh-brewed espresso and vanilla ice cream." }
{ "_id" : ObjectId("61895d2787f246b334ece915"), "name" : "Pumpkin Spice Latte", "description" : "It wouldn't be autumn without pumpkin spice lattes made with espresso, steamed milk, cinnamon spices, and pumpkin puree." }
{ "_id" : ObjectId("61895d2787f246b334ece911"), "name" : "Cafecito", "description" : "A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam." }

توجه داشته باشید که دو تا از این نوشیدنی ها با شیر سرو می شوند، اما فرض کنید شما یک نوشیدنی بدون شیر می خواهید. این موردی است که در آن محرومیت ها می توانند مفید باشند. در یک جستار، می‌توانید کلماتی را که می‌خواهید در نتایج نشان داده شوند، با کلماتی که می‌خواهید حذف شوند، با اضافه کردن کلمه یا عبارتی که می‌خواهید حذف کنید با علامت منفی (-) بپیوندید.

به عنوان مثال، فرض کنید برای جستجوی قهوه‌های اسپرسو که حاوی شیر نیستند، عبارت زیر را اجرا می‌کنید:

db.recipes.find({ $text: { $search: “espresso -milk” } });

با این پرس و جو، دو سند از نتایج برگشت داده شده قبلی حذف می شوند:

 

Output

{ "_id" : ObjectId("61895d2787f246b334ece913"), "name" : "Affogato", "description" : "An Italian sweet dessert coffee made with fresh-brewed espresso and vanilla ice cream." }
{ "_id" : ObjectId("61895d2787f246b334ece911"), "name" : "Cafecito", "description" : "A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam." }

شما همچنین می توانید عبارات کامل را حذف کنید. برای جستجوی قهوه های بدون بستنی، می توانید -“ice cream” را در عبارت جستجوی خود قرار دهید. باز هم، باید از نقل قول های دوگانه با اسلش های معکوس فرار کنید، مانند این:

db.recipes.find({ $text: { $search: “espresso -\”ice cream\”” } });

 

Output

{ "_id" : ObjectId("61d48c31a285f8250c8dd5e6"), "name" : "Maple Latte", "description" : "A wintertime classic made with espresso and steamed milk and sweetened with some maple syrup." }
{ "_id" : ObjectId("61d48c31a285f8250c8dd5e7"), "name" : "Pumpkin Spice Latte", "description" : "It wouldn't be autumn without pumpkin spice lattes made with espresso, steamed milk, cinnamon spices, and pumpkin puree." }
{ "_id" : ObjectId("61d48c31a285f8250c8dd5e3"), "name" : "Cafecito", "description" : "A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam." }

اکنون که یاد گرفتید چگونه اسناد را بر اساس عبارتی متشکل از چند کلمه فیلتر کنید و چگونه کلمات و عبارات خاصی را از نتایج جستجو حذف کنید، می توانید خود را با امتیاز جستجوی تمام متن MongoDB آشنا کنید.

مرحله 5 – امتیاز دادن به نتایج و مرتب سازی بر اساس امتیاز

هنگامی که یک پرس و جو، به ویژه یک پرسش پیچیده، نتایج متعددی را برمی گرداند، برخی از اسناد احتمالاً تطبیق بهتری نسبت به سایرین دارند. به عنوان مثال، وقتی به دنبال نوشیدنی‌های اسپرسو ادویه‌دار می‌گردید، آن‌هایی که هم ادویه‌دار هستند و هم بر پایه اسپرسو، مناسب‌تر از نوشیدنی‌های بدون ادویه هستند یا از اسپرسو به عنوان پایه استفاده نمی‌کنند.

موتورهای جستجوی متن کامل معمولاً یک امتیاز مربوط به نتایج جستجو را تعیین می‌کنند که نشان می‌دهد تا چه حد با عبارت جستجو مطابقت دارند. MongoDB نیز این کار را انجام می دهد، اما ارتباط جستجو به طور پیش فرض قابل مشاهده نیست.

یک بار دیگر اسپرسوی تند را جستجو کنید، اما این بار MongoDB امتیاز مربوط به جستجوی هر نتیجه را نیز بازگردانید. برای انجام این کار، می توانید پس از سند فیلتر پرس و جو یک طرح اضافه کنید:

db.recipes.find(
{ $text: { $search: “spiced espresso” } },
{ score: { $meta: “textScore” } }
)

طرح ریزی { score: {$meta: “textScore” } } از عملگر $meta استفاده می کند، نوع خاصی از طرح ریزی که ابرداده خاصی را از اسناد برگشتی برمی گرداند. این مثال ابرداده textScore اسناد را برمی‌گرداند، یکی از ویژگی‌های داخلی موتور جستجوی متن کامل MongoDB که حاوی امتیاز مربوط به جستجو است.

پس از اجرای پرس و جو، اسناد برگشتی شامل یک فیلد جدید به نام score می شود، همانطور که در سند فیلتر مشخص شده است:

 

Output

{ "_id" : ObjectId("61895d2787f246b334ece913"), "name" : "Affogato", "description" : "An Italian sweet dessert coffee made with fresh-brewed espresso and vanilla ice cream.", "score" : 0.5454545454545454 }
{ "_id" : ObjectId("61895d2787f246b334ece911"), "name" : "Cafecito", "description" : "A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam.", "score" : 0.5384615384615384 }
{ "_id" : ObjectId("61895d2787f246b334ece914"), "name" : "Maple Latte", "description" : "A wintertime classic made with espresso and steamed milk and sweetened with some maple syrup.", "score" : 0.55 }
{ "_id" : ObjectId("61895d2787f246b334ece912"), "name" : "New Orleans Coffee", "description" : "Cafe Noir from New Orleans is a spiced, nutty coffee made with chicory.", "score" : 0.5454545454545454 }
{ "_id" : ObjectId("61895d2787f246b334ece915"), "name" : "Pumpkin Spice Latte", "description" : "It wouldn't be autumn without pumpkin spice lattes made with espresso, steamed milk, cinnamon spices, and pumpkin puree.", "score" : 2.0705128205128203 }

توجه کنید که امتیاز Pumpkin Spice Latte چقدر بالاتر است، تنها نوشیدنی قهوه که حاوی کلمات spiced و اسپرسو است. با توجه به امتیاز مرتبط MongoDB، مرتبط ترین سند برای آن پرس و جو است. با این حال، به طور پیش فرض، نتایج به ترتیب مرتبط بودن برگردانده نمی شوند.

برای تغییر آن، می توانید یک بند sort() به پرس و جو اضافه کنید، مانند این:

db.recipes.find(
{ $text: { $search: “spiced espresso” } },
{ score: { $meta: “textScore” } }
).sort(
{ score: { $meta: “textScore” } }
);

نحو برای سند مرتب‌سازی مانند پروژکشن است. اکنون لیست اسناد یکسان است، اما ترتیب آنها متفاوت است:

 

Output

{ "_id" : ObjectId("61895d2787f246b334ece915"), "name" : "Pumpkin Spice Latte", "description" : "It wouldn't be autumn without pumpkin spice lattes made with espresso, steamed milk, cinnamon spices, and pumpkin puree.", "score" : 2.0705128205128203 }
{ "_id" : ObjectId("61895d2787f246b334ece914"), "name" : "Maple Latte", "description" : "A wintertime classic made with espresso and steamed milk and sweetened with some maple syrup.", "score" : 0.55 }
{ "_id" : ObjectId("61895d2787f246b334ece913"), "name" : "Affogato", "description" : "An Italian sweet dessert coffee made with fresh-brewed espresso and vanilla ice cream.", "score" : 0.5454545454545454 }
{ "_id" : ObjectId("61895d2787f246b334ece912"), "name" : "New Orleans Coffee", "description" : "Cafe Noir from New Orleans is a spiced, nutty coffee made with chicory.", "score" : 0.5454545454545454 }
{ "_id" : ObjectId("61895d2787f246b334ece911"), "name" : "Cafecito", "description" : "A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam.", "score" : 0.5384615384615384 }

سند Pumpkin Spice Latte به عنوان اولین نتیجه ظاهر می شود زیرا دارای بالاترین امتیاز مرتبط است.

مرتب سازی نتایج بر اساس امتیاز مربوط به آنها می تواند مفید باشد. این امر به‌ویژه در مورد پرسش‌هایی که حاوی چند کلمه هستند، صادق است، جایی که مناسب‌ترین اسناد معمولاً شامل چندین عبارت جستجو می‌شوند در حالی که اسناد کمتر مرتبط ممکن است فقط شامل یک عبارت باشند.

نتیجه

با دنبال کردن این آموزش، با ویژگی های جستجوی متن کامل MongoDB آشنا شدید. شما یک نمایه متن ایجاد کردید و پرس و جوهای جستجوی متنی را با استفاده از کلمات تک و چندگانه، عبارات کامل و موارد استثنا نوشتید. شما همچنین امتیازات مربوط به اسناد برگشتی را ارزیابی کرده اید و نتایج جستجو را مرتب کرده اید تا ابتدا مرتبط ترین نتایج را نشان دهید. در حالی که ویژگی‌های جستجوی متن کامل MongoDB ممکن است به اندازه ویژگی‌های برخی از موتورهای جستجوی اختصاصی قوی نباشد، اما برای بسیاری از موارد استفاده به اندازه کافی توانایی دارند.

توجه داشته باشید که اصلاح‌کننده‌های جستجوی بیشتری – مانند حساسیت حروف کوچک و بزرگ و پشتیبانی از زبان‌های مختلف – در یک فهرست متنی واحد وجود دارد.

 

https://vpsgol.net/product/vps-germany/

 

https://vpsgol.net/product/vps-usa/

 

https://vpsgol.net/product/vps-france/

 

https://vpsgol.net/product/vps-canada/

 

https://vpsgol.net/product/vps-poland/

 

https://vpsgol.net/product/vps-netherlands/

 

https://vpsgol.net/product/vps-england/

 

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه استفاده از Ansible Vault برای محافظت از داده های حساس Playbook

ورود به سایت

معرفی

Ansible Vault قابلیتی است که به کاربران امکان می دهد مقادیر و ساختارهای داده را در پروژه های Ansible رمزگذاری کنند. این امکان را فراهم می کند تا داده های حساسی را که برای اجرای موفقیت آمیز بازی های Ansible لازم است، اما نباید به صورت عمومی قابل مشاهده باشند، مانند گذرواژه ها یا کلیدهای خصوصی، ایمن کنید. Ansible به طور خودکار محتوای رمزگذاری شده در طاق را در زمان اجرا پس از ارائه کلید رمزگشایی می کند.

در این راهنما، نحوه استفاده از Ansible Vault را نشان خواهیم داد و برخی از روش‌های توصیه شده برای ساده‌سازی استفاده از آن را بررسی خواهیم کرد. ما از سرور اوبونتو 20.04 برای ماشین کنترلی Ansible استفاده خواهیم کرد. به هاست راه دور نیاز نیست.

پیش نیازها

برای پیگیری، به یک سرور اوبونتو 20.04 با یک کاربر غیر ریشه با امتیازات sudo نیاز دارید. شما می توانید راهنمای راه اندازی سرور اولیه Ubuntu 20.04 ما را دنبال کنید تا کاربری با مجوزهای مناسب ایجاد کنید.

در سرور، باید Ansible را نصب و پیکربندی کنید. برای نصب بسته های مناسب می توانید آموزش نصب Ansible در اوبونتو 20.04 را دنبال کنید.

هنگامی که سرور شما با شرایط بالا پیکربندی شده است، این راهنما را ادامه دهید.

Ansible Vault چیست؟

Ansible Vault مکانیزمی است که به محتوای رمزگذاری شده اجازه می دهد تا به طور شفاف در جریان های کاری Ansible گنجانده شود. ابزاری به نام ansible-vault داده‌های محرمانه به نام Secrets را با رمزگذاری روی دیسک ایمن می‌کند. برای ادغام این اسرار با داده‌های معمولی Ansible، هر دو دستور ansible و ansible-playbook، به ترتیب برای اجرای وظایف موقت و playbook ساختاریافته، از رمزگشایی محتوای رمزگذاری‌شده در طاق در زمان اجرا پشتیبانی می‌کنند.

Vault با جزئیات در سطح فایل پیاده سازی می شود، به این معنی که فایل های جداگانه یا رمزگذاری شده یا غیر رمزگذاری شده هستند. از الگوریتم AES256 برای ارائه رمزگذاری متقارن کلید شده به رمز عبور ارائه شده توسط کاربر استفاده می کند. این بدان معنی است که رمز عبور یکسان برای رمزگذاری و رمزگشایی محتوا استفاده می شود، که از نقطه نظر قابلیت استفاده مفید است. Ansible قادر به شناسایی و رمزگشایی هر فایل رمزگذاری شده در طاقچه ای است که در حین اجرای یک کتاب بازی یا کار پیدا می کند.

اکنون که کمی در مورد Vault چیست، می‌توانیم درباره ابزارهایی که Ansible ارائه می‌کند و نحوه استفاده از Vault با گردش‌های کاری موجود بحث کنیم.

تنظیم ویرایشگر Ansible Vault

قبل از استفاده از دستور ansible-vault، ایده خوبی است که ویرایشگر متن مورد نظر خود را مشخص کنید. تعدادی از دستورات Vault شامل باز کردن یک ویرایشگر برای دستکاری محتوای یک فایل رمزگذاری شده است. Ansible به متغیر محیط EDITOR نگاه می کند تا ویرایشگر مورد نظر شما را پیدا کند. اگر این تنظیم نشده باشد، به طور پیش فرض روی vi خواهد بود.

اگر نمی خواهید با ویرایشگر vi ویرایش کنید، باید متغیر EDITOR را در محیط خود تنظیم کنید.

برای تنظیم ویرایشگر برای یک فرمان فردی، دستور را با انتساب متغیر محیطی به صورت زیر اضافه کنید:

EDITOR=nano ansible-vault . . .

برای تداوم این موضوع، فایل ~/.bashrc خود را باز کنید:

nano ~/.bashrc

ویرایشگر مورد نظر خود را با افزودن یک تخصیص EDITOR به انتهای فایل مشخص کنید:

~/.bashrc

export EDITOR=nano

پس از اتمام کار فایل را ذخیره کرده و ببندید.

برای خواندن تغییر در جلسه فعلی، فایل را دوباره منبع کنید:

. ~/.bashrc

برای بررسی اینکه تنظیمات شما اعمال شده است، متغیر EDITOR را نمایش دهید:

echo $EDITOR

 

Output

nano

اکنون که ویرایشگر دلخواه خود را ایجاد کرده اید، می توانیم عملیات های موجود را با دستور ansible-vault مورد بحث قرار دهیم.

نحوه مدیریت فایل های حساس با ansible-vault

دستور ansible-vault رابط اصلی برای مدیریت محتوای رمزگذاری شده در Ansible است. این دستور در ابتدا برای رمزگذاری فایل ها استفاده می شود و سپس برای مشاهده، ویرایش یا رمزگشایی داده ها استفاده می شود.

ایجاد فایل های رمزگذاری شده جدید

برای ایجاد یک فایل جدید رمزگذاری شده با Vault، از دستور ansible-vault create استفاده کنید. نام فایلی را که می خواهید ایجاد کنید ارسال کنید. به عنوان مثال، برای ایجاد یک فایل YAML رمزگذاری شده به نام vault.yml برای ذخیره متغیرهای حساس، می توانید تایپ کنید:

ansible-vault create vault.yml

از شما خواسته می شود رمز عبور را وارد کرده و تأیید کنید:

 

Output

New Vault password: 
Confirm New Vault password:

هنگامی که رمز عبور خود را تأیید کردید، Ansible بلافاصله یک پنجره ویرایش باز می کند که در آن می توانید مطالب مورد نظر خود را وارد کنید.

برای آزمایش عملکرد رمزگذاری، متن آزمایشی را وارد کنید:

vault.yml

Secret information

هنگامی که فایل را ببندید، Ansible محتویات را رمزگذاری می کند. اگر فایل را بررسی کنید، به جای دیدن کلماتی که تایپ کرده اید، یک بلوک رمزگذاری شده خواهید دید:

cat vault.yml

 

Output

$ANSIBLE_VAULT;1.1;AES256
65316332393532313030636134643235316439336133363531303838376235376635373430336333
3963353630373161356638376361646338353763363434360a363138376163666265336433633664
30336233323664306434626363643731626536643833336638356661396364313666366231616261
3764656365313263620a383666383233626665376364323062393462373266663066366536306163
31643731343666353761633563633634326139396230313734333034653238303166

ما می‌توانیم برخی از اطلاعات هدر را ببینیم که Ansible برای اطلاع از نحوه مدیریت فایل استفاده می‌کند و به دنبال آن محتویات رمزگذاری‌شده که به صورت اعداد نمایش داده می‌شوند.

رمزگذاری فایل های موجود

اگر از قبل فایلی دارید که می خواهید با Vault رمزگذاری کنید، به جای آن از دستور encrypt ansible-vault استفاده کنید.

برای آزمایش، می‌توانیم با تایپ کردن یک فایل نمونه ایجاد کنیم:

echo ‘unencrypted stuff’ > encrypt_me.txt

اکنون می توانید فایل موجود را با تایپ کردن رمزگذاری کنید:

ansible-vault encrypt encrypt_me.txt

مجدداً از شما خواسته می شود رمز عبور را ارائه و تأیید کنید. پس از آن، یک پیام رمزگذاری را تایید می کند:

 

Output

New Vault password: 
Confirm New Vault password:
Encryption successful

به جای باز کردن یک پنجره ویرایش، ansible-vault محتویات فایل را رمزگذاری می کند و آن را روی دیسک می نویسد و نسخه رمزگذاری نشده را جایگزین می کند.

اگر فایل را بررسی کنیم، باید یک الگوی رمزگذاری شده مشابه را ببینیم:

cat encrypt_me.txt

 

Output

$ANSIBLE_VAULT;1.1;AES256
66633936653834616130346436353865303665396430383430353366616263323161393639393136
3737316539353434666438373035653132383434303338640a396635313062386464306132313834
34313336313338623537333332356231386438666565616537616538653465333431306638643961
3636663633363562320a613661313966376361396336383864656632376134353039663662666437
39393639343966363565636161316339643033393132626639303332373339376664

همانطور که می بینید، Ansible محتوای موجود را به همان روشی که فایل های جدید را رمزگذاری می کند، رمزگذاری می کند.

مشاهده فایل های رمزگذاری شده

گاهی اوقات، ممکن است لازم باشد به محتویات یک فایل رمزگذاری شده بدون نیاز به ویرایش یا نوشتن آن در سیستم فایل بدون رمزگذاری، ارجاع دهید. دستور ansible-vault view محتویات یک فایل را به صورت استاندارد تغذیه می کند. به طور پیش فرض، این بدان معنی است که محتویات در ترمینال نمایش داده می شوند.

فایل رمزگذاری شده vault را به دستور ارسال کنید:

ansible-vault view vault.yml

از شما رمز عبور فایل خواسته می شود. پس از وارد کردن موفقیت آمیز آن، محتوا نمایش داده می شود:

 

Output

Vault password:
Secret information

همانطور که می بینید، درخواست رمز عبور در خروجی محتویات فایل مخلوط می شود. هنگام استفاده از نمای ansible-vault در فرآیندهای خودکار این را در نظر داشته باشید.

ویرایش فایل های رمزگذاری شده

هنگامی که نیاز به ویرایش یک فایل رمزگذاری شده دارید، از دستور ansible-vault edit استفاده کنید:

ansible-vault edit vault.yml

 

از شما رمز عبور فایل خواسته می شود. پس از وارد کردن آن، Ansible فایل را در یک پنجره ویرایش باز می کند، جایی که می توانید تغییرات لازم را انجام دهید.

پس از ذخیره، محتویات جدید با استفاده از رمز رمزگذاری فایل دوباره رمزگذاری شده و روی دیسک نوشته می شود.

رمزگشایی دستی فایل های رمزگذاری شده

برای رمزگشایی یک فایل رمزگذاری شده vault، از دستور ansible-vault decrypt استفاده کنید.

نام فایل رمزگذاری شده را ارسال کنید:

ansible-vault decrypt vault.yml

از شما رمز عبور فایل خواسته می شود. پس از وارد کردن موفقیت آمیز آن، محتوا نمایش داده می شود:

 

Output

Vault password:
Secret information

همانطور که می بینید، درخواست رمز عبور در خروجی محتویات فایل مخلوط می شود. هنگام استفاده از نمای ansible-vault در فرآیندهای خودکار این را در نظر داشته باشید.

ویرایش فایل های رمزگذاری شده

هنگامی که نیاز به ویرایش یک فایل رمزگذاری شده دارید، از دستور ansible-vault edit استفاده کنید:

ansible-vault edit vault.yml

از شما رمز عبور فایل خواسته می شود. پس از وارد کردن آن، Ansible فایل را در یک پنجره ویرایش باز می کند، جایی که می توانید تغییرات لازم را انجام دهید.

پس از ذخیره، محتویات جدید با استفاده از رمز رمزگذاری فایل دوباره رمزگذاری شده و روی دیسک نوشته می شود.

رمزگشایی دستی فایل های رمزگذاری شده

برای رمزگشایی یک فایل رمزگذاری شده vault، از دستور ansible-vault decrypt استفاده کنید.

نام فایل رمزگذاری شده را ارسال کنید:

ansible-vault decrypt vault.yml

از شما خواسته می شود رمز رمزگذاری فایل را وارد کنید. پس از وارد کردن رمز عبور صحیح، فایل رمزگشایی خواهد شد:

 

Output

Vault password:
Decryption successful

اگر دوباره فایل را مشاهده کنید، به جای رمزگذاری طاق، باید محتوای واقعی فایل را ببینید:

cat vault.yml

 

Output

Secret information

فایل شما اکنون روی دیسک رمزگذاری نشده است. پس از پایان کار، مطمئن شوید که اطلاعات حساس را حذف کرده یا فایل را دوباره رمزگذاری کنید.

تغییر رمز عبور فایل های رمزگذاری شده

اگر نیاز به تغییر رمز عبور یک فایل رمزگذاری شده دارید، از دستور ansible-vault rekey استفاده کنید:

ansible-vault rekey encrypt_me.txt

هنگامی که دستور را وارد می کنید، ابتدا رمز عبور فعلی فایل از شما خواسته می شود:

 

Output

Vault password:

پس از وارد کردن آن، از شما خواسته می شود رمز عبور جدید صندوق را انتخاب و تأیید کنید:

 

Output

Vault password:
New Vault password:
Confirm New Vault password:

هنگامی که رمز عبور جدید را با موفقیت تأیید کردید، پیامی مبنی بر موفقیت در فرآیند رمزگذاری مجدد دریافت خواهید کرد:

 

Output

Rekey successful

اکنون فایل باید با استفاده از رمز عبور جدید قابل دسترسی باشد. رمز عبور قدیمی دیگر کار نخواهد کرد.

اجرای Ansible با فایل‌های رمزگذاری‌شده Vault

پس از اینکه اطلاعات حساس خود را با Vault رمزگذاری کردید، می توانید از فایل ها با ابزار معمولی Ansible استفاده کنید. دستورهای ansible و ansible-playbook هر دو می‌دانند چگونه فایل‌های محافظت‌شده در صندوق را با در نظر گرفتن رمز عبور صحیح رمزگشایی کنند. بسته به نیاز شما چند راه مختلف برای ارائه رمز عبور برای این دستورات وجود دارد.

برای پیگیری، به یک فایل رمزگذاری شده در طاق نیاز دارید. با تایپ کردن می توانید یکی ایجاد کنید:

ansible-vault create secret_key

رمز عبور را انتخاب و تأیید کنید. هر محتوای ساختگی را که می خواهید پر کنید:

secret_key

confidential data

ذخیره کنید و فایل را ببندید.

همچنین می توانیم یک فایل میزبان موقت به عنوان موجودی ایجاد کنیم:

nano hosts

ما فقط لوکال هاست Ansible را به آن اضافه می کنیم. برای آماده شدن برای مرحله بعدی، آن را در گروه [پایگاه داده] قرار می دهیم:

hosts

[database]
localhost ansible_connection=local

پس از اتمام کار فایل را ذخیره کرده و ببندید.

در مرحله بعد، یک فایل ansible.cfg در دایرکتوری فعلی ایجاد کنید، اگر قبلاً وجود نداشته باشد:

nano ansible.cfg

در حال حاضر، فقط یک بخش [پیش‌فرض] اضافه کنید و Ansible را به موجودی که ایجاد کردیم اضافه کنید:

ansible.cfg

[defaults]
inventory = ./hosts

وقتی آماده شدید، ادامه دهید.

استفاده از یک اعلان تعاملی

ساده ترین راه برای رمزگشایی محتوا در زمان اجرا این است که Ansible اعتبار مناسب را از شما بخواهد. می توانید این کار را با افزودن –ask-vault-pass به هر دستور ansible یا ansible-playbook انجام دهید. Ansible از شما رمز عبوری می خواهد که از آن برای رمزگشایی هر محتوای محافظت شده در خزانه که پیدا می کند استفاده می کند.

به عنوان مثال، اگر ما نیاز به کپی کردن محتویات یک فایل رمزگذاری شده در طاقچه در یک میزبان داشتیم، می‌توانیم این کار را با ماژول کپی و پرچم –ask-vault-pass انجام دهیم. اگر فایل واقعا حاوی داده های حساس است، به احتمال زیاد می خواهید دسترسی به میزبان راه دور را با محدودیت های مجوز و مالکیت قفل کنید.

ansible –ask-vault-pass -bK -m copy -a ‘src=secret_key dest=/tmp/secret_key mode=0600 owner=root group=root’ localhost

وظیفه ما مشخص می کند که مالکیت فایل باید به روت تغییر کند، بنابراین امتیازات مدیریتی مورد نیاز است. پرچم -bK به Ansible می گوید که رمز عبور sudo را برای میزبان مورد نظر درخواست کند، بنابراین از شما رمز عبور sudo خواسته می شود. سپس از شما رمز عبور Vault خواسته می شود:

 

Output

BECOME password:
Vault password:

هنگامی که رمز عبور ارائه می شود، Ansible تلاش می کند تا با استفاده از رمز عبور Vault برای هر فایل رمزگذاری شده ای که پیدا می کند، کار را اجرا کند. به خاطر داشته باشید که تمام فایل هایی که در حین اجرا به آنها ارجاع داده می شود باید از یک رمز عبور استفاده کنند:

 

Output

localhost | SUCCESS => {
    "changed": true, 
    "checksum": "7a2eb5528c44877da9b0250710cba321bc6dac2d", 
    "dest": "/tmp/secret_key", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "270ac7da333dd1db7d5f7d8307bd6b41", 
    "mode": "0600", 
    "owner": "root", 
    "size": 18, 
    "src": "/home/sammy/.ansible/tmp/ansible-tmp-1480978964.81-196645606972905/source", 
    "state": "file", 
    "uid": 0
}

درخواست رمز عبور امن است، اما می تواند خسته کننده باشد، به خصوص در اجراهای مکرر، و همچنین مانع از اتوماسیون می شود. خوشبختانه، چند جایگزین برای این شرایط وجود دارد.

استفاده از Ansible Vault با یک فایل رمز عبور

اگر نمی‌خواهید هر بار که کاری را انجام می‌دهید رمز عبور Vault را تایپ کنید، می‌توانید رمز عبور Vault خود را به یک فایل اضافه کنید و در حین اجرا به فایل ارجاع دهید.

به عنوان مثال، می توانید رمز عبور خود را در یک فایل .vault_pass مانند این قرار دهید:

echo ‘my_vault_password’ > .vault_pass

اگر از کنترل نسخه استفاده می کنید، مطمئن شوید که فایل رمز عبور را به فایل نادیده گرفتن نرم افزار کنترل نسخه خود اضافه کنید تا از انجام تصادفی آن جلوگیری کنید:

echo ‘.vault_pass’ >> .gitignore

اکنون می توانید به جای آن به فایل ارجاع دهید. پرچم –vault-password-file در خط فرمان موجود است. می‌توانیم همان کار را از قسمت آخر با تایپ کردن کامل کنیم:

ansible –vault-password-file=.vault_pass -bK -m copy -a ‘src=secret_key dest=/tmp/secret_key mode=0600 owner=root group=root’ localhost

این بار رمز عبور Vault از شما خواسته نمی شود.

خواندن خودکار فایل رمز عبور

برای جلوگیری از ارائه پرچم، می توانید متغیر محیطی ANSIBLE_VAULT_PASSWORD_FILE را با مسیر فایل رمز عبور تنظیم کنید:

export ANSIBLE_VAULT_PASSWORD_FILE=./.vault_pass

اکنون باید بتوانید دستور را بدون پرچم –vault-password-file برای جلسه جاری اجرا کنید:

ansible -bK -m copy -a ‘src=secret_key dest=/tmp/secret_key mode=0600 owner=root group=root’ localhost

برای آگاه کردن Ansible از محل فایل رمز عبور در جلسات، می توانید فایل ansible.cfg خود را ویرایش کنید.

فایل ansible.cfg محلی را که قبلا ایجاد کردیم باز کنید:

nano ansible.cfg

در بخش [defaults]، تنظیمات vault_password_file را تنظیم کنید. به محل فایل رمز عبور خود اشاره کنید. این می تواند یک مسیر نسبی یا مطلق باشد، بسته به اینکه کدام یک برای شما مفیدتر است:

ansible.cfg

[defaults]
. . .
vault_password_file = ./.vault_pass

اکنون، وقتی دستوراتی را اجرا می‌کنید که نیاز به رمزگشایی دارند، دیگر از شما خواسته نمی‌شود که پسورد vault را وارد کنید. به عنوان یک امتیاز، ansible-vault نه تنها از رمز عبور موجود در فایل برای رمزگشایی هر فایلی استفاده می کند، بلکه رمز عبور را هنگام ایجاد فایل های جدید با ایجاد ansible-vault و ensible-vault encrypt اعمال می کند.

خواندن رمز عبور از یک متغیر محیطی

ممکن است نگران ارسال تصادفی فایل رمز عبور خود به مخزن خود باشید. در حالی که Ansible یک متغیر محیطی برای اشاره به محل یک فایل رمز عبور دارد، اما متغیری برای تنظیم رمز عبور ندارد.

با این حال، اگر فایل رمز عبور شما قابل اجرا باشد، Ansible آن را به عنوان یک اسکریپت اجرا می کند و از خروجی به عنوان رمز عبور استفاده می کند. در یکی از مشکلات GitHub، برایان شویند پیشنهاد می کند که از اسکریپت زیر می توان برای استخراج رمز عبور از یک متغیر محیطی استفاده کرد.

فایل .vault_pass خود را در ویرایشگر خود باز کنید:

nano .vault_pass

اسکریپت زیر را جایگزین محتویات کنید:

.vault_pass

#!/usr/bin/env python3

import os
print os.environ['VAULT_PASSWORD']

فایل را با تایپ کردن قابل اجرا کنید:

chmod +x .vault_pass

سپس می توانید متغیر محیطی VAULT_PASSWORD را تنظیم و صادر کنید، که برای جلسه فعلی شما در دسترس خواهد بود:

export VAULT_PASSWORD=my_vault_password

شما باید این کار را در ابتدای هر جلسه Ansible انجام دهید، که ممکن است ناخوشایند به نظر برسد. با این حال، این کار به طور موثری از انجام تصادفی رمز عبور رمزگذاری Vault شما محافظت می کند، که می تواند اشکالات جدی داشته باشد.

استفاده از متغیرهای رمزگذاری شده در Vault با متغیرهای منظم

در حالی که Ansible Vault را می توان با فایل های دلخواه استفاده کرد، اغلب برای محافظت از متغیرهای حساس استفاده می شود. ما از طریق یک مثال کار خواهیم کرد تا به شما نشان دهیم که چگونه یک فایل متغیرهای معمولی را به پیکربندی تبدیل کنید که امنیت و قابلیت استفاده را متعادل می کند.

تنظیم مثال

برای این مثال، ما وانمود می کنیم که در حال پیکربندی یک سرور پایگاه داده هستیم، بدون اینکه در واقع نیاز به نصب پایگاه داده به عنوان پیش نیاز داشته باشیم.

زمانی که فایل هاست را زودتر ایجاد کردید، ورودی لوکال هاست را در گروهی به نام پایگاه داده قرار دادید تا برای این مرحله آماده شوید. پایگاه های داده معمولاً به ترکیبی از متغیرهای حساس و غیر حساس نیاز دارند. اینها را می توان در یک پوشه group_vars در فایلی به نام گروه اختصاص داد:

mkdir -p group_vars
nano group_vars/database

در داخل فایل group_vars/database، چند متغیر معمولی اضافه می کنیم. برخی از متغیرها، مانند شماره پورت MySQL، مخفی نیستند و می توانند آزادانه به اشتراک گذاشته شوند. سایر متغیرها، مانند رمز عبور پایگاه داده، محرمانه خواهند بود:

group_vars/database

---
# nonsensitive data
mysql_port: 3306
mysql_host: 10.0.0.3
mysql_user: fred

# sensitive data
mysql_password: supersecretpassword

می‌توانیم آزمایش کنیم که همه متغیرها با ماژول اشکال زدایی Ansible و متغیر hostvars در دسترس میزبان ما هستند:

ansible -m debug -a ‘var=hostvars[inventory_hostname]’ database

 

Output

localhost | SUCCESS => {
    "hostvars[inventory_hostname]": {
        "ansible_check_mode": false, 
        "ansible_version": {
            "full": "2.2.0.0", 
            "major": 2, 
            "minor": 2, 
            "revision": 0, 
            "string": "2.2.0.0"
        }, 
        "group_names": [
            "database"
        ], 
        "groups": {
            "all": [
                "localhost"
            ], 
            "database": [
                "localhost"
            ], 
            "ungrouped": []
        }, 
        "inventory_dir": "/home/sammy", 
        "inventory_file": "hosts", 
        "inventory_hostname": "localhost", 
        "inventory_hostname_short": "localhost", 
        "mysql_host": "10.0.0.3",
        "mysql_password": "supersecretpassword",
        "mysql_port": 3306,
        "mysql_user": "fred",
        "omit": "__omit_place_holder__1c934a5a224ca1d235ff05eb9bda22044a6fb400", 
        "playbook_dir": "."
    }
}

خروجی تأیید می کند که همه متغیرهایی که ما تنظیم کرده ایم روی هاست اعمال می شوند. با این حال، فایل group_vars/database ما در حال حاضر همه متغیرهای ما را در خود جای می دهد. این بدان معناست که ما می‌توانیم آن را رمزگذاری نشده رها کنیم، که به دلیل متغیر رمز پایگاه داده یک نگرانی امنیتی است، یا همه متغیرها را رمزگذاری کنیم، که باعث ایجاد مشکلاتی در قابلیت استفاده و همکاری می‌شود.

انتقال متغیرهای حساس به Ansible Vault

برای حل این موضوع باید بین متغیرهای حساس و غیر حساس تفاوت قائل شویم. ما باید بتوانیم مقادیر محرمانه را رمزگذاری کنیم و در عین حال به راحتی متغیرهای غیر حساس خود را به اشتراک بگذاریم. برای انجام این کار، متغیرهای خود را بین دو فایل تقسیم می کنیم.

به منظور اعمال متغیرهای بیش از یک فایل، می توان از یک فهرست متغیر به جای فایل متغیر Ansible استفاده کرد. ما می توانیم پیکربندی خود را برای استفاده از این توانایی تغییر دهیم. ابتدا نام فایل موجود را از پایگاه داده به vars تغییر دهید. این فایل متغیر رمزگذاری نشده ما خواهد بود:

mv group_vars/database group_vars/vars

بعد، یک دایرکتوری با همان نام فایل متغیر قدیمی ایجاد کنید. فایل vars را به داخل منتقل کنید:

mkdir group_vars/database
mv group_vars/vars group_vars/database/

ما اکنون به جای یک فایل، یک دایرکتوری متغیر برای گروه پایگاه داده داریم و یک فایل متغیر رمزگذاری نشده داریم. از آنجایی که متغیرهای حساس خود را رمزگذاری خواهیم کرد، باید آنها را از فایل رمزگذاری نشده خود حذف کنیم. برای حذف داده های محرمانه، فایل group_vars/database/vars را ویرایش کنید:

nano group_vars/database/vars

در این صورت می خواهیم متغیر mysql_password را حذف کنیم. اکنون فایل باید به شکل زیر باشد:

group_vars/database/vars

---
# nonsensitive data
mysql_port: 3306
mysql_host: 10.0.0.3
mysql_user: fred

سپس، یک فایل رمزگذاری شده با طاق در دایرکتوری ایجاد کنید که در کنار فایل vars رمزگذاری نشده زندگی می کند:

ansible-vault create group_vars/database/vault

در این فایل متغیرهای حساسی که قبلا در فایل vars وجود داشت را تعریف کنید. از نام متغیرهای یکسانی استفاده کنید، اما رشته vault_ را برای نشان دادن اینکه این متغیرها در فایل محافظت شده توسط vault تعریف شده اند، پیشاپیش قرار دهید:

group_vars/database/vault

---
vault_mysql_password: supersecretpassword

پس از اتمام کار فایل را ذخیره کرده و ببندید.

ساختار دایرکتوری حاصل به این صورت است:

.
├── . . .
├── group_vars/
│   └── database/
│       ├── vars
│       └── vault
└── . . .

در این مرحله، متغیرها جدا هستند و فقط داده های محرمانه رمزگذاری می شوند. این امن است، اما اجرای ما بر قابلیت استفاده ما تأثیر گذاشته است. در حالی که هدف ما محافظت از مقادیر حساس بود، همچنین ناخواسته دید را به نام متغیرهای واقعی کاهش دادیم. مشخص نیست که کدام متغیرها بدون ارجاع به بیش از یک فایل اختصاص داده شده اند، و در حالی که ممکن است بخواهید دسترسی به داده های محرمانه را در حین همکاری محدود کنید، هنوز احتمالاً می خواهید نام متغیرها را به اشتراک بگذارید.

برای پرداختن به این موضوع، پروژه Ansible به طور کلی رویکرد کمی متفاوت را توصیه می کند.

ارجاع به متغیرهای Vault از متغیرهای رمزگذاری نشده

هنگامی که ما داده های حساس خود را به فایل محافظت شده در طاق انتقال دادیم، نام متغیرها را با vault_ در پیش گفتیم (mysql_password تبدیل به vault_mysql_password شد). ما می توانیم نام متغیرهای اصلی (mysql_password) را به فایل رمزگذاری نشده اضافه کنیم. به‌جای تنظیم مستقیم این مقادیر روی مقادیر حساس، می‌توانیم از عبارات قالب‌بندی Jinja2 برای ارجاع نام متغیرهای رمزگذاری‌شده از داخل فایل متغیر رمزگذاری نشده خود استفاده کنیم. به این ترتیب، می توانید با ارجاع به یک فایل، همه متغیرهای تعریف شده را مشاهده کنید، اما مقادیر محرمانه در فایل رمزگذاری شده باقی می مانند.

برای نشان دادن، فایل متغیرهای رمزگذاری نشده را دوباره باز کنید:

nano group_vars/database/vars

دوباره متغیر mysql_password را اضافه کنید. این بار، از قالب Jinja2 برای ارجاع به متغیر تعریف شده در فایل محافظت شده از طاق استفاده کنید:

group_vars/database/vars

---
# nonsensitive data
mysql_port: 3306
mysql_host: 10.0.0.3
mysql_user: fred

# sensitive data
mysql_password: "{{ vault_mysql_password }}"

متغیر mysql_password به مقدار متغیر vault_mysql_password که در فایل vault تعریف شده تنظیم می شود.

با این روش می توانید با مشاهده فایل group_vars/database/vars، تمامی متغیرهایی را که بر روی هاست های گروه پایگاه داده اعمال می شود، درک کنید. قسمت های حساس توسط قالب Jinja2 محو می شوند. group_vars/database/vault تنها زمانی باید باز شود که خود مقادیر نیاز به مشاهده یا تغییر داشته باشند.

می توانید بررسی کنید تا مطمئن شوید که همه متغیرهای mysql_* هنوز به درستی با استفاده از همان روش دفعه قبل اعمال می شوند.

ansible -m debug -a ‘var=hostvars[inventory_hostname]’ database

 

Output

localhost | SUCCESS => {
    "hostvars[inventory_hostname]": {
        "ansible_check_mode": false, 
        "ansible_version": {
            "full": "2.2.0.0", 
            "major": 2, 
            "minor": 2, 
            "revision": 0, 
            "string": "2.2.0.0"
        }, 
        "group_names": [
            "database"
        ], 
        "groups": {
            "all": [
                "localhost"
            ], 
            "database": [
                "localhost"
            ], 
            "ungrouped": []
        }, 
        "inventory_dir": "/home/sammy/vault", 
        "inventory_file": "./hosts", 
        "inventory_hostname": "localhost", 
        "inventory_hostname_short": "localhost", 
        "mysql_host": "10.0.0.3",
        "mysql_password": "supersecretpassword",
        "mysql_port": 3306,
        "mysql_user": "fred",
        "omit": "__omit_place_holder__6dd15dda7eddafe98b6226226c7298934f666fc8", 
        "playbook_dir": ".", 
        "vault_mysql_password": "supersecretpassword"
    }
}

هم vault_mysql_password و هم mysql_password قابل دسترسی هستند. این تکرار بی ضرر است و تاثیری در استفاده شما از این سیستم نخواهد داشت.

نتیجه

پروژه های شما باید تمام اطلاعات مورد نیاز برای نصب و پیکربندی موفقیت آمیز سیستم های پیچیده را داشته باشند. با این حال، برخی از داده‌های پیکربندی طبق تعریف حساس هستند و نباید در معرض عموم قرار گیرند. در این راهنما، ما نشان دادیم که چگونه Ansible Vault می تواند اطلاعات محرمانه را رمزگذاری کند تا بتوانید تمام داده های پیکربندی خود را در یک مکان بدون به خطر انداختن امنیت نگه دارید.

Ansible VaultVPS یا سرور مجازیاتصال به لینوکسخرید سرور مجازیسرور اوبونتو 20.04سرور مجازیسرور مجازی آلمانسرور مجازی آمریکامتغیرهای Vault

 

 

https://vpsgol.net/product/vps-germany/

 

https://vpsgol.net/product/vps-usa/

 

https://vpsgol.net/product/vps-france/

 

https://vpsgol.net/product/vps-canada/

 

https://vpsgol.net/product/vps-poland/

 

https://vpsgol.net/product/vps-netherlands/

 

https://vpsgol.net/product/vps-england/

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه تنظیم نوت بوک Jupyter برای Python 3

ورود به سایت

معرفی

Jupyter Notebook یک پوسته فرمان برای محاسبات تعاملی به عنوان یک برنامه وب ارائه می دهد. این ابزار را می توان با چندین زبان از جمله Python، Julia، R، Haskell و Ruby استفاده کرد. اغلب برای کار با داده ها، مدل سازی آماری و یادگیری ماشین استفاده می شود.

این آموزش شما را در راه اندازی نوت بوک Jupyter برای اجرا به صورت محلی یا از سرور اوبونتو 20.04 راهنمایی می کند و همچنین نحوه اتصال و استفاده از نوت بوک را به شما آموزش می دهد. نوت‌بوک‌های Jupyter (یا به سادگی نوت‌بوک‌ها) اسنادی هستند که توسط برنامه نوت‌بوک Jupyter تولید می‌شوند که حاوی کدهای کامپیوتری و عناصر متن غنی (پاراگراف، معادلات، شکل‌ها، پیوندها و غیره) هستند که به ارائه و به اشتراک‌گذاری تحقیقات قابل تکرار کمک می‌کنند.

در پایان این راهنما، می‌توانید کد پایتون 3 را با استفاده از نوت‌بوک Jupyter که روی یک ماشین محلی یا سرور راه دور اجرا می‌شود، اجرا کنید.

پیش نیازها

برای دنبال کردن این آموزش، به یک محیط برنامه نویسی پایتون 3 نیز نیاز دارید

  • در دستگاه محلی شما، یا
  • روی سرور اوبونتو

تمام دستورات این آموزش باید به صورت یک کاربر غیر روت اجرا شوند. اگر دسترسی root برای دستور مورد نیاز باشد، قبل از دستور sudo قرار می گیرد. راه اندازی اولیه سرور با اوبونتو 20.04 نحوه اضافه کردن کاربران و دادن دسترسی sudo را توضیح می دهد.

مرحله 1 – نصب نوت بوک Jupyter

در این قسمت نوت بوک Jupyter را با pip نصب می کنیم.

محیط برنامه نویسی Python 3 را که می خواهید Jupyter Notebook را در آن نصب کنید، فعال کنید. در مثال خود، آن را در my_env نصب می‌کنیم، بنابراین مطمئن می‌شویم که در دایرکتوری آن محیط هستیم و آن را به این صورت فعال می‌کنیم:

cd ~/environments
. my_env/bin/activate

در مرحله بعد، می توانیم اطمینان حاصل کنیم که پیپ به آخرین نسخه ارتقا یافته است:

pip install –upgrade pip

حالا می توانیم Jupyter Notebook را با دستور زیر نصب کنیم:

pip install jupyter

در این مرحله Jupyter Notebook در محیط برنامه نویسی فعلی نصب می شود.

مرحله اختیاری بعدی برای کسانی است که نصب سرور رابط وب را با استفاده از تونل SSH متصل می کنند.

مرحله 2 (اختیاری) – استفاده از SSH Tunneling برای اتصال به نصب سرور

اگر نوت بوک Jupyter را روی سرور نصب کرده اید، در این بخش نحوه اتصال به رابط وب Jupyter Notebook با استفاده از تونل SSH را یاد می گیریم. از آنجایی که Jupyter Notebook بر روی یک پورت خاص روی سرور اجرا می شود (مانند :8888، :8889 و غیره)، تونل SSH شما را قادر می سازد تا به طور ایمن به پورت سرور متصل شوید.

توجه داشته باشید که این دستورالعمل‌ها طوری طراحی شده‌اند که از یک پنجره ترمینال محلی اجرا شوند، یعنی نه از پنجره‌ای که با آن به سرور متصل شده‌اید.

SSH Tunneling

اگر از ویندوز استفاده می کنید، باید نسخه ای از OpenSSH را نصب کنید تا بتوانید از ترمینال ssh کنید. اگر ترجیح می دهید در PowerShell کار کنید، می توانید اسناد مایکروسافت را برای اضافه کردن OpenSSH به PowerShell دنبال کنید. اگر ترجیح می‌دهید یک محیط لینوکس کامل در دسترس داشته باشید، می‌توانید WSL، زیرسیستم ویندوز برای لینوکس را راه‌اندازی کنید، که به طور پیش‌فرض شامل ssh می‌شود. در نهایت، به عنوان گزینه سوم سبک، می‌توانید Git را برای ویندوز نصب کنید، که یک محیط ترمینال bash ویندوز که شامل دستور ssh می‌شود را فراهم می‌کند. هر کدام از این ها به خوبی پشتیبانی می شوند و هر کدام را که تصمیم به استفاده از آن داشته باشید به اولویت شما بستگی دارد.

اگر از مک یا لینوکس استفاده می کنید، از قبل دستور ssh را در ترمینال خود خواهید داشت.

مراحل ایجاد یک SSH tunneling شبیه نحوه اتصال به قطرات با راهنمای SSH است با این تفاوت که پارامترهای اضافی در دستور ssh اضافه شده است. این زیربخش پارامترهای اضافی مورد نیاز در دستور ssh برای تونل موفقیت آمیز را تشریح می کند.

SSH tunneling را می توان با اجرای دستور SSH زیر در یک پنجره ترمینال محلی جدید انجام داد:

ssh -L 8888:localhost:8888 your_server_username@your_server_ip

دستور ssh یک اتصال SSH را باز می کند، اما -L مشخص می کند که پورت داده شده در میزبان محلی (کلینت) باید به هاست و پورت در سمت راه دور (سرور) ارسال شود. این بدان معناست که هر چیزی که روی شماره پورت دوم (به عنوان مثال 8888) در سرور اجرا می شود، در اولین شماره پورت (مثلاً 8888) در رایانه محلی شما ظاهر می شود.

اگر پیامی دریافت کردید که پورت 8888 در دسترس نیست، می توانید آن را به شماره پورت دلخواه دیگری زیر 65535 تغییر دهید. پورت 8888 معنای مهمی ندارد اما اغلب برای دموهایی مانند این استفاده می شود.

server_username نام کاربری شما (به عنوان مثال sammy) در سروری است که ایجاد کرده اید و your_server_ip آدرس IP سرور شما است.

به عنوان مثال، برای نام کاربری sammy و آدرس سرور 203.0.113.0، دستور به صورت زیر خواهد بود:

ssh -L 8888:localhost:8888 sammy@203.0.113.0

اگر پس از اجرای دستور ssh -L خطایی نشان داده نشد، می توانید به محیط برنامه نویسی خود بروید و Jupyter Notebook را اجرا کنید:

jupyter notebook

خروجی را با URL دریافت خواهید کرد. از یک مرورگر وب در دستگاه محلی خود، رابط وب Jupyter Notebook را با URL که با http://localhost:8888 شروع می شود، باز کنید. اطمینان حاصل کنید که شماره رمز گنجانده شده است یا در صورت درخواست در http://localhost:8888 رشته شماره رمز را وارد کنید.

مرحله 3 – اجرای نوت بوک Jupyter

با نصب نوت بوک Jupyter، می توانید آن را در ترمینال خود اجرا کنید. برای این کار دستور زیر را اجرا کنید:

jupyter notebook

گزارشی از فعالیت های نوت بوک Jupyter در ترمینال چاپ می شود. هنگامی که Jupyter Notebook را اجرا می کنید، روی یک شماره پورت خاص اجرا می شود. اولین نوت‌بوکی که اجرا می‌کنید معمولاً روی پورت 8888 اجرا می‌شود. برای بررسی شماره پورت خاصی که Jupyter Notebook روی آن اجرا می‌شود، به خروجی دستور استفاده شده برای شروع آن مراجعه کنید:

 

Output

[I NotebookApp] Serving notebooks from local directory: /home/sammy
[I NotebookApp] 0 active kernels 
[I NotebookApp] The Jupyter Notebook is running at: http://localhost:8888/
[I NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
...

اگر Jupyter Notebook را روی یک رایانه محلی (نه روی سرور) اجرا می کنید، مرورگر پیش فرض شما باید برنامه وب Jupyter Notebook را باز کرده باشد. اگر نه، یا اگر پنجره را ببندید، می توانید به URL ارائه شده در خروجی بروید یا برای اتصال به localhost:8888 بروید.

هر زمان که می‌خواهید فرآیند Jupyter Notebook را متوقف کنید، Ctrl+C را فشار دهید، زمانی که از شما خواسته شد Y را تایپ کنید و سپس Enter را برای تأیید فشار دهید.

خروجی زیر را دریافت خواهید کرد:

 

Output

[C 12:32:23.792 NotebookApp] Shutdown confirmed
[I 12:32:23.794 NotebookApp] Shutting down kernels

Jupyter Notebook اکنون دیگر کار نمی کند.

مرحله 4 – استفاده از نوت بوک Jupyter

این بخش به اصول استفاده از نوت بوک Jupyter می پردازد. اگر در حال حاضر Jupyter Notebook را در حال اجرا ندارید، آن را با دستور jupyter notebook شروع کنید.

اکنون باید با استفاده از یک مرورگر وب به آن متصل شوید. نوت بوک Jupyter بسیار قدرتمند است و ویژگی های زیادی دارد. در این بخش چند مورد از ویژگی‌های اساسی برای شروع استفاده از نوت‌بوک توضیح داده می‌شود. Jupyter Notebook همه فایل‌ها و پوشه‌ها را در فهرستی که از آن اجرا می‌شود نشان می‌دهد، بنابراین وقتی روی پروژه کار می‌کنید، مطمئن شوید که آن را از فهرست پروژه شروع کنید.

برای ایجاد یک فایل نوت بوک جدید، New > Python 3 را از منوی کشویی بالا سمت راست انتخاب کنید:

با این کار یک نوت بوک باز می شود. اکنون می‌توانیم کد پایتون را در سلول اجرا کنیم یا سلول را به markdown تغییر دهیم. برای مثال، با کلیک روی Cell > Cell Type > Markdown از نوار پیمایش بالا، اولین سلول را برای پذیرش Markdown تغییر دهید. اکنون می‌توانیم یادداشت‌هایی را با استفاده از Markdown بنویسیم و حتی معادلات نوشته‌شده در LaTeX را با قرار دادن آنها بین نمادهای $$ اضافه کنیم. به عنوان مثال، پس از تغییر سلول به علامت گذاری، عبارت زیر را در سلول تایپ کنید:

# Simple Equation

Let us now implement the following equation:
$$ y = x^2$$

where $x = 2$

برای تبدیل علامت گذاری به متن غنی، Ctrl+Enter را فشار دهید و نتایج زیر باید باشد:

می توانید از سلول های علامت گذاری برای یادداشت برداری و مستندسازی کد خود استفاده کنید. بیایید آن معادله ساده را پیاده سازی کنیم و نتیجه را چاپ کنیم. روی سلول بالا کلیک کنید، سپس Alt+Enter را فشار دهید تا یک سلول زیر آن اضافه شود. کد زیر را در سلول جدید وارد کنید.

x = 2
y = x**2
print(y)

برای اجرای کد، Ctrl+Enter را فشار دهید. نتایج زیر را دریافت خواهید کرد:

اکنون می توانید ماژول ها را وارد کنید و از نوت بوک مانند سایر محیط های توسعه پایتون استفاده کنید!

برای خاموش کردن نوت بوک Jupyter سمت سرور، به پنجره ترمینال که آن را از آنجا شروع کرده اید بازگردید و Ctrl+C را فشار دهید. این یک میانبر استاندارد برای پایان دادن به فرآیندهای ترمینال است و Jupyter از شما می خواهد قبل از خروج ذخیره کنید.

نتیجه

تبریک می گویم! اکنون باید بتوانید کدها و یادداشت های قابل تکرار پایتون را با استفاده از Jupyter Notebook در Markdown بنویسید. برای دریافت یک تور سریع از Jupyter Notebook از داخل رابط، Help > User Interface Tour را از منوی پیمایش بالا انتخاب کنید تا بیشتر بدانید.


 

https://vpsgol.net/product/vps-germany/

 

https://vpsgol.net/product/vps-usa/

 

https://vpsgol.net/product/vps-france/

 

https://vpsgol.net/product/vps-canada/

 

https://vpsgol.net/product/vps-poland/

 

https://vpsgol.net/product/vps-netherlands/

 

https://vpsgol.net/product/vps-england/

 

برچسب‌ها:SSH TunnelingUbuntu VPSاتصال به سرور مجازیخرید سرور مجازیسرور اوبونتو 20.04فروش سرور مجازینحوه تنظیم نوت بوک Jupyterنصب سرورنصب نوت بوک Jupyter

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه نصب Nginx در اوبونتو 20.04

ورود به سایت

معرفی

Nginx یکی از محبوب ترین وب سرورها در جهان است و مسئولیت میزبانی برخی از بزرگترین و پربازدیدترین سایت های اینترنت را بر عهده دارد. این یک انتخاب سبک وزن است که می تواند به عنوان وب سرور یا پروکسی معکوس استفاده شود.

در این راهنما، نحوه نصب Nginx بر روی سرور اوبونتو 20.04، تنظیم فایروال، مدیریت فرآیند Nginx و راه اندازی بلوک های سرور برای میزبانی بیش از یک دامنه از یک سرور واحد را مورد بحث قرار خواهیم داد.

پیش نیازها

قبل از شروع این راهنما، باید یک کاربر معمولی و غیر ریشه با امتیازات sudo پیکربندی شده روی سرور خود داشته باشید.

هنگامی که یک حساب کاربری در دسترس دارید، برای شروع به عنوان کاربر غیر روت وارد شوید.

مرحله 1 – نصب Nginx

از آنجایی که Nginx در مخازن پیش‌فرض اوبونتو موجود است، می‌توان آن را از این مخازن با استفاده از سیستم بسته‌بندی apt نصب کرد.

از آنجایی که این اولین تعامل ما با سیستم بسته بندی apt در این جلسه است، فهرست بسته محلی خود را به روز می کنیم تا به آخرین لیست های بسته دسترسی داشته باشیم. پس از آن، می توانیم nginx را نصب کنیم:

sudo apt update

sudo apt install nginx

پس از پذیرش رویه، apt Nginx و هر گونه وابستگی مورد نیاز را روی سرور شما نصب خواهد کرد.

مرحله 2 – تنظیم فایروال

قبل از آزمایش Nginx، نرم افزار فایروال باید تنظیم شود تا امکان دسترسی به سرویس فراهم شود. Nginx پس از نصب خود را به عنوان یک سرویس در ufw ثبت می‌کند و اجازه دسترسی به Nginx را آسان می‌کند.

پیکربندی های برنامه ای را که ufw می داند چگونه با آنها کار کند با تایپ کردن فهرست کنید:

sudo ufw app list

شما باید لیستی از پروفایل های برنامه دریافت کنید:

 

Output

Available applications:
  Nginx Full
  Nginx HTTP
  Nginx HTTPS
  OpenSSH

همانطور که در خروجی نشان داده شده است، سه نمایه برای Nginx وجود دارد:

  • Nginx Full: این نمایه هم پورت 80 (ترافیک وب عادی و رمزگذاری نشده) و هم پورت 443 (ترافیک رمزگذاری شده TLS/SSL) را باز می کند.
  • Nginx HTTP: این نمایه فقط پورت 80 را باز می کند (ترافیک وب عادی و رمزگذاری نشده)
  • Nginx HTTPS: این نمایه فقط پورت 443 را باز می کند (ترافیک رمزگذاری شده TLS/SSL)

توصیه می شود محدودترین نمایه را فعال کنید که همچنان به ترافیکی که پیکربندی کرده اید اجازه دهد. در حال حاضر، فقط باید اجازه دهیم ترافیک در پورت 80 وجود داشته باشد.

شما می توانید این را با تایپ کردن فعال کنید:

sudo ufw allow ‘Nginx HTTP’

می توانید با تایپ کردن این تغییر را تأیید کنید:

sudo ufw status

خروجی نشان می دهد که کدام ترافیک HTTP مجاز است:

 

Output

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                  
Nginx HTTP                 ALLOW       Anywhere                  
OpenSSH (v6)               ALLOW       Anywhere (v6)             
Nginx HTTP (v6)            ALLOW       Anywhere (v6)

مرحله 3 – وب سرور خود را بررسی کنید

در پایان مراحل نصب، اوبونتو 20.04 Nginx را راه اندازی می کند. وب سرور باید از قبل راه اندازی شده باشد.

می‌توانیم با تایپ کردن:

systemctl status nginx

 

Output

● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2020-04-20 16:08:19 UTC; 3 days ago
     Docs: man:nginx(8)
 Main PID: 2369 (nginx)
    Tasks: 2 (limit: 1153)
   Memory: 3.5M
   CGroup: /system.slice/nginx.service
           ├─2369 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
           └─2380 nginx: worker process

همانطور که در این مورد تایید شد، این سرویس با موفقیت شروع شده است. با این حال، بهترین راه برای آزمایش این است که واقعاً یک صفحه از Nginx درخواست کنید.

می‌توانید با پیمایش به آدرس IP سرور خود، به صفحه فرود پیش‌فرض Nginx دسترسی پیدا کنید تا تأیید کنید که نرم‌افزار به درستی اجرا می‌شود. اگر آدرس IP سرور خود را نمی دانید، می توانید آن را با استفاده از ابزار icanhazip.com پیدا کنید، که آدرس IP عمومی شما را همانطور که از مکان دیگری در اینترنت دریافت کرده اید به شما می دهد:

curl -4 icanhazip.com

وقتی آدرس IP سرور خود را دارید، آن را در نوار آدرس مرورگر خود وارد کنید:

http://your_server_ip

شما باید صفحه فرود پیش فرض Nginx را دریافت کنید:

اگر در این صفحه هستید، سرور شما به درستی کار می کند و آماده مدیریت است.

مرحله 4 – مدیریت فرآیند Nginx

اکنون که وب سرور خود را راه‌اندازی کرده‌اید، اجازه دهید برخی از دستورات مدیریتی اولیه را مرور کنیم.

برای متوقف کردن وب سرور خود، تایپ کنید:

sudo systemctl stop nginx

برای راه اندازی وب سرور در صورت توقف، تایپ کنید:

sudo systemctl start nginx

برای توقف و سپس شروع مجدد سرویس، تایپ کنید:

sudo systemctl restart nginx

اگر فقط تغییرات پیکربندی را انجام می دهید، Nginx اغلب می تواند بدون حذف اتصالات، بارگیری مجدد کند. برای انجام این کار، تایپ کنید:

sudo systemctl reload nginx

به‌طور پیش‌فرض، Nginx طوری پیکربندی شده است که هنگام بوت شدن سرور، به‌طور خودکار شروع به کار کند. اگر این چیزی نیست که شما می خواهید، می توانید این رفتار را با تایپ کردن غیرفعال کنید:

sudo systemctl disable nginx

برای فعال کردن مجدد سرویس برای راه اندازی در هنگام بوت، می توانید تایپ کنید:

sudo systemctl enable nginx

شما اکنون دستورات مدیریتی اولیه را یاد گرفته اید و باید آماده پیکربندی سایت برای میزبانی بیش از یک دامنه باشید.

مرحله 5 – راه اندازی بلوک های سرور (توصیه می شود)

هنگام استفاده از وب سرور Nginx، بلوک های سرور (مشابه میزبان های مجازی در آپاچی) می توانند برای کپسوله کردن جزئیات پیکربندی و میزبانی بیش از یک دامنه از یک سرور استفاده شوند. ما دامنه ای به نام your_domain راه اندازی خواهیم کرد، اما شما باید آن را با نام دامنه خود جایگزین کنید.

Nginx در اوبونتو 20.04 دارای یک بلوک سرور است که به طور پیش فرض فعال شده است که برای ارائه اسناد خارج از دایرکتوری در /var/www/html پیکربندی شده است. در حالی که این برای یک سایت خوب کار می کند، اگر چندین سایت را میزبانی کنید، می تواند سخت شود. به جای تغییر /var/www/html، بیایید یک ساختار دایرکتوری در /var/www برای سایت your_domain خود ایجاد کنیم، و در صورت عدم مطابقت با درخواست مشتری، /var/www/html را به عنوان دایرکتوری پیش‌فرض باقی می‌گذاریم تا ارائه شود. سایت های دیگر

دایرکتوری برای your_domain به صورت زیر ایجاد کنید، با استفاده از پرچم -p برای ایجاد هر دایرکتوری والد ضروری:

sudo mkdir -p /var/www/your_domain/html

سپس، مالکیت دایرکتوری را با متغیر محیطی $USER اختصاص دهید:

sudo chown -R $USER:$USER /var/www/your_domain/html

اگر مقدار umask خود را که مجوزهای فایل پیش فرض را تنظیم می کند، تغییر نداده اید، مجوزهای ریشه های وب شما باید صحیح باشد. برای اطمینان از صحیح بودن مجوزهای شما و اجازه به مالک برای خواندن، نوشتن و اجرای فایل ها در حالی که فقط مجوزهای خواندن و اجرا را به گروه ها و سایرین اعطا می کند، می توانید دستور زیر را وارد کنید:

sudo chmod -R 755 /var/www/your_domain

سپس، یک صفحه نمونه index.html با استفاده از nano یا ویرایشگر مورد علاقه خود ایجاد کنید:

nano /var/www/your_domain/html/index.html

در داخل، نمونه HTML زیر را اضافه کنید:

/var/www/your_domain/html/index.html

<html>
    <head>
        <title>Welcome to your_domain!</title>
    </head>
    <body>
        <h1>Success!  The your_domain server block is working!</h1>
    </body>
</html>

با فشار دادن Ctrl+X برای خروج، فایل را ذخیره کرده و ببندید، سپس وقتی از شما خواسته شد که ذخیره کنید، Y و سپس Enter را فشار دهید.

برای اینکه Nginx بتواند این محتوا را ارائه دهد، لازم است یک بلوک سرور با دستورالعمل های صحیح ایجاد کنید. به جای اینکه مستقیماً فایل پیکربندی پیش‌فرض را تغییر دهیم، بیایید یک فایل جدید در /etc/nginx/sites-available/your_domain ایجاد کنیم:

sudo nano /etc/nginx/sites-available/your_domain

در بلوک پیکربندی زیر، که شبیه به پیش‌فرض است، اما برای فهرست و نام دامنه جدید ما به‌روزرسانی شده است، قرار دهید:

/etc/nginx/sites-available/your_domain

server {
        listen 80;
        listen [::]:80;

        root /var/www/your_domain/html;
        index index.html index.htm index.nginx-debian.html;

        server_name your_domain www.your_domain;

        location / {
                try_files $uri $uri/ =404;
        }
}

توجه داشته باشید که ما پیکربندی root را به دایرکتوری جدید خود و server_name را به نام دامنه خود به روز کرده ایم.

سپس، بیایید فایل را با ایجاد پیوندی از آن به دایرکتوری فعال شده توسط سایت‌ها، که Nginx هنگام راه‌اندازی از آن می‌خواند، فعال کنیم:

sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/

اکنون دو بلوک سرور برای پاسخگویی به درخواست‌ها بر اساس دستورالعمل‌های listen و server_name فعال و پیکربندی شده‌اند (شما می‌توانید در مورد نحوه پردازش Nginx این دستورالعمل‌ها را در اینجا بیشتر بخوانید):

your_domain: به درخواست های your_domain و www.your_domain پاسخ می دهد.
پیش فرض: به هر درخواستی در پورت 80 که با دو بلوک دیگر مطابقت ندارد پاسخ می دهد.
برای جلوگیری از مشکل احتمالی حافظه سطل هش که ممکن است در اثر افزودن نام سرور اضافی ایجاد شود، لازم است یک مقدار واحد را در فایل /etc/nginx/nginx.conf تنظیم کنید. فایل را باز کنید:

sudo nano /etc/nginx/nginx.conf

دستور server_names_hash_bucket_size را پیدا کنید و برای لغو نظر خط، نماد # را بردارید. اگر از nano استفاده می‌کنید، می‌توانید با فشردن CTRL و w به سرعت کلمات موجود در فایل را جستجو کنید.

/etc/nginx/nginx.conf

...
http {
    ...
    server_names_hash_bucket_size 64;
    ...
}
...

پس از اتمام کار فایل را ذخیره کرده و ببندید.

در مرحله بعد، آزمایش کنید تا مطمئن شوید که در هیچ یک از فایل های Nginx شما خطای نحوی وجود ندارد:

sudo nginx -t

اگر مشکلی وجود ندارد، Nginx را مجددا راه اندازی کنید تا تغییرات شما فعال شود:

sudo systemctl restart nginx

Nginx اکنون باید نام دامنه شما را ارائه دهد. می توانید این را با رفتن به http://your_domain آزمایش کنید، جایی که باید چیزی شبیه به این را ببینید:

مرحله 6 – آشنایی با فایل ها و دایرکتوری های مهم Nginx

اکنون که می دانید چگونه خود سرویس Nginx را مدیریت کنید، باید چند دقیقه وقت بگذارید تا با چند فهرست و فایل مهم آشنا شوید.

محتوا

/var/www/html: محتوای واقعی وب، که به طور پیش‌فرض فقط از صفحه پیش‌فرض Nginx تشکیل شده است که قبلاً دیده‌اید، خارج از فهرست /var/www/html ارائه می‌شود. این را می توان با تغییر فایل های پیکربندی Nginx تغییر داد.

پیکربندی سرور

  • /etc/nginx: دایرکتوری پیکربندی Nginx. همه فایل های پیکربندی Nginx در اینجا قرار دارند.
  • /etc/nginx/nginx.conf: فایل پیکربندی اصلی Nginx. این را می توان برای ایجاد تغییرات در پیکربندی جهانی Nginx تغییر داد.
  • /etc/nginx/sites-available/: فهرستی که می‌توان بلوک‌های سرور هر سایت را در آن ذخیره کرد. Nginx از فایل های پیکربندی موجود در این دایرکتوری استفاده نمی کند مگر اینکه به دایرکتوری فعال شده سایت ها پیوند داده شده باشند. به طور معمول، تمام پیکربندی بلوک سرور در این دایرکتوری انجام می شود و سپس با پیوند دادن به دایرکتوری دیگر فعال می شود.
  • /etc/nginx/sites-enabled/: فهرستی که در آن بلوک‌های سرور فعال در هر سایت ذخیره می‌شوند. به طور معمول، این ها با پیوند دادن به فایل های پیکربندی موجود در فهرست سایت های موجود ایجاد می شوند.
  • /etc/nginx/snippets: این دایرکتوری شامل قطعات پیکربندی است که می تواند در جای دیگری از پیکربندی Nginx گنجانده شود. بخش‌های پیکربندی بالقوه تکرارپذیر، کاندیدهای خوبی برای تبدیل مجدد به قطعه‌ها هستند.

گزارش های سرور

  • /var/log/nginx/access.log: هر درخواست به سرور وب شما در این فایل گزارش ثبت می‌شود، مگر اینکه Nginx به گونه‌ای دیگر پیکربندی شده باشد.
  • /var/log/nginx/error.log: هر گونه خطای Nginx در این گزارش ثبت می شود.

نتیجه

اکنون که وب سرور خود را نصب کرده اید، گزینه های زیادی برای نوع محتوا و فناوری هایی که می خواهید برای ایجاد یک تجربه غنی تر استفاده کنید، دارید.

 


 

https://vpsgol.net/product/vps-germany/

 

https://vpsgol.net/product/vps-usa/

 

https://vpsgol.net/product/vps-france/

 

https://vpsgol.net/product/vps-canada/

 

https://vpsgol.net/product/vps-poland/

 

https://vpsgol.net/product/vps-netherlands/

 

https://vpsgol.net/product/vps-england/

 

 

برچسب‌ها:Nginx در اوبونتو 20.04خرید سرورخرید سرور لینوکسخرید سرور مجازیراه اندازی وب سرورسرور اوبونتو 20.04سرور مجازی آمریکانحوه نصب Nginxوب سرور

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه نصب و مدیریت Supervisor

ورود به سایت

معرفی

در بسیاری از محیط‌های VPS، معمولاً تعدادی برنامه کوچک خواهید داشت که می‌خواهید دائماً اجرا کنید، چه اسکریپت‌های پوسته کوچک، برنامه‌های Node.js یا هر بسته‌ای با اندازه بزرگ.

معمولاً بسته‌های خارجی با یک فایل واحد عرضه می‌شوند که به آنها اجازه می‌دهد توسط یک سیستم init مانند systemd مدیریت شوند یا به‌عنوان تصاویر docker بسته‌بندی شوند که می‌توانند توسط یک موتور کانتینر مدیریت شوند. با این حال، برای نرم افزارهایی که به خوبی بسته بندی نشده اند، یا برای کاربرانی که ترجیح می دهند با سیستم init سطح پایین روی سرور خود تعامل نداشته باشند، داشتن یک جایگزین سبک مفید است.

Supervisor یک مدیر فرآیند است که یک رابط منحصر به فرد برای مدیریت و نظارت بر تعدادی از برنامه های طولانی مدت ارائه می دهد. در این آموزش، Supervisor را بر روی یک سرور لینوکس نصب می‌کنید و یاد می‌گیرید که چگونه تنظیمات Supervisor را برای چندین برنامه مدیریت کنید.

پیش نیازها

برای تکمیل این راهنما، شما نیاز دارید:

  • یک سرور لینوکس و یک کاربر غیر ریشه با امتیازات sudo.

مرحله 1 – نصب

با نصب Supervisor شروع کنید:

sudo apt install supervisor

سرویس سرپرست پس از نصب به طور خودکار اجرا می شود. می توانید وضعیت آن را بررسی کنید:

sudo systemctl status supervisor

شما باید خروجی زیر را دریافت کنید:

 

Output

● supervisor.service - Supervisor process control system for UNIX
     Loaded: loaded (/lib/systemd/system/supervisor.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2021-11-17 22:56:48 UTC; 5min ago

اکنون که Supervisor را نصب کرده ایم، می توانیم اولین برنامه های خود را اضافه کنیم.

مرحله 2 – اضافه کردن یک برنامه

بهترین روش برای کار با Supervisor نوشتن یک فایل پیکربندی برای هر برنامه ای است که مدیریت می کند.

به منظور نشان دادن عملکرد Supervisor، ما یک اسکریپت پوسته ایجاد می کنیم که کاری جز تولید یک خروجی قابل پیش بینی در ثانیه انجام نمی دهد، اما به طور مداوم در پس زمینه اجرا می شود تا زمانی که به صورت دستی متوقف شود. با استفاده از nano یا ویرایشگر متن مورد علاقه خود، فایلی به نام idle.sh را در فهرست اصلی خود باز کنید:

nano ~/idle.sh

مطالب زیر را اضافه کنید:

~/idle.sh

#!/bin/bash
while true
do
    # Echo current date to stdout
    echo `date`
    # Echo 'error!' to stderr
    echo 'error!' >&2
    sleep 1
done

ذخیره کنید و فایل را ببندید. اگر از nano استفاده می کنید، Ctrl+X را فشار دهید، سپس وقتی از شما خواسته شد، Y و Enter را فشار دهید.

بعد، اسکریپت خود را قابل اجرا کنید:

chmod +x ~/idle.sh

فایل های پیکربندی هر برنامه برای برنامه های Supervisor در دایرکتوری /etc/supervisor/conf.d قرار دارند، معمولاً یک برنامه در هر فایل اجرا می شود و به .conf ختم می شود. ما یک فایل پیکربندی برای این اسکریپت به عنوان`/etc/supervisor/conf.d/idle.conf ایجاد می کنیم:

sudo nano /etc/supervisor/conf.d/idle.conf

این مطالب را اضافه کنید:

/etc/supervisor/conf.d/idle.conf

command=/home/ubuntu/idle.sh
autostart=true
autorestart=true
stderr_logfile=/var/log/idle.err.log
stdout_logfile=/var/log/idle.out.log

این را خط به خط مرور می کنیم:

command=/home/ubuntu/idle.sh

پیکربندی با تعریف برنامه ای با نام بیکار و مسیر کامل برنامه شروع می شود:

autostart=true
autorestart=true

دو خط بعدی رفتار خودکار اسکریپت را تحت شرایط خاصی تعریف می کند.

گزینه autostart به Supervisor می گوید که این برنامه باید هنگام بوت شدن سیستم راه اندازی شود. تنظیم این مورد روی false به شروع دستی پس از خاموش شدن سیستم نیاز دارد.

autorestart تعریف می کند که چگونه Supervisor باید برنامه را در صورت خروج از آن مدیریت کند:

false به Supervisor می‌گوید که پس از خروج برنامه هرگز آن را مجددا راه‌اندازی نکند.
true به Supervisor می گوید که همیشه برنامه را پس از خروج مجدداً راه اندازی کند.
unexpected به Supervisor می گوید که فقط در صورتی برنامه را مجدداً راه اندازی کند که با یک کد خطای غیرمنتظره (به طور پیش فرض هر چیزی غیر از کدهای 0 یا 2) خارج شود. برای کسب اطلاعات بیشتر در مورد کدهای خطا، به دستور errno نگاه کنید.

stderr_logfile=/var/log/idle.err.log
stdout_logfile=/var/log/idle.out.log

دو خط پایانی مکان دو فایل لاگ اصلی را برای برنامه مشخص می کند. همانطور که توسط نام گزینه پیشنهاد می شود، stdout و stderr به ترتیب به مکان های stdout_logfile و stderr_logfile هدایت می شوند. دایرکتوری های مشخص شده باید از قبل وجود داشته باشند، زیرا Supervisor سعی نخواهد کرد هیچ دایرکتوری گمشده ای ایجاد کند.

پیکربندی که ما در اینجا ایجاد کرده ایم یک الگوی حداقلی برای یک برنامه Supervisor است. اسناد Supervisor بسیاری از گزینه های پیکربندی اختیاری دیگر را فهرست می کند که برای تنظیم نحوه اجرای برنامه ها در دسترس هستند.

هنگامی که فایل پیکربندی ما ایجاد و ذخیره شد، می توانیم از طریق دستور supervisorctl برنامه جدید خود را به Supervisor اطلاع دهیم. ابتدا به Supervisor می‌گوییم که به دنبال تنظیمات برنامه جدید یا تغییر یافته در فهرست /etc/supervisor/conf.d با استفاده از:

sudo supervisorctl reread

 

Output

idle: available

هر زمان که تغییری در هر فایل پیکربندی برنامه ایجاد می کنید، اجرای دو دستور قبلی تغییرات را اعمال می کند.

در این مرحله برنامه ما اکنون باید در حال اجرا باشد. ما می توانیم خروجی آن را با مشاهده فایل گزارش خروجی بررسی کنیم:

sudo tail /var/log/idle.out.log

 

Output

Sat Nov 20 22:21:22 UTC 2021
Sat Nov 20 22:21:23 UTC 2021
Sat Nov 20 22:21:24 UTC 2021
Sat Nov 20 22:21:25 UTC 2021
Sat Nov 20 22:21:26 UTC 2021
Sat Nov 20 22:21:27 UTC 2021
Sat Nov 20 22:21:28 UTC 2021
Sat Nov 20 22:21:29 UTC 2021
Sat Nov 20 22:21:30 UTC 2021
Sat Nov 20 22:21:31 UTC 2021

در مرحله بعد، برخی دیگر از کاربردهای Supervisor را پوشش خواهیم داد.

مرحله 3 – مدیریت برنامه ها

فراتر از اجرای برنامه‌ها، می‌خواهید توقف، راه‌اندازی مجدد یا وضعیت آنها را ببینید. برنامه supervisorctl که در مرحله 2 از آن استفاده کردیم، یک حالت تعاملی نیز دارد که می توانیم از آن برای کنترل برنامه های خود استفاده کنیم.

برای وارد شدن به حالت تعاملی، supervisorctl را بدون آرگومان اجرا کنید:

sudo supervisorctl

supervisorctl در ابتدا وضعیت و زمان آپدیت تمام برنامه های پیکربندی شده را چاپ می کند و سپس خط فرمان آن را چاپ می کند. با وارد کردن راهنما، تمام دستورات موجود آن آشکار می‌شود:

supervisor> help

 

Output

default commands (type help <topic>):
=====================================
add    clear  fg        open  quit    remove  restart   start   stop  update
avail  exit   maintail  pid   reload  reread  shutdown  status  tail  version

شما می توانید یک برنامه را با دستورات مرتبط به دنبال نام برنامه شروع یا متوقف کنید:

supervisor> stop idle

 

Output

idle: stopped

supervisor> start idle

 

Output

idle: started

با استفاده از دستور tail، می‌توانید آخرین ورودی‌های فهرست‌های stdout و stderr را برای برنامه خود مشاهده کنید:

supervisor> tail idle

 

Output

Sun Nov 21 00:36:10 UTC 2021
Sun Nov 21 00:36:11 UTC 2021
Sun Nov 21 00:36:12 UTC 2021
Sun Nov 21 00:36:13 UTC 2021
Sun Nov 21 00:36:14 UTC 2021
Sun Nov 21 00:36:15 UTC 2021
Sun Nov 21 00:36:17 UTC 2021

supervisor> tail idle stderr

 

Output

error!
error!
error!
error!
error!
error!
error!

با استفاده از وضعیت می توانید پس از ایجاد هر گونه تغییر، وضعیت اجرای فعلی هر برنامه را دوباره مشاهده کنید:

supervisor> status

 

Output

idle                      STOPPED    Nov 21 01:07 AM

در نهایت، می‌توانید با Ctrl+C یا با وارد کردن quit در فرمان از supervisorctl خارج شوید:

supervisor> quit

نتیجه

در این آموزش نحوه نصب و مدیریت Supervisor را یاد گرفتید. همانطور که گفته شد، Supervisor با استانداردهای مدرن بسیار سبک وزن است، اما همچنان به خوبی نگهداری می شود و می تواند ابزار مفیدی برای استقرارهای کوچکتر باشد. همچنین روشی کم‌معنا و خودکفایی برای تولید لاگ‌ها به‌عنوان بخشی از یک استقرار بزرگ‌تر است.

اگر چندین برنامه کوچک را اجرا می کنید که نیاز به دسترسی به وب دارند، ممکن است بخواهید درباره پیکربندی Nginx به عنوان یک پروکسی معکوس نیز مطالعه کنید، که یکی دیگر از اجزای اساسی استقرارهای کوچک و قابل استفاده مجدد است.

 

 

https://vpsgol.net/product/vps-germany/

 

https://vpsgol.net/product/vps-usa/

 

https://vpsgol.net/product/vps-france/

 

https://vpsgol.net/product/vps-canada/

 

https://vpsgol.net/product/vps-poland/

 

https://vpsgol.net/product/vps-netherlands/

 

https://vpsgol.net/product/vps-england/

برچسب‌ها:Supervisorبرنامه supervisorctlپیکربندی Nginxخرید vpsخرید سرور مجازیراه اندازی سرور مجازیسرور مجازیسرور مجازی آمریکا

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه وارد کردن و گرفتن خروجی پایگاه داده در MySQL یا MariaDB

ورود به سایت

معرفی

واردات و صادرات پایگاه داده یک کار رایج در توسعه نرم افزار است. می توانید از داده های dump برای پشتیبان گیری و بازیابی اطلاعات خود استفاده کنید. شما همچنین می توانید از آنها برای انتقال داده ها به یک سرور جدید یا محیط توسعه استفاده کنید.

در این آموزش، شما با داده های پایگاه داده در MySQL یا MariaDB کار خواهید کرد (دستورات قابل تعویض هستند). به طور خاص، شما یک پایگاه داده را صادر می کنید و سپس آن پایگاه داده را از فایل dump وارد می کنید.

پیش نیازها

برای وارد کردن یا صادر کردن پایگاه داده MySQL یا MariaDB، به موارد زیر نیاز دارید:

  • یک ماشین مجازی با کاربر sudo غیر روت.
  • MySQL یا MariaDB نصب شده است.
  • یک پایگاه داده نمونه ایجاد شده در سرور پایگاه داده شما.

مرحله 1 – گرفتن خروجی یک پایگاه داده MySQL یا MariaDB

ابزار کنسول mysqldump پایگاه داده را به فایل های متنی SQL صادر می کند. این امر انتقال و جابجایی پایگاه های داده را آسان تر می کند. برای حسابی که امتیازات آن حداقل دسترسی کامل فقط خواندنی به پایگاه داده را می دهد، به نام پایگاه داده و اعتبارنامه خود نیاز دارید.

از mysqldump برای صادرات پایگاه داده خود استفاده کنید:

mysqldump -u username -p database_name > data-dump.sql

  • نام کاربری نام کاربری است که می توانید با آن وارد پایگاه داده شوید
  • database_name نام پایگاه داده برای صادرات است
  • data-dump.sql فایلی در دایرکتوری فعلی است که خروجی را ذخیره می کند.

این دستور هیچ خروجی بصری تولید نمی کند، اما می توانید محتویات data-dump.sql را بررسی کنید تا بررسی کنید که آیا یک فایل dump قانونی SQL است یا خیر.

دستور زیر را اجرا کنید:

head -n 5 data-dump.sql

بالای فایل باید شبیه به این به نظر برسد، و یک داپ MySQL را برای پایگاه داده ای به نام database_name نشان می دهد.

مرحله 2 – وارد کردن یک پایگاه داده MySQL یا MariaDB

برای وارد کردن یک فایل dump موجود به MySQL یا MariaDB، باید یک پایگاه داده جدید ایجاد کنید. این پایگاه داده ها را ذخیره می کند.

ابتدا به عنوان root یا کاربر دیگری با امتیازات کافی برای ایجاد پایگاه داده جدید وارد MySQL شوید:

mysql -u root -p

این دستور شما را وارد اعلان پوسته MySQL می کند. سپس با دستور زیر یک پایگاه داده جدید ایجاد کنید. در این مثال، پایگاه داده جدید new_database نامیده می شود:

CREATE DATABASE new_database;

این خروجی را خواهید دید که ایجاد پایگاه داده را تأیید می کند..

 

Output

Query OK, 1 row affected (0.00 sec)

سپس با فشار دادن CTRL+D از پوسته MySQL خارج شوید. از خط فرمان معمولی، می توانید فایل dump را با دستور زیر وارد کنید:

mysql -u username -p new_database < data-dump.sql

  • نام کاربری نام کاربری است که می توانید با آن وارد پایگاه داده شوید
  • newdatabase نام پایگاه داده تازه ایجاد شده است
  • data-dump.sql فایل تخلیه داده ای است که باید وارد شود و در فهرست فعلی قرار دارد

اگر دستور با موفقیت اجرا شود، هیچ خروجی تولید نمی کند. اگر در طول فرآیند خطایی رخ دهد، mysql آنها را در ترمینال چاپ می کند. برای بررسی موفقیت آمیز بودن وارد کردن، وارد پوسته MySQL شوید و داده ها را بررسی کنید. انتخاب پایگاه داده جدید با USE new_database و سپس استفاده از SHOW TABLES. یا یک دستور مشابه برای مشاهده برخی از داده ها.

نتیجه

در این آموزش شما یک پایگاه داده از پایگاه داده MySQL یا MariaDB ایجاد کردید. سپس آن داده‌ها را به یک پایگاه داده جدید وارد کردید. mysqldump دارای تنظیمات اضافی است که می توانید از آنها برای تغییر نحوه ایجاد تخلیه اطلاعات توسط سیستم استفاده کنید.

 

https://vpsgol.net/product/vps-germany/

 

https://vpsgol.net/product/vps-usa/

 

https://vpsgol.net/product/vps-france/

 

https://vpsgol.net/product/vps-canada/

 

https://vpsgol.net/product/vps-poland/

 

https://vpsgol.net/product/vps-netherlands/

 

https://vpsgol.net/product/vps-england/

 

MySQL or MariaDBایجاد پایگاه دادهخرید سرور مجازیسرور مجازیگرفتن خروجی از mysqlوارد کردن اطلاعات در پایگاه داده

  • behnam gol mohamadi
  • ۰
  • ۰

چگونه با Angular 11 و Scully یک Jamstack Portfolio بسازیم

ورود به سایت

معرفی

به عنوان یک توسعه دهنده، راه های زیادی وجود دارد که می توانید مهارت ها، دستاوردها و کار خود را نشان دهید. اینها شامل مشارکت‌های منبع باز، پروژه‌های شخصی، مشارکت‌های گفتاری، پست‌های وبلاگ، و غیره می‌شوند. با این حال، انجام همه این کارها ممکن است بیهوده باشد، اگر کار شما در چندین پلتفرم پراکنده باشد و وقتی مردم شما را جستجو می‌کنند، پیدا کردن آن دشوار باشد. نداشتن مکانی مرکزی برای نمایش دستاوردهای شما می تواند بر علیه شما کار کند و ممکن است باعث شود مشتریان، استخدام کنندگان و کارفرمایان بالقوه ارزش شما را دست کم بگیرند. پورتفولیو به شما این امکان را می دهد که بهترین کار خود را به جلو بفرستید، دستاوردهای شما را آسان می کند، به شما کمک می کند خود را برندسازی کنید، و ارتباطاتی را که منجر به فرصت های بالقوه پرسود می شود، تسهیل می کند. جفت کردن نمونه کارها با یک وبلاگ به شما ابزاری می دهد تا افکار خود را به اشتراک بگذارید، آنچه را که یاد می گیرید مستند کنید و اعتبار خود را بیشتر بسازید.

با استفاده از طیف گسترده ای از ویژگی های قوی آنها، می توانید یک نمونه کار جذاب و سریع با استفاده از Angular و Scully بسازید. Angular یک پلت فرم همه کاره است که به شما امکان می دهد همه چیز را از وب گرفته تا برنامه های بومی و تلفن همراه ایجاد کنید. ابزارهای مفید مختلفی را ارائه می‌کند که توسعه برنامه را ساده می‌کند و در نتیجه برنامه‌های سریع‌تری با عملکرد عالی ایجاد می‌کند.

برنامه های زاویه ای می توانند حتی با ثابت کردن آنها سریعتر شوند. با استفاده از Scully، می‌توانید برنامه‌های Angular را به برنامه‌های Jamstack با ارائه سریع‌تر تبدیل کنید. Scully یک مولد سایت استاتیک است که یک صفحه HTML ثابت برای هر مسیر در برنامه Angular شما ایجاد می کند. این صفحات سریعتر ارائه می شوند و برای سئو موثر هستند. همچنین ابزارهایی مانند مولد وبلاگ را ارائه می دهد که می توانید با آن وبلاگ نمونه کار خود را بسازید.

در این آموزش با استفاده از Angular 11 و Scully یک نمونه کار و یک وبلاگ می سازید. شما یک برنامه Angular ایجاد می کنید، صفحاتی را برای نمایش پروژه ها و نمایه خود اضافه می کنید و خدماتی را برای پر کردن این صفحات اضافه می کنید. علاوه بر این، شما یک وبلاگ ایجاد می کنید و برای آن پست ایجاد می کنید. در نهایت، شما برنامه را با استفاده از Scully به یک سایت ثابت تبدیل خواهید کرد.

پیش نیازها

برای تکمیل این آموزش شما نیاز دارید:

  • یک محیط توسعه که Node.js نسخه ۱۲ یا بالاتر را اجرا می کند.
  • Angular CLI نصب شده است، که می توانید با دنبال کردن مرحله 1 آموزش شروع با Angular با استفاده از Angular CLI انجام دهید. این آموزش با استفاده از Angular CLI v11.2.14 ساخته شده است. با اجرای دستور: می توانید این نسخه را نصب کنید
    npm -g نصب @angular/cli@11.2.14
  • Chromium نصب شده است (فقط کاربران ویندوز). Scully به Chromium نیاز دارد. اگر از macOS، اوبونتو یا سیستم عامل دیگری استفاده می‌کنید، به‌طور پیش‌فرض، Scully یک نسخه محلی را دانلود می‌کند که اگر قبلاً نصب نشده باشد، از آن برای ارائه یک سایت ثابت استفاده می‌کند. با این حال، اگر از ویندوز استفاده می کنید، باید Chrome را روی WSL نصب کنید، که می توانید با دنبال کردن این راهنما در مورد پیش نیازهای WSL برای Scully این کار را انجام دهید.
  • درک درستی از HTML، CSS، و TypeScript .
  • آشنایی با RxJS که می توانید در مستندات محصول RxJS بیابید.
  • درک درستی از Angular که می توانید در آموزش شروع با Angular CLI بیابید.

مرحله 1 – راه اندازی برنامه Angular

در این مرحله، اپلیکیشن نمونه کارها را با استفاده از Angular CLI تولید خواهید کرد. CLI برنامه را داربست می کند و تمام وابستگی های لازم برای اجرای آن را نصب می کند. سپس وابستگی هایی مانند Bootstrap، Font Awesome و Scully را اضافه خواهید کرد. اسکالی برنامه را ثابت می کند. بوت استرپ اجزا و یک ظاهر طراحی را ارائه می دهد. Font Awesome آیکون ها را عرضه می کند. پس از نصب این وابستگی‌ها، دارایی‌هایی مانند فونت‌ها و فایل‌های JSON را اضافه می‌کنید که حاوی داده‌های نمونه کار شما هستند.

برای شروع، دستور زیر را اجرا کنید تا برنامه تولید شود. به آن پورتفولیو می گویند. این آموزش شامل تست هایی برای برنامه نیست، بنابراین می توانید از پرچم -S برای رد شدن از تولید فایل آزمایشی استفاده کنید. اگر می‌خواهید بعداً آزمایش‌هایی اضافه کنید، می‌توانید این پرچم را حذف کنید.

ng new portfolio -S

وقتی از شما پرسیده شد که آیا می‌خواهید مسیریابی Angular را اضافه کنید، با بله پاسخ دهید. این به ابزار CLI می‌گوید که یک ماژول جداگانه برای مدیریت مسیریابی برنامه ایجاد کند. این در src/app/app-routing.module.ts در دسترس خواهد بود.

همچنین از شما خواسته می شود که یک قالب شیوه نامه را انتخاب کنید. CSS را انتخاب کنید. Angular گزینه های سبک دیگری مانند SCSS، Sass، Less و Stylus را ارائه می دهد. CSS ساده تر است و به همین دلیل است که می خواهید از آن در اینجا استفاده کنید

 

Output

? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? (Use arrow keys)
❯ CSS 

 

نصب Dependencies

برای این برنامه به سه وابستگی نیاز دارید: Scully، ng-bootstrap و Font Awesome. اسکالی برنامه Angular را به یک برنامه ثابت تبدیل می کند. وابستگی های دیگر، Bootstrap و Font Awesome، ظاهر و احساس نمونه کارها را سفارشی می کنند. ng-bootstrap کامپوننت‌های Angular را با استفاده از Bootstrap ارائه می‌کند. این به ویژه مفید است زیرا همه اجزای وانیلی Bootstrap با Angular کار نمی کنند. بوت استرپ همچنین میزان استایلی را که باید به برنامه اضافه کنید کاهش می دهد زیرا قبلاً آن را برای شما فراهم کرده است. Font Awesome آیکون ها را عرضه می کند.

هنگامی که Scully را به عنوان یک وابستگی اضافه می کنید، شماتیک اولیه خود را اجرا می کند که تغییراتی را به برنامه شما اضافه می کند تا برای تولید سایت استاتیک آماده شود. از دایرکتوری پروژه خود، از این دستور برای اضافه کردن Scully به پروژه خود استفاده کنید:

ng add @scullyio/init@2.0.0

سپس با استفاده از این دستور ng-bootstrap را اضافه کنید.

ng add @ng-bootstrap/ng-bootstrap@9.1.3

آخرین وابستگی برای اضافه کردن Font Awesome است.

npm install –save @fortawesome/fontawesome-free@5.15.4

اکنون که وابستگی ها اضافه شده اند، آماده اضافه کردن پیکربندی هستید.

اضافه کردن پیکربندی

برای در دسترس قرار دادن Font Awesome برای برنامه، باید یک مرجع به CSS کوچک شده آن در فایل angular.json اضافه کنید. این فایل را می توان در پایه پروژه یافت. با استفاده از nano یا ویرایشگر متن مورد علاقه خود، این فایل را باز کنید:

nano angular.json

در فایل به دنبال بخش architect/build بگردید. این بخش پیکربندی دستور ng build را ارائه می دهد. شما مرجع کوچک شده Font Awesome CSS، node_modules/@fortawesome/fontawesome-free/css/all.min.css را به آرایه سبک ها اضافه می کنید. آرایه سبک ها تحت پروژه ها / نمونه کارها / معمار / ساخت / گزینه ها قرار دارد. خط هایلایت شده را به فایل خود اضافه کنید:

angular.json

{
  ...
  "projects": {
    "portfolio": {
      ...
      "architect": {
        "build": {
          ...
          "options": {
              ...
              "styles": [
                  "node_modules/bootstrap/dist/css/bootstrap.min.css",
                  "node_modules/@fortawesome/fontawesome-free/css/all.min.css",
                  "src/styles.css"
              ],
          }
        },
        ...
      }
    }
  }
}

اکنون Font Awesome در دسترس خواهد بود.

ذخیره کنید و فایل را ببندید.

در مرحله بعد، یک فونت جدید به پروژه اضافه خواهید کرد که می تواند به شخصی سازی ظاهر و احساس نمونه کارها شما کمک کند. می‌توانید با استفاده از فونت‌های Google که طیف وسیعی از فونت‌های موجود را ارائه می‌کند، فونت‌هایی را به پروژه Angular خود اضافه کنید. می توانید با استفاده از تگ پیوند به فونت های انتخاب شده در تگ head پیوند دهید.

در این آموزش از فونت Nunito استفاده خواهید کرد. src/index.html را باز کنید و خطوط مشخص شده در زیر را اضافه کنید:

src/index.html

...
<head>
  <meta charset="utf-8">
  <title>Portfolio</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Nunito:wght@200;400;800&display=swap" rel="stylesheet">
</head>
...

خطوط برجسته شده به فونت Nunito در فونت های گوگل پیوند دارند. شما آن را در سه وزن دریافت خواهید کرد: بسیار سبک، معمولی و بسیار پررنگ.

ذخیره کنید و فایل را ببندید.

افزودن بیو و داده های پروژه

کاری که انجام می دهید این است که فایل های JSON را ایجاد کنید که تمام داده هایی را که می خواهید در نمونه کار خود قرار دهید در خود نگه می دارد. جداسازی الگوها از داده ها، ایجاد تغییرات و افزودن چیزهای بیشتری را در آینده بدون دستکاری در برنامه آسان تر می کند.

با ایجاد یک پوشه json در src/assets شروع کنید.

mkdir src/assets/json

در پوشه json، دو فایل JSON ایجاد خواهید کرد: bio.json و فایل projects.json. bio.json نمایه ای را که می خواهید در سایت نمایش دهید نگه می دارد. projects.json لیستی از پروژه هایی است که می خواهید به نمایش بگذارید.

ساختار فایل bio.json شبیه به این خواهد بود:

src/assets/json/bio.json

{
    "firstName": "Jane",
    "lastName": "Doe",
    "intro": [ "paragraph 1", "paragraph 2" ],
    "about": [ "paragraph 1", "paragraph 2" ]
}

مقدمه یک مقدمه کوتاه است که در صفحه اصلی نمایش داده می شود. درباره نمایه گسترده تری است که در صفحه «درباره» نشان داده شده است.

برای این آموزش، می توانید از یک نمونه بیو استفاده کنید یا خودتان آن را سفارشی کنید. برای استفاده از نمونه بیو، bio.json را باز کنید و موارد زیر را اضافه کنید:

src/assets/json/bio.json

{
    "firstName": "Jane",
    "lastName": "Doe",
    "intro": [
        "I'm a software developer with a passion for web development. I am currently based somewhere in the world. My main focus is building fast, accessible, and beautiful websites that users enjoy.",
        "You can have a look at some of my work here."
    ],
    "about": [
        "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam aliquam auctor fringilla. Proin scelerisque lacinia nisl vel ultrices. Ut gravida finibus velit sit amet pulvinar. Nunc nisi arcu, pretium quis ultrices nec, volutpat sit amet nulla. Mauris semper elementum placerat. Aenean velit risus, aliquet quis lectus id, laoreet accumsan erat. Curabitur varius facilisis velit, et rutrum ligula mollis et. Sed imperdiet sit amet urna ut eleifend. Suspendisse consectetur velit nunc, at fermentum eros volutpat nec. Vivamus scelerisque nec turpis volutpat sagittis. Aenean eu sem et diam consequat euismod.",
        "Mauris dolor tellus, sagittis vel pellentesque sit amet, viverra in enim. Maecenas non lectus eget augue convallis iaculis mattis malesuada nisl. Suspendisse malesuada purus et luctus scelerisque. Cras hendrerit, eros malesuada blandit scelerisque, nulla dui gravida arcu, nec maximus nunc felis sit amet mauris. Donec lorem elit, feugiat sit amet condimentum quis, consequat id diam. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras rutrum sodales condimentum. Aenean ultrices mi vel augue dapibus mattis. Donec ut ornare nisl. Curabitur feugiat pharetra dictum."
    ]
}

پس از اتمام ویرایش فایل را ذخیره کرده و ببندید.

فایل JSON دیگر، projects.json، ساختاری مشابه این خواهد داشت:

src/assets/json/projects.json

[
    {
        "name": "",
        "stack": {
            "name": "Vue.js",
            "iconClasses": "fab fa-vuejs"
        },
        "description": "",
        "sourceUrl": "",
        "previewUrl": "",
        "featured": false
    }
]

هر پروژه دارای یک نام، توضیحات، یک URL برای جایی که کد منبع آن میزبانی می شود، و یک URL پیش نمایش اگر در جایی مستقر شده باشد. اگر پروژه URL پیش‌نمایش ندارد، می‌توانید آن را حذف کنید.

آبجکت پشته برای نشان دادن زبان یا چارچوبی که پروژه از آن ساخته شده است استفاده می شود. بنابراین نام، نام زبان/فریم ورک خواهد بود و iconClasses کلاس‌های Font Awesome CSS برای نماد زبان/فریم‌ورک هستند. ویژگی برجسته نشان می دهد که آیا پروژه باید در صفحه اصلی نمایش داده شود یا خیر. اگر ویژگی روی false تنظیم شود، به جای نمایش در صفحه اصلی و «پروژه ها» فقط در صفحه «پروژه ها» نمایش داده می شود.

برای این آموزش، می توانید از چند پروژه نمونه استفاده کنید یا پروژه خود را اضافه کنید. برای استفاده از پروژه های نمونه، projects.json را باز کرده و موارد زیر را اضافه کنید:

src/assets/json/projects.json

[
    {
        "name": "Soduko",
        "stack": {
            "name": "Angular",
            "iconClasses": "fab fa-angular"
        },
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "sourceUrl": "https://github.com",
        "previewUrl": "https://github.com",
        "featured": true
    },
    {
        "name": "E-commerce Store",
        "stack": {
            "name": "React",
            "iconClasses": "fab fa-react"
        },
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "sourceUrl": "https://github.com",
        "previewUrl": "https://github.com",
        "featured": true
    },
    {
        "name": "Algorithm Visualization App",
        "stack": {
            "name": "Angular",
            "iconClasses": "fab fa-angular"
        },
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "sourceUrl": "https://github.com",
        "previewUrl": "https://github.com",
        "featured": true
    },
    {
        "name": "Time Tracking CLI App",
        "stack": {
            "name": "Node.js",
            "iconClasses": "fab fa-node-js"
        },
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "sourceUrl": "https://github.com",
        "previewUrl": "https://github.com",
        "featured": true
    }
]

ذخیره کنید و فایل را ببندید.

راه اندازی سرور

برای بررسی اینکه برنامه شما مطابق انتظار کار می کند، سرور ارائه شده توسط Angular CLI را با استفاده از این دستور اجرا کنید:

ng serve

این دستور برنامه را می سازد و به آن سرویس می دهد. اگر تغییری ایجاد کنید، آن را بازسازی می کند. پس از تکمیل، برنامه در http://localhost:4200/ ارائه خواهد شد.

مرورگر خود را باز کنید و به http://localhost:4200 بروید. شما باید یک صفحه نگهدارنده را ببینید که به شکل زیر است:

هر بار که تغییری را ذخیره می کنید باید خروجی مشابه این را ببینید:

✔ Browser application bundle generation complete.

Initial Chunk Files           | Names                      |      Size
vendor.js                     | vendor                     |   3.83 MB
styles.css                    | styles                     | 202.25 kB
polyfills.js                  | polyfills                  | 141.85 kB
main.js                       | main                       |  26.08 kB
runtime.js                    | runtime                    |   9.06 kB

                              | Initial Total              |   4.20 MB

Build at:  - Hash:  - Time: 13312ms

** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **

✔ Compiled successfully.

پس از تکمیل یک مرحله، بررسی کنید که ✔ با موفقیت کامپایل شده است. پیام موجود است اگر مشکلی وجود داشته باشد، دستور ng serve یک خطا را خروجی می دهد. وقتی این اتفاق افتاد، مرحله را طی کنید تا مطمئن شوید چیزی را از دست نداده اید یا اشتباهی مرتکب نشده اید. پس از تکمیل آموزش، صفحه اصلی نمونه کارها باید چیزی شبیه به این باشد:

در این مرحله، برنامه را تولید کرده و تمام وابستگی ها، دارایی ها و تنظیمات لازم را اضافه کرده اید. شما همچنین سرور ارائه شده توسط Angular CLI را راه اندازی کرده اید. در مرحله بعد ماژول هسته را ایجاد می کنید.

مرحله 2 – ایجاد ماژول هسته

در این آموزش، اپلیکیشنی که در حال ساخت آن هستید شامل سه ماژول است: هسته، وبلاگ و نمونه کارها. ساختار برنامه به صورت زیر خواهد بود:

src/app

src/app
├── blog
├── core
└── portfolio

ماژول وبلاگ برای صفحات فرود وبلاگ و صفحات پست وبلاگ است. ماژول اصلی شامل همه چیزهای اصلی برنامه است. اینها شامل مولفه هدر، خدمات داده و مدل های داده می شود. ماژول نمونه کارها همه صفحات نمونه کار شما را نگه می دارد: “درباره”، “پروژه ها” و صفحه اصلی.

در این مرحله ماژول هسته را تولید خواهید کرد. همچنین مؤلفه هدر، سرویس ها و مدل های داده را تولید و پر می کنید. هدر در بالای هر صفحه نمایش داده می شود و حاوی نام و منوی سایت است. مدل ها داده های پورتفولیو را ساختار می دهند. خدمات داده های نمونه کارها را واکشی می کنند.

ماژول اصلی باید به این صورت باشد:

src/app/core/

src/app/core
├── header
├── models
└── services

برای تولید ماژول هسته، دستور زیر را از ریشه پروژه اجرا کنید:

ng generate module core

این دستور ماژول هسته را در پوشه src / app / core اضافه می کند و فایل ماژول را در src / app / core / core.module.ts اضافه می کند.

فایل ماژول هسته ماژول اصلی و واردات آن را تعریف می کند. در فایل ماژول جدید ایجاد شده، باید چند import اضافه کنید تا از هدر و سرویس ها پشتیبانی کنید.

core.module.ts را باز کنید و خطوط برجسته شده را اضافه کنید (حتما کاما را بعد از وارد کردن CommonModule وارد کنید):

src/app/core/core.module.ts

...
import { RouterModule } from '@angular/router';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [],
  imports: [
    CommonModule,
    RouterModule,
    NgbModule,
    HttpClientModule
  ]
})
...

این ماژول از HttpClientModule برای واکشی داده ها از فایل های JSON که قبلا ایجاد کرده اید استفاده می کند. همچنین از چند جزء ng-bootstrap از NgbModule و RouterModule برای مسیریابی استفاده خواهد کرد. همچنین باید آنها را به واردات CoreModule اضافه کنید.

پس از اتمام کار فایل را ذخیره کرده و ببندید.

تولید مدل های داده

در این بخش مدل های داده تولید می کنید. مدل‌های داده رابط‌هایی هستند که برای تعریف ساختار داده‌ها از فایل‌های JSON استفاده می‌کنید. آنها در سرویس ها و در بقیه اجزاء به عنوان انواع بازگشت و پارامتر استفاده خواهند شد. شما به دو مدل نیاز دارید: bio که ساختار داده های زیستی شما را تعریف می کند و پروژه که ساختار داده های پروژه شما را مشخص می کند.

src/app/core/models

src/app/core/models
├── bio.ts
└── project.ts

مدل Bio نمایانگر یک نمایه است در حالی که مدل پروژه پروژه ای برای نمایش است. شما هر دو مدل را با اجرای دستور زیر در ریشه پروژه تولید خواهید کرد:

for model in bio project ; do ng generate interface “core/models/${model}”; done

این دستور از طریق مسیرهای فایل حلقه می زند و آنها را به رابط تولید ng ارسال می کند که آنها را در پوشه src / app / core / models ایجاد می کند.

فایل مدل بیو اطلاعاتی را که می‌خواهید بیو شما حاوی آن باشد، مشخص می‌کند. در فایل src / app / core / models / bio.ts که ایجاد شده است، فیلدهایی را که در زیر برجسته شده اند اضافه کنید.

src/app/core/models/bio.ts

export interface Bio {
    firstName: string;
    lastName: string;
    about: string[];
    intro: string[];
}

در این بلوک کد، فیلدهای نام، نام خانوادگی، درباره و مقدمه را به مدل بیو اضافه کردید. دو فیلد اول از انواع رشته‌ها و دو فیلد آخر آرایه‌هایی از رشته‌ها هستند، زیرا ممکن است حاوی چند پاراگراف باشند.

ذخیره کنید و فایل را ببندید.

فایل پروژه ساختار یک پروژه را تعریف می کند. در اینجا، فیلدهایی را که می خواهید برای هر پروژه استفاده کنید فهرست می کنید. در فایل src / app / core / models / project.ts، خطوط برجسته شده را اضافه کنید.

src/app/core/models/project.ts

export interface Project {
    name: string;
    stack: { iconClasses: string, name: string };
    description: string;
    sourceUrl: string;
    previewUrl: string;
    featured?: boolean;
}

شما فیلدهایی را برای مدل پروژه اضافه کرده اید. هر پروژه دارای یک نام، توضیحات، یک URL برای کد منبع خود و یک URL پیش نمایش است اگر در جایی مستقر شده باشد. آبجکت پشته برای نشان دادن زبان یا چارچوب پروژه استفاده می شود. (نام نام زبان / فریمورک خواهد بود و iconClasses کلاس‌های Font Awesome CSS برای نماد زبان / فریمورک هستند.) ویژگی برجسته نشان می‌دهد که آیا پروژه باید در صفحه اصلی نمایش داده شود یا خیر. اگر ویژگی روی false تنظیم شده باشد، به جای صفحه اصلی و «پروژه‌ها» فقط در صفحه «پروژه‌ها» نمایش داده می‌شود.

پس از اتمام کار فایل را ذخیره کرده و ببندید.

در این قسمت مدل هایی را برای داده ها ایجاد کردید. در مرحله بعد، خدماتی را ایجاد خواهید کرد که داده های نمونه کارها را دریافت کرده و از این مدل ها استفاده می کنند.

تولید خدمات

سرویس‌هایی که در این بخش ایجاد می‌کنید، داده‌های فایل‌های JSON را که قبلاً ساخته‌اید واکشی می‌کنند. هنگامی که آنها این داده ها را واکشی کردند، اجزا می توانند این سرویس ها را فراخوانی کرده و داده ها را مصرف کنند. مدل ها به عنوان انواع برگشتی در این سرویس ها استفاده خواهند شد. مدل bio در سرویس bio و مدل پروژه در سرویس پروژه استفاده می شود. شما یک سرویس هدر اضافی اضافه خواهید کرد که به تصمیم گیری در مورد مسیرهایی که برای موارد موجود در هدر و سایر مؤلفه ها استفاده کنید کمک می کند. ماژول اصلی دارای سه سرویس است: BioService، HeaderService و ProjectsService.

src/app/core/services

src/app/core/services
├── bio.service.ts
├── header.service.ts
└── projects.service.ts

برای تولید این خدمات، این دستور را از دایرکتوری ریشه پروژه اجرا کنید:

for service in bio projects header; do ng generate service “core/services/${service}”; done

این دستور از طریق مسیرهای فایل حلقه می زند و آنها را به سرویس ng generate می دهد که آنها را در پوشه src / app / core / services ایجاد می کند.

سرویس بیو داده‌های زیستی شما را از فایل JSON بیو واکشی می‌کند. برای این کار، روشی برای واکشی این داده ها اضافه می کنید. فایل src / app / core / services / bio.service.ts را باز کنید و خطوط برجسته زیر را اضافه کنید:

src/app/core/services/bio.service.ts

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Bio } from '../models/bio';

@Injectable({
  providedIn: 'root'
})
export class BioService {

  constructor(private http: HttpClient) { }

  getBio() {
   return this.http.get<Bio>('assets/json/bio.json');
  }
}

روش getBio در BioService بیوگرافی شما را از فایل assets / json / bio.json واکشی می کند. شما سرویس HttpClient را به سازنده آن تزریق می‌کنید و از آن در متد getBio () برای درخواست GET به فایل استفاده می‌کنید.

ذخیره کنید و فایل را ببندید.

در مرحله بعد، HeaderService را تغییر خواهید داد. از سرویس هدر برای بررسی اینکه آیا مسیر فعلی صفحه اصلی است یا خیر استفاده می شود. روشی اضافه خواهید کرد که تعیین می کند صفحه فعلی صفحه اصلی است یا خیر. فایل src / app / core / services / header.service.ts را باز کنید و خطوط برجسته شده را اضافه کنید:

src/app/core/services/header.service.ts

import { Injectable } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { filter, map, startWith } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class HeaderService {

  constructor(private router: Router) { }

  isHome() {
    return this.router.events.pipe(
      filter(event => event instanceof NavigationEnd),
      map(event => {
        if (event instanceof NavigationEnd) {
          if (this.checkForHomeUrl(event.url)) {
            return true;
          }
        }

        return false;
      }),
      startWith(this.checkForHomeUrl(this.router.url))
    );
  }

  private checkForHomeUrl(url: string): boolean {
    return url.startsWith('/#') || url == '/';
  }
}

در HeaderService، روش isHome بررسی می کند که آیا صفحه فعلی که در آن هستید، صفحه اصلی است یا خیر. این برای پیمایش به یک لنگر و نمایش پروژه های برجسته در صفحه اصلی مفید است.

ذخیره کنید و فایل را ببندید.

در نهایت شما ProjectsService را تغییر خواهید داد. سرویس پروژه ها داده های پروژه را از فایل JSON پروژه ها واکشی می کند. روشی برای واکشی داده های پروژه اضافه خواهید کرد. فایل src / app / core / services / projects.service.ts را باز کنید و محتویات را به موارد زیر تغییر دهید:

src/app/core/services/projects.service.ts

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { filter, mergeAll, toArray } from 'rxjs/operators';
import { Project } from '../models/project';

@Injectable({
  providedIn: 'root'
})
export class ProjectsService {

  constructor(private http: HttpClient) { }

  getProjects(featured?: boolean): Observable<Project[]> {
    let projects$ = this.http.get<Project[]>('assets/json/projects.json');

    if (featured) {
      return projects$.pipe(
        mergeAll(),
        filter(project => project.featured || false),
        toArray()
      );
    }

    return projects$;
  }
}

ProjectsService یک متد getProjects دارد که پروژه ها را دریافت و فیلتر می کند. پروژه ها را از فایل assets / json / projects.json دریافت می کند. شما سرویس HttpClient را به سازنده آن تزریق خواهید کرد و از آن در متد getProjects () برای درخواست GET به فایل استفاده خواهید کرد. با استفاده از پارامتر featured، می توانید انتخاب کنید که فقط پروژه های برجسته را برای اختصار برگردانید. زمانی که می خواهید پروژه های مهم را نشان دهید، در صفحه اصلی مفید است.

ذخیره کنید و فایل را ببندید.

در این بخش، سرویس‌های داده‌های زیستی و پروژه را اضافه کرده‌اید که داده‌های بیو و پروژه را از فایل‌های JSON و پروژه‌ها واکشی می‌کنند. شما همچنین یک سرویس هدر ایجاد کردید که بررسی می کند آیا صفحه فعلی صفحه اصلی است یا خیر. در قسمت بعدی یک هدر ایجاد می کنید که در بالای هر صفحه از نمونه کار شما نمایش داده می شود. از خدمات بیو و هدر استفاده خواهد کرد.

تولید هدر

جزء هدر در بالای همه صفحات نمایش داده می شود. این شامل نام شما و پیوندهایی به صفحات “درباره” و “پروژه ها” و همچنین وبلاگ است. از سرویس بیو و هدر در هدر استفاده خواهد شد. سرویس بیو داده های زیستی را به هدر ارائه می دهد. از سرویس هدر برای بررسی اینکه آیا صفحه فعلی صفحه اصلی است استفاده می شود و پیوندهایی را به بخش ها یا صفحات “درباره” و “پروژه ها” تنظیم می کند. با اجرای این دستور از ریشه پروژه آن را تولید خواهید کرد:

ng generate component core/header

جزء هدر در بالای هر صفحه نمایش داده می شود. از سرویس بیو برای دریافت نام و نام خانوادگی شما استفاده خواهد کرد. همچنین از سرویس هدر برای تعیین اینکه آیا صفحه فعلی صفحه اصلی است یا خیر استفاده می کند. با استفاده از این اطلاعات، پیوندهایی را به بخش‌ها یا صفحات «درباره» و «پروژه‌ها» تنظیم می‌کند.

در فایل header.component.ts، خدمات بیو و هدر را تزریق می‌کنید و یک ویژگی استایلی اضافه می‌کنید تا پاسخگویی مؤلفه در اندازه‌های مختلف صفحه نمایش را کنترل کند.

header.component.ts را باز کنید و خطوط هایلایت شده را اضافه کنید:

src/app/core/header/header.component.ts

import { Component } from '@angular/core';
import { BioService } from '../services/bio.service';
import { HeaderService } from '../services/header.service';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css']
})
export class HeaderComponent {
  bio$ = this.bioService.getBio();
  isHome$ = this.headerService.isHome();

  menuItems = [
    { title: 'About Me', homePath: '/', fragment: 'about', pagePath: '/about' },
    { title: 'My Projects', homePath: '/', fragment: 'projects', pagePath: '/projects' },
    { title: 'My Blog', homePath: '/blog', fragment: '', pagePath: '/blog' }
  ];

  constructor(private bioService: BioService, private headerService: HeaderService) { }
}

در این فایل کامپوننت، دو سرویس را تزریق خواهید کرد: bioService برای دریافت نام شما از فایل bio JSON و headerService برای اینکه بفهمید صفحه نمایش داده شده در حال حاضر صفحه اصلی است یا خیر. دومی به شما امکان می دهد تصمیم بگیرید که آیا دکمه ها باید به یک صفحه جداگانه مانند / پروژه ها بروند یا لنگر اسکرول را مانند پروژه / # انجام دهند. menuItems شامل تمام موارد منو برای نمایش است. ویژگی‌های bio $ و isHome $ قابل مشاهده‌هایی از سرویس‌های فوق‌الذکر هستند.

ذخیره کنید و فایل را ببندید.

در مرحله بعد، الگوی کامپوننت هدر را تغییر خواهید داد. اینجا جایی است که داده های واکشی شده از سرویس bio نمایش داده می شود. پیوندهایی به بخش‌ها یا صفحات «درباره» و «پروژه‌ها» نیز در اینجا اضافه می‌شوند. در فایل قالب src / app / core / header / header.component.html کد زیر را اضافه کنید.

src/app/core/header/header.component.html

<div class="d-flex min-vh-10 w-100 justify-content-center pb-3 pt-3 pr-4 pl-4">
    <div class="d-flex justify-content-start" *ngIf="bio$ | async as bio" routerLink="/">
        <h2 class="font-weight-bold">{{bio.firstName}}</h2>
        <h2 class="font-weight-light">{{bio.lastName}}</h2>
    </div>
    <div class="d-none d-md-flex flex-grow-1 justify-content-end align-items-start">
        <button type="button" class="ml-2 mr-2 btn btn-outline-dark border-0 font-weight-bold"
            *ngFor="let item of menuItems" [routerLink]="(isHome$ | async) ? item.homePath : item.pagePath"
            [fragment]="(isHome$ | async) ? item.fragment : ''">{{item.title}}</button>
    </div>
    <div class="d-flex d-md-none justify-content-end flex-grow-1">
        <div ngbDropdown class="d-inline-block" display="dynamic" container="body">
            <button class="btn btn-outline-dark border-0" ngbDropdownToggle>
                <i class="fas fa-lg fa-bars"></i>
            </button>
            <div ngbDropdownMenu class="dropdown-menu dropdown-menu-right">
                <button ngbDropdownItem *ngFor="let item of menuItems"
                    [routerLink]="(isHome$ | async) ? item.homePath : item.pagePath"
                    [fragment]="(isHome$ | async) ? item.fragment : ''">{{item.title}}</button>
            </div>
        </div>
    </div>
</div>

در قالب، نام های شما (bio.firstName و bio.lastName) با استفاده از داده های ویژگی bio نمایش داده می شود. بسته به اندازه صفحه، یک منوی کشویی یا فهرستی از دکمه‌ها از menuItems نشان داده می‌شود. لوله مستعار در الگو لغو اشتراک از موارد مشاهده‌پذیر را کنترل می‌کند. این الگو در طول این آموزش رعایت خواهد شد.

ذخیره کنید و فایل را ببندید.

هدر باید در تمام صفحات قابل مشاهده باشد. برای تحقق این امر، باید چند قدم بردارید. ابتدا، CoreModule باید HeaderComponent را صادر کند تا در دسترس باشد. برای صادر کردن آن، خطوط برجسته شده را به src / app / core / core.module.ts اضافه کنید. فراموش نکنید که کاما را بعد از آرایه واردات اضافه کنید.

src/app/core/core.module.ts

...
@NgModule({
  ...

  imports: [
    ...
  ],
  exports: [ HeaderComponent ]
})
...

برای اینکه هدر قابل مشاهده باشد، باید آن را به قالب AppComponent که در AppModule است نیز اضافه کنید. AppModule همچنین باید CoreModule را وارد کند تا به هدر دسترسی داشته باشد. این وظایف اضافی را در مرحله بعد تکمیل خواهید کرد.

در این مرحله، مدل هایی ایجاد کردید که داده های پورتفولیوی شما را سازماندهی می کند. شما همچنین خدماتی را برای واکشی داده های نمونه کارها با استفاده از مدل ها ایجاد کردید. علاوه بر این، یک سرویس هدر ساخته اید که به تصمیم گیری در مورد مسیرهایی که برای موارد سرصفحه استفاده کنید کمک می کند. در نهایت، شما یک جزء هدر ایجاد کردید تا در تمام صفحات نمونه کارها نمایش داده شود. در مرحله بعد، ماژول نمونه کارها را تولید می کنید که شامل تمام صفحات اولیه نمونه کار شما است. صفحات موجود در ماژول نمونه کارها از خدمات و مدل هایی که در این بخش ایجاد کرده اید، بیو و پروژه ها استفاده می کنند.

مرحله 3 – تولید ماژول نمونه کارها

در مرحله قبل، ماژول اصلی را ایجاد کردید که هدر را نگه می دارد و شامل تمام سرویس ها و مدل هایی است که برای واکشی داده های نمونه کارها استفاده خواهید کرد. در این مرحله ماژول نمونه کارها را تولید می کنید که شامل تمام صفحات ضروری نمونه کارها است. اینها شامل صفحه اصلی، “درباره” و “پروژه ها” است. در این مرحله از خدمات و مدل هایی که در ماژول اصلی ساخته اید برای ایجاد این صفحات استفاده خواهید کرد. همچنین مسیرهایی را برای هر یک از صفحات اضافه خواهید کرد.

صفحه اصلی خلاصه ای از نمایه شما را با استفاده از هدر و خدمات بیو نمایش می دهد. صفحه “درباره” یک نمایه عمیق تر است و از خدمات و مدل بیو استفاده می کند. صفحه “پروژه ها” پروژه های شما را با استفاده از خدمات و مدل پروژه ها برای نمایش پروژه های شما به نمایش می گذارد. در پایان این مرحله، ماژول نمونه کارها شما به صورت زیر ساختار می یابد:

src/app/portfolio

src/app/portfolio
├── about
├── home
└── projects

ابتدا دو ماژول تولید خواهید کرد: یک ماژول نمونه کارها و یک ماژول مسیریابی نمونه کارها. ماژول نمونه کارها شامل تمام صفحات اولیه نمونه کار شما است. ماژول مسیریابی پورتفولیو مسئول مسیریابی به این صفحات است.

برای تولید هر دو ماژول، این دستور را از ریشه پروژه اجرا کنید:

ng generate module portfolio –module app –routing –route portfolio

این دستور پوشه app / portfolio را ایجاد می کند و یک فایل ماژول در app / portfolio / portfolio.module.ts اضافه می کند. این مسیر را در app / src / app-routing.module.ts خواهید دید. پرچم مسیریابی — مشخص می کند که ماژول مسیریابی پورتفولیو تولید شود. این ماژول مسیریابی در app / portfolio / portfolio-routing.module.ts قرار خواهد گرفت.

پرچم –route یک مسیر با بارگذاری تنبل در ماژول برنامه ایجاد می کند، همانطور که توسط پرچم –module مشخص شده است. این مسیر را در app / src / app-routing.module.ts خواهید دید. همچنین یک مولفه نگهدارنده مکان را برای اهداف مسیریابی اضافه می کند که در بخش بعدی مورد بحث قرار می گیرد.

این ماژول نمونه کارها باید در مسیر / موجود باشد. این مستلزم آن است که پرچم –route را با یک رشته خالی، مانند –route = “. با این حال، ماژول تولید ng به رشته های خالی برای پرچم –route اجازه نمی دهد. بنابراین شما مجبور خواهید بود از یک مکان نگهدار، نمونه کار استفاده کنید. سپس این مکان‌نما را با یک رشته خالی در src/app/app-routing.module.ts جایگزین می‌کنید، که مسیریابی کل برنامه را انجام می‌دهد.

src / app / app-routing.module.ts را باز کنید و خطوط هایلایت شده را جایگزین کنید:

src/app/app-routing.module.ts

...
const routes: Routes = [
  {
    path: '',
    loadChildren: () => import('./portfolio/portfolio.module').then(m => m.PortfolioModule)
  }
];
...

این تضمین می کند که تمام صفحات در ماژول نمونه کارها با شروع از مسیر / در دسترس هستند.

ذخیره کنید و فایل را ببندید.

ایجاد صفحه اصلی

دستوری که ماژول پورتفولیو را ایجاد می کند یک PortfolioComponent نیز ایجاد می کند. این یک جزء نگهدارنده مکان است که هنگام تنظیم مسیریابی برای ماژول استفاده می شود. با این حال، نام مناسب‌تر برای این مؤلفه HomeComponent است. صفحه اصلی صفحه فرود نمونه کارها شما است. خلاصه ای از کل مجموعه شما خواهد داشت. این کار باعث می‌شود تا کاربران بدون نیاز به پیمایش به چندین صفحه، دیدی کلی از کار شما داشته باشند و خطر از دست دادن علاقه را کاهش می‌دهد.

برای تغییر نام این کامپوننت، ابتدا یک پوشه جدید برای قرار دادن آن ایجاد خواهید کرد. از ریشه پروژه، دستور زیر را اجرا کنید:

mkdir -p src/app/portfolio/home

در مرحله بعد، تمام فایل های PortfolioComponent را به این پوشه جدید منتقل می کنید.

mv src/app/portfolio/portfolio.component.* src/app/portfolio/home/

این دستور همه فایل‌ها را با نام‌هایی که با portfolio.component شروع می‌شوند، به داخل src/app/portfolio/home/folder منتقل می‌کند.

سپس نام portfolio.component * فایل ها را به home.component تغییر می دهید *.

find src/app/portfolio/home -name ‘portfolio*’ -exec bash -c ‘ mv $0 ${0/\portfolio./home.}’ {} \;

پس از اجرای دستورات بالا، به دلیل تغییر نام و مسیر کامپوننت، با خطاهایی مواجه خواهید شد. برای رفع این مشکل باید در چند فایل تغییراتی ایجاد کنید: ماژول مسیریابی نمونه کارها، ماژول نمونه کارها و فایل های مؤلفه خانگی. در این فایل ها، تمام نمونه های PortfolioComponent را به HomeComponent تغییر خواهید داد. همچنین مسیرها را از ./portfolio.component به ./home/home.component به روز خواهید کرد.

با باز کردن src / app / portfolio / portfolio-routing.module، که مسیریابی ماژول نمونه کارها را انجام می دهد، شروع کنید. تغییرات برجسته شده را انجام دهید:

src/app/portfolio/portfolio-routing.module

...
import { HomeComponent } from './home/home.component';

const routes: Routes = [{ path: '', component: HomeComponent }];
...

ذخیره کنید و فایل را ببندید.

سپس src / app / portfolio / portfolio.module.ts، فایل ماژول نمونه کارها را باز کنید. تغییرات برجسته شده را انجام دهید:

src/app/portfolio/portfolio.module.ts

...
import { HomeComponent } from './home/home.component';


@NgModule({
  declarations: [
    HomeComponent
  ],
  ...
})
...

ذخیره کنید و فایل را ببندید.

در نهایت، src / app / portfolio / home / home.component.ts، فایل کامپوننت خانه را باز کنید. تغییرات برجسته شده را انجام دهید:

src/app/portfolio/home/home.component.ts

...
@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
...
}

ذخیره کنید و فایل را ببندید.

در این فایل‌ها، تمام نمونه‌های PortfolioComponent را به HomeComponent تغییر داده‌اید و مسیرها را برای اشاره به HomeComponent به‌روزرسانی کرده‌اید. پس از انجام همه این کارها، ماژول نمونه کارها باید به این شکل باشد.

src/app/portfolio

src/app/portfolio
├── home
│   ├── home.component.css
│   ├── home.component.html
│   └── home.component.ts
├── portfolio-routing.module.ts
└── portfolio.module.ts

اکنون نام ها و مسیرهای فایل های مؤلفه اصلی را به روز کرده اید.

در مرحله بعد، قالب کامپوننت خانه را با محتوا پر می کنید و به آن استایل می دهید. مولفه خانه صفحه اصلی نمونه کارها است و خلاصه مشخصات را نمایش می دهد. (این مؤلفه ای است که در بالا از جزء نمونه کارها به مؤلفه اصلی تغییر نام داده شد.) در این مؤلفه، باید داده های زیستی را برای نمایش واکشی کنید و برای اینکه صفحه در اندازه های مختلف صفحه نمایش پاسخگو باشد، استایلی به آن اضافه کنید.

src/app/portfolio/home/home.component.ts را باز کنید و کد را برای مطابقت با موارد زیر به روز کنید:

src/app/portfolio/home/home.component.ts

import { Component } from '@angular/core';
import { BioService } from '../../core/services/bio.service';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent {
  bio$ = this.bioService.getBio();

  respOptions = [
    { viewClasses: 'd-none d-md-flex', headingClass: 'display-3', useSmallerHeadings: false },
    { viewClasses: 'd-flex d-md-none', headingClass: '', useSmallerHeadings: true }
  ];

  constructor(private bioService: BioService) { }
}

صفحه اصلی نام شما و یک بیوگرافی کوتاه را نشان می دهد که از BioService که در اینجا تزریق می کنید بازیابی شده است. هنگامی که متد getBio آن را فراخوانی کردید، مشاهده پذیر حاصل در ویژگی bio$ ذخیره می شود. ویژگی respOptions پیکربندی را ذخیره می‌کند که به اطمینان از پاسخگو بودن نما کمک می‌کند.

ذخیره کنید و فایل را ببندید.

در مرحله بعد، الگوی کامپوننت خانه را تغییر خواهید داد. این مسئول نمایش اطلاعات از سرویس bio در اندازه های مختلف صفحه نمایش پاسخگو است. نام خود، معرفی مختصری، و اجزای درباره و پروژه‌ها را اضافه می‌کنید که بعداً پوشش داده خواهد شد.

src/app/portfolio/home/home.component.html را باز کرده و کد زیر را اضافه کنید:

src/app/portfolio/home/home.component.html

<div class="d-flex flex-column justify-content-center align-items-center w-100" *ngIf="bio$ | async as bio">
    <div class="d-flex flex-column min-vh-95 justify-content-center align-items-center w-100">
        <div *ngFor="let options of respOptions" [ngClass]="options.viewClasses"
            class="flex-column justify-content-center align-items-start w-75">
            <h1 [ngClass]="options.headingClass" class="text-left">Hello, 👋. My name is <span
                    class="font-weight-bold">{{bio.firstName+'
                    '+bio.lastName}}.</span></h1>
            <div *ngFor="let par of bio.intro">
                <h2 class="text-left" *ngIf="!options.useSmallerHeadings">{{par}}</h2>
                <h5 class="text-left" *ngIf="options.useSmallerHeadings">{{par}}</h5>
            </div>
            <button class="mt-3 mb-5 btn btn-outline-dark" routerLink="/" fragment="projects">
                See My Work
                <i class="ml-1 fas fa-angle-right"></i>
            </button>
        </div>
    </div>

    <div class="d-none d-md-block mt-5"></div>
    <app-about id="about" class="mb-3"></app-about>

    <div class="d-none d-md-block mt-5"></div>
    <app-projects id="projects" class="mb-5"></app-projects>
</div>

در این الگو، نام‌های bio.firstName+ و +bio.lastName و همچنین یک مقدمه، bio.intro از بیو را نمایش می‌دهید. شما همچنین در مورد مؤلفه app-about و پروژه جزء برنامه-پروژه ها را نشان می دهید که در مرحله بعد تولید خواهید کرد.

src/app/portfolio/home/home.component.html

...
<app-about id="about" class="mb-3"></app-about>

...

<app-projects id="projects" class="mb-5"></app-projects>
...

در مرحله بعد، می توانید یک ظاهر طراحی برای مولفه خانه اضافه کنید. src/app/portfolio/home/home.component.css را باز کنید و این خطوط را اضافه کنید:

src/app/portfolio/home/home.component.css

.min-vh-95 {
    height: 95vh;
}

در اینجا شما یک استایل را به مؤلفه خانه اضافه می کنید تا بین محتوای اصلی صفحه اصلی و لبه های پنجره مرورگر فاصله وجود داشته باشد.

پس از تکمیل، صفحه اصلی به این شکل خواهد بود (در مرحله آخر می توانید پیش نمایش سایت را مشاهده کنید):

 

در این مرحله صفحه اصلی را ایجاد کردید که خلاصه ای از نمونه کارها را نمایش می دهد. در بخش بعدی، اجزای «درباره» و «پروژه» را تولید خواهید کرد. اینها در صفحه اصلی نمایش داده می شوند و به عنوان صفحات مستقل نیز استفاده می شوند.

ایجاد صفحات درباره و پروژه

به جای اینکه هر صفحه را به صورت جداگانه تولید کنید، می توانید یک فرمان را اجرا کنید تا صفحات باقی مانده «پروژه ها» و «درباره» را به یکباره بسازید. این کار را با اجرای دستور زیر از ریشه پروژه انجام می دهید:

for page in about projects; do ng generate component “portfolio/${page}”; done

این دستور از طریق نام هر صفحه حلقه زده و آنها را تولید می کند.

پر کردن صفحه درباره

صفحه “درباره” نمایه عمیق تری از شما نمایش می دهد. اطلاعات این صفحه از سرویس بیو بازیابی شده و از مدل بیو نیز استفاده می کند. این جزء در صفحه اصلی نمایش داده می شود. همچنین یک صفحه مستقل با مسیر خاص خود خواهد بود.

برای پر کردن صفحه «درباره» با بیو خود، فایل مؤلفه «درباره» را برای استفاده از سرویس بیو تغییر دهید. همچنین گزینه هایی را برای پاسخگویی صفحه در نمایشگرهای مختلف تنظیم خواهید کرد. src/app/portfolio/about/about.component.ts را باز کرده و خطوط هایلایت شده را اضافه کنید:

src/app/portfolio/about/about.component.ts

import { Component } from '@angular/core';
import { BioService } from '../../core/services/bio.service';

@Component({
  selector: 'app-about',
  templateUrl: './about.component.html',
  styleUrls: ['./about.component.css']
})
export class AboutComponent {
  bio$ = this.bioService.getBio();

  respOptions = [
    { viewClasses: 'd-none d-md-flex', headingClass: 'display-3', useSmallerHeadings: false },
    { viewClasses: 'd-flex d-md-none', headingClass: '', useSmallerHeadings: true }
  ];

  constructor(private bioService: BioService) { }
}

اطلاعات “درباره” از BioService می آید و پس از فراخوانی متد getBio آن، قابل مشاهده در ویژگی bio$ ذخیره می شود. respOptions با ارائه کلاس های CSS اختیاری برای اندازه های مختلف نمایش به پاسخگویی کمک می کند.

ذخیره کنید و فایل را ببندید.

در مرحله بعد، الگوی صفحه “درباره” را تغییر می دهید تا بتوانید اطلاعات بازیابی شده از سرویس بیو را نمایش دهید. src/app/portfolio/about/about.component.html را باز کنید و خطوط زیر را اضافه کنید:

src/app/portfolio/about/about.component.html

<div class="d-flex justify-content-center vw-90 mx-auto" *ngIf="bio$ | async as bio">
    <div *ngFor="let options of respOptions" [ngClass]="options.viewClasses"
        class="flex-column align-items-center text-center w-75">
        <h1 [ngClass]="options.headingClass" class="mb-5"><span class="font-weight-bold">About</span> Me</h1>
        <div *ngFor="let par of bio.about">
            <h4 *ngIf="!options.useSmallerHeadings" class="mb-4">{{par}}</h4>
            <h5 *ngIf="options.useSmallerHeadings" class="mb-4">{{par}}</h5>
        </div>
    </div>
</div>

در این قالب، داده های موجود در bio$ observable را نمایش می دهید. بخش «درباره» اطلاعات را مرور می‌کنید و آن را به عنوان پاراگراف به صفحه «درباره» اضافه می‌کنید.

ذخیره کنید و فایل را ببندید.

پس از تکمیل، صفحه «درباره» به این شکل خواهد بود (در مرحله آخر می توانید پیش نمایش سایت را مشاهده کنید):

پر کردن صفحه پروژه ها

صفحه “پروژه ها” تمام پروژه های شما را که از سرویس پروژه ها بازیابی شده اند نشان می دهد. این کامپوننت در صفحه اصلی استفاده خواهد شد و همچنین یک صفحه مستقل خواهد بود. در صفحه اصلی همراه با مولفه “درباره” نمایش داده می شود. هنگامی که این مؤلفه در صفحه اصلی استفاده می شود، فقط پروژه های برجسته باید قابل مشاهده باشند. یک دکمه See More Projects وجود دارد که فقط در صفحه اصلی ظاهر می شود. وقتی روی آن کلیک کردید، به صفحه پروژه‌های فهرست کامل هدایت می‌شود.

برای پر کردن صفحه «پروژه‌ها»، فایل مؤلفه آن را برای دریافت پروژه‌ها از سرویس پروژه‌ها تغییر می‌دهید. همچنین از سرویس هدر برای تعیین اینکه آیا همه پروژه ها نمایش داده می شوند یا برجسته شده استفاده خواهید کرد. همچنین گزینه هایی را اضافه می کنید تا صفحه را در اندازه های مختلف صفحه نمایش پاسخگو کنید. src/app/portfolio/projects/projects.component.ts را باز کنید و خطوط هایلایت شده را اضافه کنید:

src/app/portfolio/projects/projects.component.ts

import { Component } from '@angular/core';
import { mergeMap } from 'rxjs/operators';
import { HeaderService } from '../../core/services/header.service';
import { ProjectsService } from '../../core/services/projects.service';

@Component({
  selector: 'app-projects',
  templateUrl: './projects.component.html',
  styleUrls: ['./projects.component.css']
})
export class ProjectsComponent {
  isHome$ = this.headerService.isHome();
  projects$ = this.isHome$.pipe(
    mergeMap(atHome => this.projectsService.getProjects(atHome))
  );

  respOptions = [
    { viewClasses: 'd-none d-md-flex', displayInColumn: false, useSmallerHeadings: false, titleClasses: 'display-3' },
    { viewClasses: 'd-flex d-md-none', displayInColumn: true, useSmallerHeadings: true, titleClasses: '' }
  ];

  constructor(private projectsService: ProjectsService, private headerService: HeaderService) { }
}

پروژه ها از ProjectsService می آیند. برای تعیین اینکه آیا صفحه فعلی صفحه اصلی است یا خیر از HeaderService استفاده خواهید کرد. شما از مقدار isHome$ برای تعیین اینکه آیا لیست کامل پروژه ها را واکشی کنید یا فقط پروژه های برجسته را تعیین کنید، استفاده خواهید کرد.

ذخیره کنید و فایل را ببندید.

در مرحله بعد، الگوی اجزای پروژه را تغییر خواهید داد. با استفاده از پروژه‌هایی که از سرویس پروژه‌ها دریافت کرده‌اید، آنها را حلقه زده و در اینجا اضافه می‌کنید. شما اطلاعات اولیه در مورد هر پروژه را در یک کارت نمایش خواهید داد و پیوندهایی را به جایی که کد آنها میزبانی می شود و جایی که می توانید آنها را پیش نمایش کنید اضافه کنید.

src/app/portfolio/projects/projects.component.html را باز کرده و خطوط زیر را اضافه کنید:

src/app/portfolio/projects/projects.component.html

<div *ngFor="let options of respOptions" [ngClass]="options.viewClasses"
    class="flex-column align-items-center text-center vw-90 mx-auto">
    <h1 [ngClass]="options.titleClasses" class="mb-5"><span class="font-weight-bold">My</span> Projects</h1>
    <div class="d-flex vw-90"
        [ngClass]="{'justify-content-center flex-wrap': !options.displayInColumn, 'flex-column  align-items-center': options.displayInColumn}"
        *ngIf="projects$ | async as projects">
        <div *ngFor="let project of projects" class="card project-card m-3"
            [ngClass]="{'m-3': !options.displayInColumn, 'mb-3': options.displayInColumn}">
            <div class="card-body d-flex flex-column">
                <h5 class="card-title font-weight-bold text-left project-title" [title]="project.name">
                    {{project.name}}
                </h5>
                <h6 class="card-subtitle mb-2 font-weight-lighter text-left">
                    <i [ngClass]="project.stack.iconClasses"></i>
                    {{project.stack.name}}
                </h6>
                <p class="card-text text-left">
                    {{project.description}}
                </p>
                <div class="d-flex flex-row justify-content-start">
                    <a [href]="project.previewUrl" *ngIf="project.previewUrl" class="btn btn-dark mr-2">
                        <i class="fa-lg mr-1 far fa-eye"></i>
                        Preview
                    </a>
                    <a [href]="project.sourceUrl" *ngIf="project.sourceUrl" class="btn btn-dark">
                        <i class="fa-lg mr-1 fab fa-github-alt"></i>
                        Source
                    </a>
                </div>
            </div>
        </div>
    </div>
    <button *ngIf="isHome$ | async" routerLink="/projects" class="mt-3 btn btn-dark">
        See More Projects
        <i class="ml-1 fas fa-angle-right"></i>
    </button>
</div>

در اینجا شما هر پروژه را از پروژه $ به یک کارت اضافه می کنید. در کارت، نام پروژه (project.name)، پشته فناوری استفاده شده در آن (project.stack) و توضیح مختصری (project.description) از کارهایی که انجام می دهد را نمایش می دهید. همچنین پیوندهایی را به جایی که کد پروژه میزبانی شده است اضافه خواهید کرد. علاوه بر این، پیوندی به جایی که پروژه در صورت استقرار آن قابل اجرا باشد، اضافه می‌کنید. در نهایت، دکمه See More Projects وجود دارد که فقط در صفحه اصلی نمایش داده می شود. در صفحه اصلی، فقط پروژه های برجسته نمایش داده می شوند. هنگامی که این دکمه کلیک می شود، کاربر به لیست کاملی از پروژه ها هدایت می شود.

ذخیره کنید و فایل را ببندید.

در مرحله بعد، با تغییر الگوی پروژه ها، به کارت های پروژه استایل می دهید. src/app/portfolio/projects/projects.component.css را باز کنید و خطوط زیر را اضافه کنید:

src/app/portfolio/projects/projects.component.css

.vw-20 {
    width: 20vw;
}

.project-card {
    width: 290px;
    height: 250px;
}

.project-title {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 20ch;
}

در اینجا، اندازه کارت پروژه و عناوین پروژه را تنظیم می کنید که کمی طولانی تر هستند.

پس از تکمیل، فهرست کامل صفحه «پروژه» به این شکل خواهد بود (در مرحله آخر می‌توانید پیش‌نمایش سایت را مشاهده کنید):

اضافه کردن بقیه مسیرهای نمونه کارها

برای دسترسی به هر صفحه، باید یک مسیر برای هر یک ایجاد کنید. شما اینها را در PortfolioRoutingModule اضافه خواهید کرد که مسیریابی PortfolioModule را انجام می دهد. صفحه “درباره” باید در /about و صفحه “پروژه ها” در /projects موجود باشد.

برای ایجاد مسیرها برای صفحات ماژول نمونه کارها، فایل ماژول مسیریابی پورتفولیو را که مسئول مسیریابی است، تغییر می دهید. src/app/portfolio/portfolio-routing.module.ts را باز کنید و خطوط هایلایت شده را اضافه کنید:

src/app/portfolio/portfolio-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { ProjectsComponent } from './projects/projects.component';
import { AboutComponent } from './about/about.component';

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'about', component: AboutComponent },
  { path: 'projects', component: ProjectsComponent }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class PortfolioRoutingModule { }

در اینجا، با مشخص کردن مسیرهای اجزا و اضافه کردن آنها به آرایه مسیرها، مسیرها را به صفحات «درباره» و «پروژه‌ها» اضافه می‌کنید.

در این مرحله ماژول نمونه کارها را با ایجاد هر یک از سه صفحه آن و اضافه کردن مسیرها برای آنها تکمیل کردید. در مرحله بعد کامپوننت وبلاگ را تولید خواهید کرد.

مرحله 4 – ایجاد ماژول وبلاگ

در این مرحله، ماژول وبلاگ را که حاوی صفحات فرود و پست وبلاگ شما است، تولید می کنید. به جای اینکه وبلاگ را از ابتدا بسازید، از شماتیک اسکالی برای تنظیم تمام موارد مورد نیاز برای یک وبلاگ کارآمد استفاده خواهید کرد. شماتیک اسکالی ماژول را تولید می کند، یک ماژول مسیریابی برای مدیریت مسیریابی به وبلاگ اضافه می کند و یک جزء وبلاگ ایجاد می کند که یک پست وبلاگ را نمایش می دهد. مؤلفه وبلاگ پست هایی را که در فایل های علامت گذاری می نویسید نمایش می دهد. در مرحله بعد با ایجاد پست های وبلاگ جدید، محل این فایل های علامت گذاری را خواهید دید. هنگام رندر کردن وبلاگ، اسکالی نسخه‌های علامت‌گذاری شده پست‌های وبلاگی را که ایجاد کرده‌اید می‌گیرد و آنها را به صفحات HTML ثابت تبدیل می‌کند، که سریع‌تر به خوانندگان ارائه می‌شوند.

می‌توانید پشتیبانی وبلاگ را برای برنامه فعال کنید و با اجرای دستور زیر از ریشه پروژه، ماژول را ایجاد کنید:

ng generate @scullyio/init:blog

دستور بالا ماژول وبلاگ را در src/app/blog ایجاد می‌کند، یک پوشه وبلاگ در پایه پروژه می‌سازد، جایی که فایل‌های علامت‌گذاری وبلاگ در آن قرار می‌گیرند، یک مسیر تنبل برای ماژول در AppRoutingModule اضافه می‌کند و یک جزء وبلاگ در پایه آن ایجاد می‌کند. ماژول

در مرحله بعد، یک پوشه در ماژول ایجاد کنید که مؤلفه وبلاگ در آن قرار دارد.

mkdir src/app/blog/blog

برای انتقال کامپوننت وبلاگ به این پوشه، اجرا کنید:

mv src/app/blog/blog.component.* src/app/blog/blog/

این منجر به ساختار این ماژول وبلاگ می شود:

src/app/blog

src/app/blog
├── blog
│   ├── blog.component.css
│   ├── blog.component.html
│   ├── blog.component.spec.ts
│   └── blog.component.ts
├── blog-routing.module.ts
└── blog.module.ts

از آنجایی که این ماژول بازسازی شده است، برخی از مسیرها شکسته شده و نیاز به به روز رسانی دارند. دو فایل، blog-routing.module.ts و blog.module.ts، باید با مسیرهای جدید به BlogComponent به روز شوند.

blog-routing.module.ts را باز کنید و وارد کردن را مطابق شکل به روز کنید:

src/app/blog/blog-routing.module.ts

...
import { BlogComponent } from './blog/blog.component';
...

ذخیره کنید و فایل را ببندید.

بعد، blog.module.ts را باز کنید و وارد کردن را مطابق شکل به روز کنید:

src/app/blog/blog.module.ts

...
import { BlogComponent } from './blog/blog.component';
...

ذخیره کنید و فایل را ببندید.

در مرحله بعد، الگوی مولفه وبلاگ را اصلاح خواهید کرد. نقش مؤلفه وبلاگ نمایش یک پست وبلاگ است. این مؤلفه به حداقل ویرایش نیاز دارد زیرا شماتیک وبلاگ اسکالی قبلاً آن را پر کرده است. به ظرفی که محتوای پست وبلاگ را در خود جای می دهد، یک ظاهر طراحی می کنید. src/app/blog/blog/blog.component.html را باز کنید و محتوای boilerplate را با خطوط زیر جایگزین کنید:

src/app/blog/blog/blog.component.html

<div class="vw-70">
    <scully-content></scully-content>
</div>

استایلی که به الگو اضافه شده است باعث می‌شود که مولفه وبلاگ با فاصله بهتری در صفحه قرار گیرد. <scully-content></scully-content> محتوای وبلاگ علامت گذاری شده را ارائه می کند.

ذخیره کنید و فایل را ببندید.

در مرحله بعد، با قرار دادن سرفصل‌ها در مرکز، استایل را تغییر می‌دهید، که ظاهر و احساس بهتری را برای مؤلفه وبلاگ ایجاد می‌کند. src/app/blog/blog/blog.component.css را باز کنید و محتوا را با این خطوط جایگزین کنید:

src/app/blog/blog/blog.component.css

h1, h2, h3, h4, h5, h6 {
  text-align: center;
  padding: 1rem;
}

ذخیره کنید و فایل را ببندید.

پس از تکمیل، وبلاگ به این شکل خواهد بود (در مرحله آخر می توانید پیش نمایش سایت را مشاهده کنید):

ایجاد صفحه فرود وبلاگ

اکنون که ماژول وبلاگ را ایجاد کرده اید و استایلی را به پست های وبلاگ اضافه کرده اید، صفحه فرود وبلاگ را ایجاد می کنید و یک استایل به صفحه فرود اضافه می کنید.

صفحه فرود وبلاگ همه پست های وبلاگ شما را فهرست می کند. با اجرای دستور زیر در ریشه پروژه می توانید آن را ایجاد کنید:

ng generate component blog/blog-landing

این به این ساختار منجر می شود:

src/app/blog

src/app/blog
├── blog
│   ├── blog.component.css
│   ├── blog.component.html
│   ├── blog.component.spec.ts
│   └── blog.component.ts
├── blog-landing
│   ├── blog-landing.component.css
│   ├── blog-landing.component.html
│   └── blog-landing.component.ts
├── blog-routing.module.ts
└── blog.module.ts

در مرحله بعد، فایل کامپوننت را برای صفحه فرود وبلاگ تغییر می‌دهید تا همه پست‌های وبلاگ فهرست شود. در اینجا تمام صفحاتی که دارای /blog/ در مسیر خود هستند را دریافت کرده و آنها را در یک لیست نمایش می دهید. همچنین گزینه هایی برای پاسخگو کردن صفحه در اندازه های مختلف صفحه اضافه خواهید کرد.

src/app/blog/blog-landing/blog-landing.component.ts را باز کنید و تغییرات زیر را اعمال کنید:

src/app/blog/blog-landing/blog-landing.component.ts

import { Component } from '@angular/core';
import { ScullyRoute, ScullyRoutesService } from '@scullyio/ng-lib';
import { map } from 'rxjs/operators';

@Component({
  selector: 'app-blog-landing',
  templateUrl: './blog-landing.component.html',
  styleUrls: ['./blog-landing.component.css']
})
export class BlogLandingComponent {
  links$ = this.scully.available$.pipe(
    map(routes => routes.filter((route: ScullyRoute) => route.route.startsWith('/blog/')))
  );

  respOptions = [
    { viewClasses: 'd-none d-md-flex', displayInColumn: false, titleClasses: 'display-3' },
    { viewClasses: 'd-flex d-md-none', displayInColumn: true, titleClasses: '' }
  ];

  constructor(private scully: ScullyRoutesService) { }
}

برای دریافت لیستی از تمام مسیرهای وبلاگ، از ScullyRoutesService استفاده خواهید کرد. قابل مشاهده $ موجود، تمام مسیرهایی را که توسط Scully ارائه شده و به عنوان منتشر شده علامت گذاری شده است، برمی گرداند. شما می توانید مشخص کنید که آیا یک پست وبلاگ منتشر شده است یا نه در فایل نشانه گذاری آن. (در مرحله بعدی به این موضوع پرداخته خواهد شد.) این قابل مشاهده همه مسیرها، از جمله مسیرهای موجود در نمونه کارها را برمی گرداند. بنابراین شما فقط مسیرهای حاوی پیشوند /blog/ را فیلتر خواهید کرد. مسیرهای وبلاگ توسط ویژگی links$ نگهداری می شود. ویژگی respOptions به پاسخگویی کمک می کند.

ذخیره کنید و فایل را ببندید.

در مرحله بعد، الگوی صفحه فرود وبلاگ را تغییر می دهید تا همه پست های وبلاگ موجود را در کارت لیست کرده و به آنها پیوند دهید. عنوان وبلاگ را نیز در خود دارد. src/app/blog/blog-landing/blog-landing.component.html را باز کنید و خطوط زیر را اضافه کنید:

src/app/blog/blog-landing/blog-landing.component.html

<div *ngFor="let options of respOptions" [ngClass]="options.viewClasses"
    class="flex-column align-items-center text-center vw-90 mx-auto">
    <h1 [ngClass]="options.titleClasses" class="mb-5"><span class="font-weight-bold">Jane's</span> Blog</h1>
    <div [ngClass]="{'justify-content-center flex-wrap': !options.displayInColumn,  'flex-column align-items-center': options.displayInColumn}"
        class="d-flex vw-90">
        <div *ngFor="let page of links$ | async" class="card post-card m-3">
            <div class="card-img-top bg-dark">
                <i class="far fa-newspaper fa-4x m-5 text-white"></i>
            </div>
            <div class="card-body d-flex flex-column">
                <h5 class="card-title post-title" [title]="page.title">{{page.title}}</h5>
                <p class="card-text post-description flex-grow-1">{{page.description}}</p>
                <a [routerLink]="page.route" class="btn btn-outline-dark align-self-center">
                    <i class="fa-lg mr-1 far fa-eye"></i>
                    Read
                </a>
            </div>
        </div>
    </div>
</div>

در این الگو، تمام پست‌های وبلاگی را که توسط سرویس روتر اسکالی برگردانده شده است، مرور خواهید کرد. برای هر پست وبلاگ، یک کارت اضافه می کنید. در هر کارت عنوان پست وبلاگ و توضیحات نمایش داده می شود. همچنین یک لینک اضافه شده است که می توانید روی آن کلیک کنید تا به پست وبلاگ بروید.

ذخیره کنید و فایل را ببندید.

در نهایت، یک استایل به قالب فرود وبلاگ اضافه خواهید کرد. به کارت های پروژه ای که به صفحه اضافه می شوند استایل می دهد. src/app/blog/blog-landing/blog-landing.component.css را باز کنید و خطوط زیر را اضافه کنید:

src/app/blog/blog-landing/blog-landing.component.css

.post-card {
    width: 290px;
    height: 360px;
}

.post-title {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 20ch;
}

ذخیره کنید و فایل را ببندید.

پس از تکمیل (و پس از افزودن پست های وبلاگ)، صفحه فرود وبلاگ به این شکل خواهد بود (در مرحله آخر می توانید پیش نمایش سایت را مشاهده کنید):

افزودن مسیر فرود بلاگ

برای دسترسی به صفحه فرود وبلاگ در مسیر /blog، باید یک مسیر برای آن در BlogRoutingModule اضافه کنید. بدون افزودن این، برای برنامه در دسترس نخواهد بود. src/app/blog/blog-routing.module.ts را باز کنید و خطوط هایلایت شده را اضافه کنید:

src/app/blog/blog-routing.module.ts

...
import { BlogLandingComponent } from './blog-landing/blog-landing.component';

const routes: Routes = [
  { path: '', component: BlogLandingComponent },
  { path: ':slug', component: BlogComponent },
  { path: '**', component: BlogComponent }
];
...

در اینجا شما مسیر BlogLandingComponent را به آرایه مسیرها اضافه کردید. این باعث می شود که در مسیر /blog قابل دسترسی باشد.

ذخیره کنید و فایل را ببندید.

در این مرحله، یک ماژول وبلاگ ایجاد کردید که شامل دو صفحه است: یک صفحه پست وبلاگ و یک صفحه فرود وبلاگ. شما یک سبک به این صفحات اضافه کردید و مسیر فرود وبلاگ را اضافه کردید تا صفحه فرود در مسیر وبلاگ / قابل دسترسی باشد. در مرحله بعد، پست های جدید وبلاگ را اضافه خواهید کرد.

مرحله 5 – اضافه کردن پست های جدید وبلاگ

در این مرحله از Scully برای ایجاد پست های وبلاگ جدید که در صفحه فرود وبلاگ نمایش داده می شوند استفاده خواهید کرد. با Scully، می توانید فایل های علامت گذاری ایجاد کنید که به عنوان پست های وبلاگ شما خدمت می کنند. مؤلفه وبلاگی که در مرحله قبل ایجاد کردید، نسخه علامت گذاری شده یک پست وبلاگ را می خواند و سپس آن را نمایش می دهد. Markdown نوشتن محتوای وبلاگ با فرمت غنی را به سرعت و به راحتی آسان می کند. Scully این فایل‌ها را ایجاد می‌کند و پوشه‌هایی را نیز اضافه می‌کند تا آنها را برای شما در خود جای دهد. همچنین ابرداده مانند عنوان و توضیحات را به هر پست اضافه می کند. برخی از ابرداده ها برای تعیین نحوه نمایش یک پست استفاده می شود. بعداً، از Scully برای تولید نسخه‌های صفحه HTML ایستا از این پست‌های وبلاگ علامت‌گذاری شده استفاده خواهید کرد.

قبل از اینکه بتوانید یک پست ایجاد کنید، باید یک نام بیاورید. برای این آموزش، یک پست با عنوان “پست وبلاگ 1” ایجاد خواهید کرد. شما این نام را با استفاده از پرچم –name از ریشه پروژه به دستور زیر ارائه می دهید.

ng generate @scullyio/init:post –name=”Blog Post 1″

خروجی شبیه به این خواهد بود:

 

Output

? What's the target folder for this post? blog
    ✅️ Blog ./blog/blog-post-1.md file created
CREATE blog/blog-post-1.md (103 bytes)

با این کار یک فایل /blog/blog-post-1.md در ریشه پروژه ایجاد می شود. محتویات فایل مشابه این خواهد بود:

blog/blog-post-1.md

---
title: Blog Post 1
description: blog description
published: false
---

# Blog Post 1

هنگامی که محتوایی را به پست وبلاگ خود اضافه کردید و از آن راضی بودید، می توانید محتوای منتشر شده را به درست تغییر دهید و هنگامی که سایت را ارائه می کنید در صفحه فرود وبلاگ ظاهر می شود. برای مشاهده پست هایی که هنوز منتشر نشده اند، می توانید از ویژگی Slug استفاده کنید.

به عنوان مثال، فرض کنید این slug را اضافه کرده اید:

blog/blog-post-1.md

---
title: Blog Post 1
description: blog description
published: true
slug: alternate-url-for-blog-post-1
---

# Blog Post 1

هنگامی که سرور را اجرا می کنید، می توانید این پست را در https://localhost:1668/blog/alternate-url-for-blog-post-1 مشاهده کنید. با این حال، این پست منتشر نشده در صفحه فرود وبلاگ نشان داده نمی شود مگر اینکه به عنوان منتشر شده علامت گذاری شود: درست است. هنگامی که مسیرهای اسکالی را ایجاد می کنید، همانطور که در مرحله بعد خواهید دید، اسکالی یک اسلاگ برای همه پست های منتشر نشده شما اضافه می کند تا مجبور نباشید.

برای افزودن محتوا به پست خود، بعد از عنوان شروع کنید. تمام محتوای پست باید در علامت گذاری باشد. در اینجا نمونه ای از محتوایی است که می توانید در پست علامت گذاری که ایجاد کرده اید استفاده کنید:

/blog/blog-post-1.md

---
title: Blog Post 1
description: Your first blog post
published: true
---

# Blog Post 1

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vitae tempor erat, eget accumsan lorem. Ut id sem id massa mattis dictum ullamcorper vitae massa. In luctus neque lectus, quis dictum tortor elementum sit amet. Mauris non lacinia nisl. Nulla tristique arcu quam, quis posuere diam elementum nec. Curabitur in mi ut purus bibendum interdum ut sit amet orci. Duis aliquam tristique auctor. Suspendisse magna magna, pellentesque vitae aliquet ac, sollicitudin faucibus est. Integer semper finibus leo, eget placerat enim auctor quis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed aliquam nibh in mi convallis mattis nec ac mi. Nam sed sagittis purus.

پس از اتمام، فایل را ذخیره کرده و ببندید.

با اجرای زیر می توانید پست های دیگری ایجاد کنید:

ng generate @scullyio/init:post –name=”Blog Post 2″
ng generate @scullyio/init:post –name=”Blog Post 3″

این دستورات دو فایل علامت گذاری دیگر را در پوشه /blog/ با نام هایی که شما اختصاص داده اید ایجاد می کند. می توانید مانند پست اول فایل های تولید شده را با محتوای نمونه بالا پر کنید.

در این مرحله، شما اولین پست وبلاگ اسکالی خود را ایجاد کردید. مرحله زیر تغییراتی را که باید برای تکمیل برنامه انجام دهید را پوشش می دهد.

مرحله 6 – فعال کردن Anchor Scrolling و پاک کردن الگوی مؤلفه برنامه

آخرین کاری که باید قبل از پیش‌نمایش برنامه انجام دهید، فعال کردن لنگر اسکرول، اضافه کردن استایل سراسری، و تمیز کردن app.component.html است.

در صفحه اصلی، زمانی که یک بازدیدکننده روی موارد موجود در هدر کلیک می کند، باید به بخش های خاص در همان صفحه هدایت شوند. برای انجام این کار، باید انکر اسکرول را در اپلیکیشن Angular فعال کنید. انجام همه این تغییرات اسکرول به بخش های صفحه اصلی را ممکن می کند.

ابتدا فایل ماژول را برای ماژول مسیریابی برنامه تغییر می دهید. این ماژول مسئول مسیریابی در کل برنامه است. در اینجا اسکرول لنگر را فعال خواهید کرد. src/app/app-routing.module.ts را باز کنید و قسمت برجسته شده را اضافه کنید:

src/app/app-routing.module.ts

...
@NgModule({
  imports: [RouterModule.forRoot(routes, { anchorScrolling: 'enabled' })],
  exports: [RouterModule]
})
...

آخرین کاری که باید قبل از پیش‌نمایش برنامه انجام دهید، فعال کردن لنگر اسکرول، اضافه کردن استایل سراسری، و تمیز کردن app.component.html است.

در صفحه اصلی، زمانی که یک بازدیدکننده روی موارد موجود در هدر کلیک می کند، باید به بخش های خاص در همان صفحه هدایت شوند. برای انجام این کار، باید انکر اسکرول را در اپلیکیشن Angular فعال کنید. انجام همه این تغییرات اسکرول به بخش های صفحه اصلی را ممکن می کند.

ابتدا فایل ماژول را برای ماژول مسیریابی برنامه تغییر می دهید. این ماژول مسئول مسیریابی در کل برنامه است. در اینجا اسکرول لنگر را فعال خواهید کرد. src/app/app-routing.module.ts را باز کنید و قسمت برجسته شده را اضافه کنید:

از آنجایی که به این محتوای نگهدارنده در پورتفولیوی خود نیاز نخواهید داشت، آن را حذف خواهید کرد.

برای حذف کد متغیر ایجاد شده از صفحه اصلی، src/app/app.component.html را باز کنید و محتوای آن را با خطوط زیر جایگزین کنید:

src/app/app.component.html

<div class="d-flex flex-column h-100 w-100">
    <app-header></app-header>
    <div class="d-flex flex-column flex-grow-1 align-items-center justify-content-center">
        <router-outlet></router-outlet>
    </div>
</div>

در این فایل، app-header، کامپوننت هدر را اضافه می‌کنید و یک div کانتینری در اطراف خروجی روتر قرار می‌دهید تا صفحات مسیریابی شده در زیر آن نمایش داده شوند.

در مرحله بعد، باید مطمئن شوید که AppModule به app-header دسترسی دارد. از آنجایی که app-header در ماژول دیگری وجود دارد، App Module در حال حاضر به آن دسترسی ندارد. شما باید CoreModule را به عنوان import به src/app/app.module.ts اضافه کنید زیرا CoreModule دسترسی به مولفه هدر را فراهم می کند. app.module.ts را باز کنید و import را همانطور که در زیر مشخص شده است اضافه کنید.

src/app/app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ScullyLibModule } from '@scullyio/ng-lib';
import { CoreModule } from './core/core.module';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    ScullyLibModule,
    CoreModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

ایجاد این تغییر تضمین می کند که AppModule به app-header دسترسی دارد.

در نهایت، با تغییر src/styles.css، تغییراتی در استایل کلی برنامه ایجاد خواهید کرد. چندین مؤلفه در سراسر برنامه از استایل موجود در این فایل استفاده می کنند. این به ظاهر و احساس کلی برنامه کمک می کند و از تکرار جلوگیری می کند زیرا استایل در همه اجزاء مورد استفاده مجدد قرار می گیرد.

قبل از اجرای سایت، src/styles.css را باز کرده و خطوط زیر را اضافه کنید:

src/styles.css

html, body {
    width: 100%;
    height: 100%;
}

body {
    font-family: 'Nunito', Arial, Verdana, Geneva, Tahoma, sans-serif;
    background: white;
    background-image: radial-gradient(lightgray 5.5%, transparent 0);
    background-size: 30px 30px;
}

.vw-90 {
    width: 90vw;
}

.vw-80 {
    width: 80vw;
}

.vw-70 {
    width: 80vw;
}

.min-vh-10 {
    min-height: 10vh;
}

در این فایل، اطمینان حاصل می کنید که html و بدنه ارتفاع و عرض تمام صفحه را می گیرند. شما همچنین Nunito را فونت پیش‌فرض قرار می‌دهید و کلاس‌های سبک مختلفی را برای تنظیم عرض و ارتفاع در آن قرار می‌دهید.

در این مرحله، اسکرول لنگر را فعال کردید، استایل کلی را اضافه کردید و قالب مؤلفه برنامه را پاکسازی کردید. در مرحله بعد، سایت را می سازید، مسیرهای Scully را رندر می کنید و نمونه کارها را سرویس می دهید.

مرحله 7 – پیش نمایش سایت استاتیک

اکنون که تمام تغییرات کد لازم را انجام داده اید، می توانید نمونه کارها را با Scully پیش نمایش کنید. این شامل ساخت سایت شما، تولید مسیرهای اسکالی و سپس ارائه نسخه ثابت سایت می شود. در این مرحله، اسکالی برنامه Angular شما را از قبل در یک سایت استاتیک رندر می کند و سروری را برای سرویس دهی به برنامه Angular و نمونه کارها استاتیک ارائه می دهد.

قبل از اینکه اسکالی بتواند نمونه کارها را از قبل رندر کند، باید آن را بسازید.

ng build

این دستور پورتفولیو شما را به dist/portfolio کامپایل می کند.

خروجی شبیه به این خواهد بود:

Compiling @angular/core : es2015 as esm2015
Compiling @angular/common : es2015 as esm2015
Compiling @angular/platform-browser : es2015 as esm2015
Compiling @angular/router : es2015 as esm2015
Compiling @angular/platform-browser-dynamic : es2015 as esm2015
Compiling @angular/common/http : es2015 as esm2015
Compiling @angular/forms : es2015 as esm2015
Compiling @scullyio/ng-lib : es2015 as esm2015
Compiling @ng-bootstrap/ng-bootstrap : es2015 as esm2015
✔ Browser application bundle generation complete.
✔ Copying assets complete.
✔ Index html generation complete.

Initial Chunk Files           | Names                      |      Size
vendor.js                     | vendor                     |   3.49 MB
styles.css                    | styles                     | 202.25 kB
polyfills.js                  | polyfills                  | 141.85 kB
main.js                       | main                       |  24.91 kB
runtime.js                    | runtime                    |   9.06 kB

                              | Initial Total              |   3.86 MB

Lazy Chunk Files              | Names                      |      Size
portfolio-portfolio-module.js | portfolio-portfolio-module |  34.19 kB
blog-blog-module.js           | blog-blog-module           |  15.28 kB

Build at:  - Hash:  - Time: 29012ms

وقتی ساخت کامل شد، اجرا کنید:

npx scully

اسکالی کل نمونه کارها را با طی کردن هر مسیر و ایجاد یک index.html جداگانه برای هر یک از آنها از قبل رندر می کند. نمونه کار از پیش رندر شده در dist/static قرار خواهد گرفت. این پوشه باید شبیه این باشد. (برخی فایل ها برای وضوح حذف شده اند.)

dist/static

dist/static
├── about
│   └── index.html
├── assets
├── blog
│   ├── angular-unit-testing
│   │   └── index.html
│   ├── create-a-blog-using-vue.js
│   │   └── index.html
│   ├── how-to-create-a-twitter-bot
│   │   └── index.html
│   └── index.html
├── index.html
└── projects
    └── index.html

توجه کنید که چگونه هر مسیر فایل index.html جداگانه خود را دارد.

برای پیش نمایش سایت استاتیک، اجرا کنید:

npm run scully:serve

این دستور یک سرور Scully استاتیک را در http://localhost:1668/ راه اندازی می کند و نمونه کارها استاتیک شما را ارائه می دهد. (زمانی که پیش نمایش سایت خود را به پایان رساندید، می توانید سرور را با Ctrl + C در ترمینالی که سرور در آن اجرا می کند، بکشید.)

scully.portfolio.config.ts

import { ScullyConfig } from '@scullyio/scully';
export const config: ScullyConfig = {
  projectRoot: "./src",
  projectName: "portfolio",
  outDir: './dist/static',
  routes: {
    '/blog/:slug': {
      type: 'contentFolder',
      slug: {
        folder: "./blog"
      }
    },
  },
  puppeteerLaunchOptions: {args: ['--no-sandbox', '--disable-setuid--sandbox']}
};

صفحه اصلی http://localhost:4200 باید به این صورت باشد:

در این مرحله، شما اپلیکیشن Angular خود را ساخته اید، آن را از قبل در یک سایت استاتیک رندر کرده و با استفاده از Scully به آن سرویس داده اید.

نتیجه

در این آموزش، شما یک برنامه نمونه کارها Angular را تولید و پیکربندی کردید. شما همچنین یک ماژول اصلی برای مدیریت داده های نمونه کارها و نگه داشتن اجزای اصلی برنامه ایجاد کردید. علاوه بر این، شما یک ماژول نمونه کارها متشکل از صفحات ضروری ساخته اید که بیوگرافی، پروژه ها و مشخصات شما را به نمایش می گذارد. شما یک ماژول وبلاگ از صفحات فرود و پست وبلاگ خود ساخته اید. در نهایت، شما نمونه کارها Angular خود را با استفاده از Scully به یک سایت ثابت تبدیل کردید.

هنوز کارهای زیادی برای انجام دادن با نمونه کارها وجود دارد. می توانید صفحاتی را برای نشان دادن مهارت ها و مقالاتی که نوشته اید اضافه کنید. همچنین می توانید یک صفحه تماس اضافه کنید تا افراد بتوانند با شما در تماس باشند. اگر تعاملات سخنرانی، یک کانال آموزشی ویدیویی، یک پادکست یا سخنرانی در کنفرانس دارید، می توانید صفحاتی برای نشان دادن آنها ایجاد کنید.

 

https://vpsgol.net/product/vps-germany/

 

https://vpsgol.net/product/vps-usa/

 

https://vpsgol.net/product/vps-france/

 

https://vpsgol.net/product/vps-canada/

 

https://vpsgol.net/product/vps-poland/

 

https://vpsgol.net/product/vps-netherlands/

 

https://vpsgol.net/product/vps-england/

 

برچسب‌ها:Angular 11Jamstack PortfolioScullyاتصال به سرور مجازی لینوکسخرید سرورراه اندازی برنامه Angularراه اندازی سرورسرورسرور مجازینصب Dependencies

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه استایل دادن به عناصر HTML با حاشیه ها، سایه ها و خطوط در CSS

ورود به سایت

معرفی

کار با سایه‌ها، حاشیه‌ها و خطوط کلی یکی از اجزای کلیدی توسعه وب است و می‌تواند تعریف بصری پیرامون عناصر HTML و آیتم‌های متنی ارائه دهد. ظاهر حاشیه ها و سایه ها را می توان از طریق پنج ویژگی اصلی CSS دستکاری کرد: border، border-radius، box-shadow، text-shadow و outline. سایه ها عمق را فراهم می کنند و به عناصر کمک می کنند تا برجسته شوند، در حالی که ویژگی های حاشیه می توانند عملکردهای بصری مختلفی را انجام دهند، از ایجاد یک تقسیم کننده خطی بین محتوا تا تعریف فضای یک شبکه. ویژگی border-radius گوشه های گردی را روی جعبه ها ایجاد می کند و حتی می تواند یک شکل دایره ای ایجاد کند. در نهایت، outline یک ویژگی است که اغلب نادیده گرفته می شود که بسیاری از عملکردهای مشابه ویژگی مرزی را بدون ایجاد اختلال در جریان محتوا ارائه می دهد.

در این آموزش، شما با این املاک کار خواهید کرد تا یک اعلامیه قانونی برای یک شرکت گردشگری فضایی خیالی ایجاد کنید. در طول نسخه ی نمایشی، با استفاده از ویژگی های مبتنی بر لبه، ظروف بصری غنی ایجاد خواهید کرد. علاوه بر این، تفاوت های ظریف در مورد مقادیر پیچیده تر، مانند سایه های متعدد و اینکه چگونه مرورگرهای مختلف می توانند ویژگی های خاص را به طور متفاوت پیاده سازی کنند را در نظر خواهید گرفت.

پیش نیازها

  • درک درستی از ویژگی‌های آبشار و ویژگی‌های CSS، که می‌توانید با خواندن نحوه اعمال سبک‌های CSS در HTML با Cascade و Specificity به آن دست پیدا کنید.
  • آشنایی با انتخابگرهای نوع، انتخابگرهای ترکیب‌کننده و گروه‌های انتخابگر، که می‌توانید در نحوه انتخاب عناصر HTML به سبک با CSS بیابید.
  • آشنایی با خواص رنگ در CSS برای اطلاعات بیشتر، نحوه استفاده از مقادیر رنگ با CSS را ببینید.
    آشنایی با گرادیان های CSS با ویژگی های پس زمینه. نحوه اعمال سبک‌های پس‌زمینه به عناصر HTML با CSS را بررسی کنید تا تجربه ایجاد پس‌زمینه گرادیان را به دست آورید.
  • یک فایل HTML خالی که در دستگاه محلی شما به عنوان index.html ذخیره شده است که می توانید از ویرایشگر متن و مرورگر وب انتخابی خود به آن دسترسی داشته باشید. برای شروع، آموزش نحوه تنظیم پروژه HTML خود را بررسی کنید و نحوه استفاده و درک عناصر HTML را برای دستورالعمل‌هایی در مورد نحوه مشاهده HTML خود در مرورگر خود دنبال کنید. اگر در HTML تازه کار هستید، کل نحوه ساخت یک وب سایت در سری HTML را امتحان کنید.

راه اندازی پایه HTML و CSS

در این بخش، پایه HTML را برای تمام سبک های بصری که در طول آموزش می نویسید، تنظیم می کنید. شما همچنین فایل styles.css خود را ایجاد کرده و سبک هایی را اضافه می کنید که طرح بندی محتوا را تنظیم می کند.

با باز کردن index.html در ویرایشگر متن خود شروع کنید. سپس HTML زیر را به فایل اضافه کنید:

index.html

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Travel Disclosure - Destination: Moon</title>
    <link href="styles.css" rel="stylesheet" />
  </head>
  <body>
  </body>
</html>

تنظیمات صفحه زیادی در عنصر <head> تعریف شده است. اولین عنصر <meta> مجموعه کاراکتری را برای استفاده از متن تعریف می کند. به این ترتیب اکثر کاراکترهای خاص، مانند علائم تاکیدی، بدون کدهای HTML خاص ارائه می شوند. عنصر دوم <meta> به مرورگرها و به ویژه مرورگرهای تلفن همراه می گوید که چگونه با عرض محتوا رفتار کنند. در غیر این صورت، مرورگر عرض دسکتاپ 960 پیکسلی را شبیه سازی می کند. عنصر <title> عنوان صفحه را در اختیار مرورگر قرار می دهد. عنصر <link> فایل CSS را بارگیری می کند که در آن استایل های خود را در طول این آموزش می نویسید.

صفحه همچنین برای استایل دادن به محتوا نیاز دارد. برای متن قانونی، شما از محتوای نمونه از Legal Ipsum به عنوان کپی پرکننده استفاده خواهید کرد که فقط برای اهداف طراحی در نظر گرفته شده است.

در ویرایشگر متن خود به index.html برگردید و HTML برجسته شده را از بلوک کد زیر اضافه کنید:

index.html

<!doctype html>
<html>
  ...
  <body>
    <section class="disclosure-alert">
      <header class="disclosure-header">
        <h2  class="disclosure-title"><em>Destination: Moon</em> Travel Disclosure</h2>
      </header>
      <div class="disclosure-content">
        <p>Although space travel is routine practice, there are many unknown possibilities that any traveller must be aware of before traveling with <em>Destination: Moon</em>. Agreeing to this disclosure of knowns is required prior to purchase of tickets with <em>Destination: Moon</em>. PLEASE, READ AND AGREE TO THE FOLLOWING DISCLOSURE OF TRAVEL UNKNOWNS BEFORE PROCEEDING TO PURCHASE.</p>
        <div class="legal-contents">
          <p>Effect of Termination. Upon termination, You agree not to use it under the terms of Sections 4(a) through 4(e) for that Covered Code, or any third party. Description of Modifications.<p>
          <p>You must make sure that you know you can do these things. To make sure the requirements of this Agreement. REQUIREMENTS A Contributor may participate in any way. Notwithstanding the foregoing, if applicable law or agreed to in writing, the Copyright Holder, but only to the terms applicable to Covered Code. Inability to Comply Due to Statute or Regulation.</p>
          <p>If it is impossible for You to the Recipient retains any such Additional Terms. Versions of This License. If you are re-using, b) a hyperlink (where possible) or URL to the terms of Sections 4(a) through 4(e) for that Work shall terminate if it fails to comply with the exception of content that is granting the License. License Terms 1.</p>
          <p>Grant of Patent Infringement. If you have knowledge of patent infringement litigation, then the only applicable Base Interpreter is a "commercial item" as defined in 48 C.F.R. Consistent with 48 C.F.R.</p>
          <p>U.S. Government End Users acquire Covered Code (Original Code and/or as part of a Larger Work; and b) allow the Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Distributor in writing of such Contributor, if any, to grant more extensive warranty protection to some or all of these conditions: (a) You must make it clear that any Modifications made by such Respondent, or (ii) withdraw Your litigation claim is resolved (such as Wikimedia-internal copying), it is Recipient's responsibility to secure any other exploitation. Program, and in any of the provisions set forth in Section 4(b), you shall terminate if it fails to comply with.</p>
          <p>Please note that these licenses do allow commercial uses of your company or organization, to others outside of this License Agreement), provided that You meet the following terms which differ from this License) and (b) You must duplicate the notice in Exhibit A in each changed file stating how and when you changed the files and the definitions are repeated for your past or future use of the Original Code; or 3) for infringements caused by: i) third party against the drafter will not be used as a handle): 1895.22/1011. This Agreement shall be held by the terms of this agreement. If any provision of this license which gives you legal permission to modify NetHack, or otherwise using this software in source and binary forms, with or without modification in printed materials or in related documentation, stating that you provide a service, including but not limited to the terms under which you distribute, wherever you describe the origin or ownership of such termination, the Recipient a non-exclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 1.6b1 or any part of Derivative Works. If You initiate litigation by asserting a patent infringement against You in that instance.</p>
          <p>Effect of New York and the like. While this license document the following disclaimer in the Work contain all the conditions listed in Clause 6 above, concerning changes from the Work. If you created a Modification, you may at your option offer warranty protection to some or all of the Licensed Program as a product of your Modifications available to others outside of this License.</p>
          <p>Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted to Licensor for inclusion in the documentation and/or other rights consistent with this program; if not, write to the modified files to carry prominent notices stating that You distribute, all copyright, patent, trademark, and attribution notices from the Public Domain or from the Original Code; 2) separate from the Public Domain or from the Work, you may distribute a Compiled Work on their system exactly as it is being maintained, then ask the Current Maintainer to update their communication data within one month. If the program is free software; you can change the License will not have to defend and indemnify every other Contributor to control, and cooperate with the Source Code version of the Licensed Program, or any Contributor.</p>
        </div>
        <div class="button-group">
          <a href="#" class="button button-primary">
            Agree
          </a>
          <a href="#" class="button button-secondary">
            Disagree
          </a>
        </div>
      </div>
    </section>
  </body>
</html>

تغییرات خود را در index.html ذخیره کنید و سپس مرورگر وب خود را باز کنید. آیتم منوی File را انتخاب کنید و سپس گزینه Open را انتخاب کنید و فایل index.html خود را در مرورگر بارگذاری کنید. تصویر زیر نحوه نمایش این HTML در مرورگر را نشان می دهد:

یک فایل جدید به نام styles.css در همان دایرکتوری index.html ایجاد کنید، سپس آن را در ویرایشگر متن خود باز کنید. این فایل شامل تمام سبک های استفاده شده در طول آموزش است. اولین مجموعه از سبک ها یک زیبایی شناسی کلی را اعمال می کند که شما از آن خواهید ساخت. CSS را از بلوک کد زیر در فایل styles.css خود اعمال کنید:

styles.css

html, body {
  height: 100%;
}

body {
  display: flex;
  margin: 0;
  font: 100% / 1.5 sans-serif;
  background: url("images/moon-bg.jpg") no-repeat fixed center / cover black;
}
.disclosure-alert {
  background-color: hsl(0, 0%, 95%);
  width: 85%;
  max-width: 48rem;
  margin: auto;
  color: hsl(0, 0%, 20%);
}
.disclosure-header {
  background: linear-gradient(hsl(300, 50%, 20%), hsl(300, 50%, 10%));
  padding: 2rem 0.5rem;
  text-align: center;
  color: hsl(300, 50%, 95%);
}
.disclosure-title {
  margin: 0;
  font-size: 2rem;
  line-height: 1.25;
}
.disclosure-content {
  margin: 1.5rem;
}
.legal-contents {
  margin-top: 1.5rem;
  background-color: white;
  padding: 0.75rem;
  font-family: "Times New Roman", serif;
}
.button-group {
  margin-top: 1.5rem;
  display: flex;
  justify-content: center;
}
.button {
  display: inline-block;
  text-align: center;
  padding: 0.5rem 1rem;
  background: black;
  text-decoration: none;
  color: white;
  width: 50%;
  max-width: 8rem;
}
.button + .button {
  margin-left: 1.5rem;
}
.button-primary {
  background: linear-gradient(to bottom, hsl(200, 100%, 30%), hsl(200, 100%, 20%));
}
.button-primary:hover {
  background: linear-gradient(to bottom, hsl(200, 100%, 25%), hsl(200, 100%, 15%));
}
.button-secondary {
  background: linear-gradient(to bottom, hsl(200, 10%, 30%), hsl(200, 10%, 20%));
}
.button-secondary:hover {
  background: linear-gradient(to bottom, hsl(200, 10%, 25%), hsl(200, 10%, 15%));
}

استایل موجود در این فایل، طرح‌بندی اولیه صفحه را با افشای قانونی متمرکز، دکمه‌هایی با فاصله و رندر با گرادیان خطی، و تصویری از ماه به‌عنوان پس‌زمینه تنظیم می‌کند. قبل از ادامه، حتما فایل styles.css را ذخیره کنید.

برای نمایش تصویر پیوند شده در ویژگی پس‌زمینه مجموعه قوانین بدن، به تصویر پس‌زمینه ماه نیاز دارید. ابتدا یک پوشه images در همان پوشه فایل index.html خود بسازید:

mkdir images

از مرورگر خود برای دانلود این فایل در فهرست تصاویر جدید خود استفاده کنید یا از دستور curl زیر برای دانلود آن از طریق خط فرمان استفاده کنید:

curl -sL https://assets.digitalocean.com/articles/68102/moon-bg.jpg -o images/moon-bg.jpg

در مرحله بعد، به مرورگر خود بازگردید و آن را به روز کنید. مرورگر اکنون رندر و استایل ها را در محتوای صفحه اعمال می کند. تصویر زیر نحوه نمایش کامل صفحه را نشان می دهد:

طول محتوا باعث ایجاد یک صفحه بسیار طولانی می شود. از آنجایی که این به عنوان کپی قانونی در نظر گرفته شده است، محتوای .legal-contents می تواند به فضایی قابل پیمایش تبدیل شود. این کار از طریق ترکیبی از ویژگی های ارتفاع، حداکثر ارتفاع و سرریز انجام می شود.

برای ایجاد یک ناحیه قابل پیمایش، styles.css را در ویرایشگر متن خود باز کنید. سپس ارتفاع محتوای قانونی را با کد زیر تنظیم کنید:

styles.css

...
.legal-contents {
  height: 50vh;
  max-height: 20rem;
  overflow: auto;
  margin-top: 1.5rem;
  background-color: white;
  padding: 0.75rem;
  font-family: "Times New Roman", serif;
}
...

در این کد، یک ویژگی height را در بلوک انتخابگر محتوای قانونی ایجاد کردید، سپس مقدار آن را روی 50vh تنظیم کردید، یعنی 50 درصد از ارتفاع پنجره viewport. شما همچنین یک ویژگی max-height ایجاد کردید که مقدار آن روی 20rem تنظیم شده است. در نهایت، یک ویژگی سرریز با مقدار خودکار اضافه کردید، که در صورت سرریز شدن محتوا از ظرف، نوار اسکرول ایجاد می‌کند.

این موارد اضافه شده را در فایل styles.css خود ذخیره کنید، سپس به مرورگر خود بازگردید و index.html را بازخوانی کنید. ارتفاع کامل صفحه و ظرف اصلی متراکم شده است. اکنون، همانطور که در انیمیشن زیر نشان داده شده است، کپی Legal Ipsum را می توان در داخل ظرف تعیین شده خود پیمایش کرد:

در سراسر این بخش، HTML اصلی را تنظیم می کنید که برای بقیه آموزش استفاده خواهید کرد. شما همچنین یک فضای قابل پیمایش را با ویژگی overflow تنظیم می کنید. در قسمت بعدی با خاصیت border برای اعمال حاشیه بر روی این کانتینرها کار خواهید کرد.

با استفاده از مرز Property

ویژگی border یکی از روش های اصلی اعمال سبک ها در لبه های عناصر است. یک خط به هر رنگی در محیط بیرونی ظرف اعمال می کند. ارزش ملک از سه جزء تشکیل شده است: ضخامت، سبک و رنگ. ویژگی border این مقادیر را برای هر چهار طرف یک عنصر اعمال می کند. می‌توانید تک تک طرف‌ها را با تغییرات جهت حاشیه مشخص کنید، مانند ویژگی border-top، که فقط برای بالای یک عنصر اعمال می‌شود.

برای شروع کار با ویژگی border، styles.css را در ویرایشگر متن خود باز کنید و به انتخابگر کلاس .disclosure-alert بروید. در بلوک انتخابگر، همانطور که در بلوک کد زیر مشخص شده است، یک ویژگی مرزی با مقدار 1px solid hsl (0، 0٪، 0%) اضافه کنید:

styles.css

...
.disclosure-alert {
  background-color: hsl(0, 0%, 95%);
  width: 85%;
  max-width: 48rem;
  margin: auto;
  color: hsl(0, 0%, 20%);
  border: 1px solid hsl(0, 0%, 0%);
}
...

این ویژگی مرزی یک ویژگی مختصر است، یعنی مقدار آن ترکیبی از مقادیر دیگر است. در این مورد، ضخامت 1px مقدار خاصیت عرض حاشیه را نشان می دهد. این مقدار می تواند هر مقدار عددی با یک واحد همراه با چند مقدار نامگذاری شده باشد: نازک، متوسط و ضخیم. در مرحله بعد، solid مقدار به سبک مرزی است که نحوه ظاهر شدن خط اطراف عنصر را مشخص می کند، در این مورد به عنوان یک خط پیوسته و پیوسته. سایر مقادیر برای سبک حاشیه عبارتند از: نقطه چین، چین، دوتایی و هیچ. مقدار نهایی خاصیت border-color را مشخص می کند که می تواند هر مقدار رنگ معتبری باشد.

تغییرات خود را در styles.css ذخیره کنید، سپس index.html را در یک مرورگر وب باز کنید. محفظه محتوای اصلی اکنون دارای یک حاشیه سیاه نازک در اطراف خود خواهد بود، که بیشتر مشهود است زیرا تصویر پس‌زمینه ماه را پوشانده است. تصویر زیر نحوه نمایان شدن حاشیه در قسمت محتوای اصلی را نشان می دهد:

 

در مرحله بعد، می‌توانید از ویژگی border برای ایجاد حس عمق با اعمال برجسته‌ها و سایه‌ها به یک عنصر استفاده کنید. می توانید این کار را با استفاده از یک حاشیه جهت دار در یک طرف که از رنگ پس زمینه روشن تر است و سپس یک رنگ تیره تر در سمت مجاور انجام دهید.

در ویرایشگر متن خود به styles.css برگردید، سپس به بلوک انتخابگر کلاس .disclosure-header بروید. خطی-gradient() در ویژگی پس زمینه یک گرادیان بنفش تیره را تعریف می کند که به یک سایه کمی تیره تر تبدیل می شود. برای ایجاد عمق بیشتر از گرادیان به تنهایی، حاشیه را با کد زیر تنظیم کنید:

 

styles.css

 
...
.disclosure-header {
  background: linear-gradient(hsl(300, 50%, 20%), hsl(300, 50%, 10%));
  padding: 2rem 0.5rem;
  text-align: center;
  color: hsl(300, 50%, 95%);
  border-top: 1px solid hsl(300, 50%, 35%);
  border-bottom: 1px solid hsl(300, 50%, 5%);
}
...
 

شما یک ویژگی border-top با مقدار 1px solid hsl (300، 50٪، 35%) اضافه کردید، که کمی سبکتر از مقدار گرادیان شروع است. سپس، یک ویژگی حاشیه-پایین را با مقدار 1px solid hsl (300، 50٪، 5%) ایجاد کردید، که کمی تیره تر از انتهای گرادیان است.

تغییرات خود را در styles.css ذخیره کنید، سپس به مرورگر بازگردید و index.html را بازخوانی کنید. پس‌زمینه هدر بنفش اکنون کمی برجسته از رنگ بنفش در بالای سرصفحه و سایه‌ای جزئی در امتداد پایین دارد. تصویر زیر نشان می دهد که چگونه در مرورگر ظاهر می شود:

از آنجایی که border یک ویژگی مختصر است، می توانید ویژگی های longhand اضافی اضافه کنید. یک حاشیه می تواند اعمال شود که عرض و سبک دو کلاس دکمه را مشخص می کند، در حالی که یک رنگ حاشیه می تواند روی کلاس های جداگانه اعمال شود.

برای شروع کار با border-color، styles.css را در ویرایشگر متن خود باز کنید. در بلوک انتخاب کننده برای دکمه، یک ویژگی حاشیه با مقدار 1px جامد اضافه کنید، سپس یک ویژگی border-color برای .button-primary و .button-secondary اضافه کنید:

styles.css

...
.button {
  ...
  border: 1px solid;
}
...
.button-primary {
  background: linear-gradient(to bottom, hsl(200, 100%, 30%), hsl(200, 100%, 20%));
  border-color: hsl(200, 100%, 15%);
}
.button-primary:hover {
  background: linear-gradient(to bottom, hsl(200, 100%, 25%), hsl(200, 100%, 15%));
  border-color: hsl(200, 100%, 10%);
}
.button-secondary {
  background: linear-gradient(to bottom, hsl(200, 10%, 30%), hsl(200, 10%, 20%));
  border-color: hsl(200, 10%, 15%);
}
.button-secondary:hover {
  background: linear-gradient(to bottom, hsl(200, 10%, 25%), hsl(200, 10%, 15%));
  border-color: hsl(200, 10%, 10%);
}

این یک حاشیه به سبک جامد با عرض 1 پیکسل برای هر دو دکمه تعریف می کند. سپس، یک ویژگی حاشیه رنگ برای سفارشی کردن رنگ‌ها برای انتخابگرهای حالت .button-primary، .button-secondary و مرتبط با آنها اضافه کردید.

این تغییرات را در styles.css ذخیره کنید، سپس صفحه را در مرورگر وب خود بازخوانی کنید. همانطور که در تصویر زیر نشان داده شده است، دکمه‌ها اکنون با یک حاشیه رنگ تیره‌تر منطبق، تعریف کمی دارند:

در نهایت، هر جهت مرزی نیز مختصری است. این به این معنی است که -width، -style و -color هر کدام می‌توانند برای یک ویژگی جهت اعمال شوند. برای مثال، ویژگی longhand border-right-color فقط یک رنگ را در حاشیه سمت راست اعمال می کند.

برای کار با این ویژگی های حاشیه longhand جهت دار، در ویرایشگر متن خود به styles.css بازگردید. به بلوک انتخابگر .legal-contents بروید و عرض و سبک را برای هر چهار طرف حاشیه تنظیم کنید، سپس رنگ‌های هر طرف را سفارشی کنید:

styles.css

...
.legal-contents {
  height: 50vh;
  max-height: 20rem;
  margin-top: 1.5rem;
  overflow: auto;
  background-color: white;
  border: 1px solid;
  border-top-color: hsl(0, 0%, 65%);
  border-bottom-color: hsl(0, 0%, 100%);
  border-right-color: hsl(0, 0%, 80%);
  border-left-color: hsl(0, 0%, 80%);
  padding: 0.75rem;
  font-family: "Times New Roman", serif;
}
...

در این کد، حاشیه: 1px جامد را به انتهای فایل اضافه کردید. پس از آن، ویژگی های حاشیه-بالا-رنگ، رنگ حاشیه-پایین، رنگ حاشیه-راست-رنگ و رنگ حاشیه-چپ را نیز ایجاد کردید. برای مقادیر، از مقادیر مختلف hsl() برای خاکستری استفاده کردید.

تغییرات خود را در styles.css ذخیره کنید، سپس صفحه را دوباره در مرورگر بارگیری کنید. ظرف محتوی قابل پیمایش اکنون دارای یک حاشیه خاکستری تیره در امتداد بالا، خاکستری کمی روشن تر در طرفین و یک حاشیه سفید در پایین است. این برای این است که این تصور را ایجاد کنیم که محتوا در پشت پس‌زمینه خاکستری روشن قرار می‌گیرد و باعث ایجاد یک اثر می‌شود که برجسته‌سازی در لبه پایینی است، همانطور که در تصویر زیر نشان داده شده است:

در این قسمت از ویژگی border و تغییرات طولانی آن استفاده کردید. شما چندین حاشیه ایجاد کردید که در صورت نیاز به طرف های مختلف اعمال شد. در بخش بعدی، با ویژگی border-radius کار خواهید کرد که اجازه می دهد گوشه های کانتینرها گرد شوند.

اعمال یکborder-radius

گوشه‌های گرد مدت‌ها قبل از اینکه ویژگی حاشیه‌ای برای انجام این کار وجود داشته باشد، یک طراحی زیبایی‌شناسی در وب بوده است. این ویژگی می‌تواند هر واحد عددی یا مقدار درصدی را بپذیرد و یک ویژگی کوتاه‌نویسی مانند خواص حاشیه یا padding است. این بدان معنی است که هر گوشه را می توان به صورت جداگانه در صورت نیاز تنظیم کرد.

برای شروع کار با ویژگی border-radius، styles.css را در ویرایشگر متن خود باز کنید. به بلوک انتخابگر .disclosure-alert و ویژگی border-radius بروید. سپس، مقدار را روی 1.5rem قرار دهید، که این مقدار را در هر چهار گوشه ویژگی اعمال می کند. CSS هایلایت شده در بلوک کد زیر نشان می دهد که چگونه این نوشته شده است:

styles.css

...
.disclosure-alert {
  ...
  border: 1px solid hsl(0, 0%, 0%);
  border-radius: 1.5rem;
}
...

این افزونه را در styles.css ذخیره کنید و سپس index.html را در یک مرورگر وب باز کنید یا به‌روزرسانی کنید. فقط دو گوشه پایینی گرد به نظر می رسد، در حالی که دو گوشه بالایی لبه های نوک تیز باقی می مانند. تصویر زیر نشان می دهد که چگونه این در مرورگر رندر می شود:

 

دلیل اینکه فقط دو گوشه گرد قابل مشاهده است به دلیل نحوه تعامل عناصر نزولی با یکدیگر در وب است. مرورگر در نمایان نگه داشتن محتوا اشتباه می کند. .disclosure-alert دارای چهار گوشه گرد است، اما از آنجایی که .disclosure-header داخل عنصر است و گوشه‌های گرد ندارد، بر گوشه‌های گرد همپوشانی دارد. یک راه حل سریع اضافه کردن سرریز: مخفی به .disclosure-alert است که باعث می‌شود کانتینر هر ظروف و محتوای نزولی را حذف کند. با این حال، این رویکرد می تواند منجر به ناخوانا یا نامرئی شدن محتوای ضروری شود. یک تمرین بهتر این است که یک شعاع مرزی برای کلاس .disclosure-header اعمال کنید تا با منحنی گوشه اجداد خود مطابقت داشته باشد.

برای تنظیم گوشه های همپوشانی، به styles.css در ویرایشگر متن خود بازگردید. به بلوک انتخابگر .disclosure-header بروید و ویژگی border-radius را اضافه کنید. از آنجایی که فقط دو گوشه بالا نیاز به تنظیم دارند، مقدار 1.5rem 1.5rem 0 0 خواهد بود:

styles.css

...
.disclosure-header {
  ...
  border-top: 1px solid hsl(300, 50%, 35%);
  border-bottom: 1px solid hsl(300, 50%, 5%);
  border-radius: 1.5rem 1.5rem 0 0;
}
...

فرمت توسعه‌یافته این مقدار یک منحنی 1.5 میلی‌متری را در گوشه‌های بالا-چپ و بالا-راست اعمال می‌کند.

تغییرات خود را در styles.css ذخیره کنید و index.html را در مرورگر بازخوانی کنید. هدر بنفش اکنون گوشه ای گرد دارد و ظرف اصلی را نمی پوشاند. یک مشکل جدید ظاهر شده است، همانطور که در تصویر بزرگنمایی شده زیر نشان داده شده است، زیرا یک برش سفید از ظرف اصلی از پشت سرصفحه بنفش به اوج می رسد:

گوشه های هر دو .disclosure-alert و .disclosure-header به اندازه 1.5rem هستند، اما عرض آنها تفاوت اندازه دارند. این تفاوت اندازه ناشی از حاشیه سمت چپ و راست عنصر .disclosure-alert است. از آنجایی که عرض حاشیه در هر دو طرف 1px است، تفاوت اندازه آن 2px یا 0.125rem است. برای مطابقت دادن منحنی ها، شعاع مرزی برای .disclosure-header باید 0.125 rem کوچکتر از آنچه در حال حاضر است باشد. همانطور که در بلوک کد زیر مشخص شده است، مقادیر حاشیه 1.5rem را به 1.375rem تغییر دهید:

styles.css

...
.disclosure-header {
  background: linear-gradient(hsl(300, 50%, 20%), hsl(300, 50%, 10%));
  padding: 2rem 0.5rem;
  text-align: center;
  color: hsl(300, 50%, 95%);
  border-top: 1px solid hsl(300, 50%, 35%);
  border-bottom: 1px solid hsl(300, 50%, 5%);
  border-radius: 1.375rem 1.375rem 0 0;
}
...

این تغییر را در styles.css ذخیره کنید و سپس صفحه را در مرورگر وب بازخوانی کنید. برش سفید اکنون از بین رفته است و منحنی های دو عنصر در مکان مناسب به هم می رسند. تصویر بزرگنمایی شده زیر نشان می‌دهد که این منحنی‌ها چگونه کنار هم قرار می‌گیرند:

در نهایت، یک گوشه گرد روی دکمه های پایین ظرف اصلی اعمال می کنید. این دکمه ها به شکل قرص، با بالا و پایین صاف و بلند و کناره های کاملا گرد خواهند بود. برای انجام این کار، مقدار شعاع مرزی باید یک مقدار مبتنی بر واحد بزرگتر از ارتفاع عنصر باشد.

برای ایجاد دکمه ای به شکل قرص، styles.css را در ویرایشگر متن خود باز کنید. در بلوک انتخابگر دکمه، ویژگی border-radius را اضافه کنید و سپس مقدار را روی 2rem قرار دهید. این عدد می‌تواند یک عدد دلخواه باشد تا زمانی که بزرگتر از ارتفاع محاسبه‌شده، ترکیبی از اندازه قلم، ارتفاع خط، لایه‌بندی و عرض حاشیه باشد که می‌تواند بر ارتفاع کلی یک عنصر تاثیر بگذارد. CSS هایلایت شده در بلوک کد زیر نشان می دهد که کجا باید این ویژگی را اضافه کرد:

styles.css

...
.button {
  ...
  border: 1px solid;
  border-radius: 2rem;
}
...

در مورد این رویکرد دو نکته قابل ذکر است. اولین مورد این است که مقدار ارتفاع روی این عنصر تنظیم نشده است. از تنظیم مقدار ارتفاع باید اجتناب شود زیرا محتوا می تواند و در موقعیتی قرار می گیرد که خارج از ظرف جریان داشته باشد. با اجتناب از تعیین ارتفاع، دکمه می تواند رشد کند تا با کل محتوا مطابقت داشته باشد. دوم این است که با یک مقدار مبتنی بر درصد به درستی کار نخواهد کرد. مقادیر مبتنی بر درصد در ویژگی شعاع حاشیه، درصدی از ارتفاع و عرض را منحنی می‌کنند و به جای گوشه‌ای گرد، شکلی بیضی ایجاد می‌کنند.

تغییرات خود را در styles.css ذخیره کنید، سپس به مرورگر بازگردید و index.html را بازخوانی کنید. این صفحه اکنون دو دکمه مستطیلی به شکل قرص را نمایش می دهد، همانطور که در تصویر زیر نشان داده شده است:

در سرتاسر این بخش، شما از ویژگی border-radius برای اعمال گوشه های گرد به چندین عنصر استفاده کردید، و متوجه شدید که یک border-radius مانع از خروج عناصر نزولی از فضای منحنی نمی شود. شما همچنین مقدار شعاع حاشیه را طوری تنظیم کردید که با عرض یک عنصر مطابقت داشته باشد، زمانی که چندین عنصر گرد روی هم قرار می گیرند. در بخش بعدی، از ویژگی text-shadow برای اعمال سایه های در حال پخش بر روی محتوای متن استفاده می کنید.

با استفاده از ویژگی text-shadow

اعمال سایه روی متن کاربردهای زیادی در توسعه روزمره وب دارد. سایه‌ها می‌توانند عمق، جلوه درخشش ایجاد کنند، یا در مکان‌هایی که ممکن است نادیده گرفته شوند، به برجسته‌تر شدن متن کمک کنند. در سرتاسر این بخش، text-shadow را به چندین عنصر برای ایجاد جلوه های بصری مختلف اعمال می کنید.

ویژگی text-shadow حداکثر از چهار مقدار تشکیل شده است: offset محور x، offset محور y، blur radius و color. به عنوان مثال، مقادیر می توانند به این شکل باشند: 2px 4px 10px قرمز. از این چهار مقدار، فقط مقادیر افست مورد نیاز است. رنگ سایه به طور پیش فرض رنگ متن است.

برای شروع کار با text-shadow، با ایجاد یک افکت درخشش در هدر شروع می‌کنید. styles.css را در ویرایشگر متن خود باز کنید و به انتخابگر کلاس .disclosure-header بروید. در بلوک انتخابگر، ویژگی text-shadow زیر را اضافه کنید:

styles.css

...
.disclosure-header {
  ...
  border-radius: 1.375rem 1.375rem 0 0;
  text-shadow: 0 0 0.375rem hsl(300, 50%, 50%);
}
...

جلوه درخشش به این معنی است که رنگ از هر لبه متن بیرون می‌آید، بنابراین مقادیر افست محور x و y در اینجا روی 0 تنظیم می‌شوند. شما تاری برای درخشش را روی 0.375 rem (معادل 6 پیکسل) تنظیم می‌کنید تا کمی ظریف باشد. هاله رنگ به متن در نهایت، مقدار رنگ کمی تیره تر از ویژگی رنگ تنظیم شد: hsl (300، 50٪، 50%).

این افزودنی را در فایل styles.css خود ذخیره کنید. بعد، index.html را در یک مرورگر وب باز کنید. متن عنوان پررنگ در پس‌زمینه گرادیان بنفش اکنون درخششی از بنفش میانی در اطراف خود دارد. تصویر زیر نحوه نمایش این افکت در مرورگر را نشان می دهد:

در مرحله بعد، چندین سایه را می توان روی عناصر متن قرار داد، که امکان ایجاد یک جلوه برجسته روی متن را فراهم می کند. این افکت با قرار دادن یک سایه با رنگ روشن تر در زیر جسم و یک سایه با رنگ تیره در بالا انجام می شود.

برای ایجاد یک جلوه برجسته، به styles.css در ویرایشگر متن خود بازگردید. افکت به دکمه های پایین ظرف اضافه می شود. برای انتخابگرهای .button-primary، .button-primary:hover، .button-secondary و .button-secondary:hover یک ویژگی text-shadow اضافه کنید. CSS هایلایت شده را در بلوک کد زیر برای مقادیر بررسی کنید:

styles.css

...
.button-primary {
  border: 1px solid hsl(200, 100%, 5%);
  background: linear-gradient(to bottom, hsl(200, 100%, 30%), hsl(200, 100%, 20%));
  text-shadow: 0 1px hsl(200, 100%, 50%),
               0 -1px hsl(200, 100%, 5%);
}
.button-primary:hover {
  border: 1px solid hsl(200, 100%, 0%);
  background: linear-gradient(to bottom, hsl(200, 100%, 25%), hsl(200, 100%, 15%));
  text-shadow: 0 1px hsl(200, 100%, 45%),
               0 -1px hsl(200, 100%, 0%);
}
.button-secondary {
  border: 1px solid hsl(200, 10%, 5%);
  background: linear-gradient(to bottom, hsl(200, 10%, 30%), hsl(200, 10%, 20%));
  text-shadow: 0 1px hsl(200, 10%, 50%),
               0 -1px hsl(200, 10%, 5%);
}
.button-secondary:hover {
  border: 1px solid hsl(200, 10%, 0%);
  background: linear-gradient(to bottom, hsl(200, 10%, 25%), hsl(200, 10%, 15%));
  text-shadow: 0 1px hsl(200, 10%, 45%),
               0 -1px hsl(200, 10%, 0%);
}

سایه اول یک برجسته روشن تر از پایین است. این کار با آفست 0 1px و سپس نسخه روشن‌تر رنگ‌های گرادیان پس‌زمینه انجام می‌شود. در مرحله بعد، سایه بالای متن را با آفست 0 -1 پیکسل ایجاد کردید، که سایه را 1 پیکسل به بالا می کشد و از تنوع تیره تری از رنگ های پس زمینه استفاده می کند.

این تغییرات را در styles.css ذخیره کنید، سپس صفحه را در مرورگر وب خود بازخوانی کنید. اکنون متن داخل دکمه‌ها دارای یک برجسته‌سازی جزئی در زیر متن و یک سایه کمی در بالای متن است. ترکیب این مقادیر متن-سایه افکت برجسته را همانطور که در تصویر زیر ارائه می شود ایجاد می کند:

در این بخش، ویژگی text-shadow را روی چند عنصر اعمال کردید. شما یک افکت درخشش روی هدر و یک جلوه برجسته با سایه های متعدد روی دکمه ها ایجاد کردید. در بخش بعدی، سایه هایی را با ویژگی box-shadow به عناصر HTML اعمال می کنید.

افزودن box-shadow به عناصر

همانطور که ویژگی text-shadow به محتوای متن اجازه می دهد سایه داشته باشد، ویژگی box-shadow نیز به عناصر و کانتینرها اجازه می دهد سایه داشته باشند. box-shadow دارای دو ویژگی اضافی است که در این بخش بررسی خواهید کرد، از جمله توانایی کنترل گسترش تاری و تنظیم سایه در داخل عنصر.

برای شروع کار با ویژگی box-shadow، styles.css را در ویرایشگر متن خود باز کنید. در بلوک انتخابگر .disclosure-alert، ویژگی box-shadow را اضافه کنید. درست مانند text-shadow، مقادیر افست محور x و y مورد نیاز است و اگر رنگی ارائه نشده باشد، از مقدار ویژگی رنگ استفاده می شود. برای اولین کادر سایه، offset ها را روی 0، blur را روی 0.5rem، و رنگ را روی یک hsl تیره (300، 40٪، 5%) تنظیم کنید، همانطور که در بلوک کد زیر مشخص شده است:

styles.css

...
.disclosure-alert {
  ...
  border-radius: 1.5rem;
  text-shadow: 0 0 0.375rem hsl(300, 50%, 50%);
  box-shadow: 0 0 0.5rem hsl(300, 40%, 5%);
}
...

تغییرات را در styles.css ذخیره کنید و صفحه را در مرورگر وب خود بازخوانی کنید. اکنون یک سایه سیاه تقریباً از ظرف پخش شده است. همچنین توجه داشته باشید که سایه به منحنی هایی که با ویژگی border-radius ایجاد کرده اید احترام گذاشته و از آنها پیروی می کند. تصویر زیر نشان می دهد که چگونه این در مرورگر ارائه می شود:

در مرحله بعد، به styles.css بازگردید و با افزودن دو افکت درخشش بزرگ اضافی به box-shadow شروع به ایجاد یک افکت پیچیده تر کنید. بین هر سایه جدید یک کاما اضافه کنید، و هر کدام را به گونه‌ای تنظیم کنید که آفست محور y 0.5rem باشد. سپس تاری های بزرگ را تنظیم کنید و از تغییرات کم رنگ آبی و بنفش از پالت رنگ استفاده کنید، همانطور که در بلوک کد زیر مشخص شده است:

styles.css

...
.disclosure-alert {
  ...
  box-shadow: 0 0 0.5rem hsl(300, 40%, 5%),
              0 0.5rem 6rem hsl(200, 40%, 30%),
              0 0.5rem 10rem hsl(300, 40%, 30%);
}
...

ترتیب این سایه ها مهم است. اولین سایه با رنگ تقریبا مشکی در بالای سایه های جدید ارائه می شود و هر سایه بعدی پشت سایه بعدی اضافه می شود.

تغییرات خود را در styles.css ذخیره کنید و صفحه را در مرورگر خود بازخوانی کنید. همانطور که در تصویر زیر نشان داده شده است، ترکیب سایه های متعدد جلوه ای منحصر به فرد را ارائه می دهد:

ویژگی گسترش تاری ویژگی box-shadow را می توان برای ایجاد احساس عمق استفاده کرد. ارزش اسپرد هر دو ارزش مثبت و منفی را می پذیرد. گسترش ارزش منفی همراه با یک افست قوی و تاری سایه ای ایجاد می کند که دور و دور از ظرف منبع ایجاد می کند.

برای شروع، به styles.css در ویرایشگر متن خود بازگردید. بین سایه کوچک تیره و سایه آبی بزرگتر در انتخابگر .disclosure-alert، CSS هایلایت شده زیر را از بلوک کد اضافه کنید:

styles.css

...
.disclosure-alert {
  ...
  box-shadow: 0 0 0.5rem hsl(300, 40%, 5%),
              0 6rem 4rem -2rem hsl(300, 40%, 5%),
              0 0.5rem 6rem hsl(200, 40%, 30%),
              0 0.5rem 10rem hsl(300, 40%, 30%);
}
...

این اضافه شدن به مجموعه سایه، افست محور x را روی 0 نگه می دارد، اما محور y را به طور قابل توجهی به 6rem می رساند. بعد، تاری به اندازه درخشش بزرگ نیست، اما در اندازه مناسب 4 rem است. سپس به مقدار گسترش blur می رسد که در این حالت روی -2rem تنظیم می شود. مقدار پیش فرض اسپرد 0 است که برابر با ظرف است. در -2rem، گسترش از ظرف به سمت داخل متراکم می شود تا جلوه بصری عمق ایجاد کند.

تغییرات خود را در styles.css ذخیره کنید، سپس index.html را در مرورگر بازخوانی کنید. سایه یک رنگ بنفش تیره است که این حس را ایجاد می کند که جعبه محتوای اصلی به خوبی بالای سطح ماه شناور است، همانطور که در تصویر زیر نشان داده شده است:

یکی دیگر از موارد استفاده از box-shadow ایجاد یک هایلایت و افکت مخروطی سایه است، همانطور که قبلاً با ویژگی border در هدر انجام دادید. مزیت استفاده از box-shadow به جای حاشیه این است که بر مدل جعبه تأثیر نمی گذارد، که باعث تغییر در جریان محتوا می شود. همچنین می توان از آن در ارتباط با حاشیه استفاده کرد. هنگام استفاده از این افکت با حاشیه، مقدار inset باید به box-shadow اضافه شود تا سایه در داخل ظرف باشد.

برای شروع استفاده از مقدار inset در box-shadow، styles.css را در ویرایشگر متن خود باز کنید. این افکت به دکمه‌ها اضافه می‌شود، بنابراین شما این استایل‌ها را در .button-primary، .button-primary:hover، .button-secondary و .button-secondary:hover اعمال خواهید کرد. مانند text-shadow، این شامل یک ترکیب افست 0 1px و 0 -1px خواهد بود. تفاوت این است که کلمه inset را می توان به ابتدا یا انتهای مقدار اضافه کرد، همانطور که در بلوک کد زیر مشخص شده است:

styles.css

...
.button-primary {
  ...
  text-shadow: 0 1px hsl(200, 100%, 50%),
               0 -1px hsl(200, 100%, 5%);
  box-shadow: inset 0 1px hsl(200, 100%, 50%),
              inset 0 -1px hsl(200, 100%, 15%);
}
.button-primary:hover {
  ...
  text-shadow: 0 1px hsl(200, 100%, 45%),
               0 -1px hsl(200, 100%, 0%);
  box-shadow: inset 0 1px hsl(200, 100%, 45%),
              inset 0 -1px hsl(200, 100%, 10%);
}
.button-secondary {
  ...
  text-shadow: 0 1px hsl(200, 10%, 50%),
               0 -1px hsl(200, 10%, 5%);
  box-shadow: inset 0 1px hsl(200, 10%, 50%),
              inset 0 -1px hsl(200, 10%, 15%);
}
.button-secondary:hover {
  ...
  text-shadow: 0 1px hsl(200, 10%, 45%),
               0 -1px hsl(200, 10%, 0%);
  box-shadow: inset 0 1px hsl(200, 10%, 45%),
              inset 0 -1px hsl(200, 10%, 10%);
}

این تغییرات را در styles.css ذخیره کنید و سپس index.html را در مرورگر خود refresh کنید. اکنون دکمه ها دارای یک برجسته و یک سایه هستند، شبیه به متن. این ترکیب با پس‌زمینه گرادیان، جلوه‌ای ساده و در عین حال متمایز برای دکمه‌ها ایجاد می‌کند. تصویر زیر نشان می دهد که چگونه این در مرورگر ارائه می شود:

 

در نهایت، شما همچنین می توانید یک مقدار گسترش تاری را به یک سایه داخلی اعمال کنید. اسپرد نقطه شروع تاری را از لبه به سمت بیرون حرکت می دهد، اما هنگام استفاده از اسپرد، نقطه شروع را به سمت داخل حرکت می دهد. این به این معنی است که وقتی یک مقدار منفی به گسترش روی یک ورودی اعمال می‌شود، سایه از ناحیه مشاهده عنصر منبسط می‌شود. گسترش بیرونی گسترش می تواند سایه ای ایجاد کند که شبیه یک گرادیان کوتاه است. این می تواند این توهم را ایجاد کند که یک عنصر در لبه ها گرد شده است زیرا سایه در زیر محتوای عنصر اعمال می شود.

برای شروع ایجاد این افکت، styles.css را در ویرایشگر متن خود باز کنید. به انتخابگر کلاس .legal-contents بروید و یک ویژگی box-shadow اضافه کنید. این سایه از سه سایه تشکیل خواهد شد. اولی یک سایه کوتاه در اطراف داخل کل ظرف ایجاد می کند و دو مورد بعدی یک سایه روشن دراز در بالا و پایین عنصر ایجاد می کند. CSS هایلایت شده در بلوک کد زیر نحوه تنظیم این را نشان می دهد:

styles.css

...
.legal-contents {
  ...
  font-family: "Times New Roman", serif;
  box-shadow: 0 0 0.25rem hsl(0, 0%, 80%) inset,
              0 4rem 2rem -4rem hsl(0, 0%, 85%) inset,
              0 -4rem 2rem -4rem hsl(0, 0%, 85%) inset;
}
...

تغییرات خود را در styles.css ذخیره کنید، سپس صفحه را در مرورگر بازخوانی کنید. اکنون سایه‌ها جلوه‌ای ایجاد می‌کنند که باعث می‌شود متن قانونی مانند پنجره‌ای به داخل ظرف ظاهر شود. سایه ها همچنین به تقویت رنگ های حاشیه ای که روی این عنصر اعمال شده اند کمک می کند. تصویر زیر نشان می دهد که چگونه این در مرورگر رندر می شود:

در این قسمت ویژگی box-shadow را عملی می کنید. شما همچنین از ویژگی‌های پخش تاری و درج کردن جعبه سایه استفاده کردید تا گزینه‌های یک ظاهر طراحی بیشتری داشته باشید. در بخش آخر، ویژگی outline را پیاده سازی می کنید، سپس از box-shadow برای ایجاد یک طرح کلی همه کاره تر استفاده می کنید.

با استفاده از ویژگی طرح کلی

آخرین ویژگی که بر لبه های عناصر تأثیر می گذارد، ویژگی outline است. در تمام مرورگرها، حالت :focus عناصر با استفاده از ویژگی outline ساخته می‌شود. با این حال، اجرای سبک :focus پیش فرض هر مرورگر به طور قابل توجهی متفاوت است. ویژگی outline شبیه به ویژگی border است، به جز دو تفاوت کلیدی: تغییرات خاصیت جهت دار را ندارد و مدل جعبه را تحت تأثیر قرار نمی دهد. آخرین مورد از این دو تفاوت، آن را برای سبک‌های فوکوس ایده‌آل می‌کند، زیرا نشانگر بصری عنصر فعال را بدون ایجاد اختلال در جریان محتوا ارائه می‌کند.

برای مشاهده پیش فرض مرورگر حالت :focus، index.html را در مرورگر خود باز کنید. از کلید TAB برای پیمایش در صفحه استفاده کنید تا زمانی که یکی از دکمه های پایین فوکوس شود. بسته به اینکه از چه مرورگری استفاده می کنید، ممکن است نتوانید سبک های پیش فرض :focus را ببینید. به عنوان مثال، فایرفاکس یک طرح کلی با نقطه سفید را نشان می دهد، اما در پس زمینه خاکستری روشن قابل درک نیست. تصویر زیر از چپ به راست نشان می دهد که چگونه سبک فوکوس پیش فرض در فایرفاکس، سافاری و کروم ظاهر می شود:

برای شروع سفارشی کردن حالت :focus خود با ویژگی outline، styles.css را در ویرایشگر متن خود باز کنید. به انتخابگر کلاس .button بروید و ویژگی outline را اضافه کنید:

styles.css

...
.button {
  ...
}
.button:focus {
  outline: 0.25rem solid hsl(200, 100%, 50%);
}
...

همانند ویژگی border، مقدار طرح کلی شامل یک مقدار عرض، سبک و رنگ است. از آنجایی که هدف یک حالت فوکوس جلب توجه به یک عنصر است، عرض به 0.25rem افزایش می یابد که معادل 4px است. در مرحله بعد، استایل را روی حالت جامد قرار می دهید تا حالت فوکوس بیشتر شبیه سافاری و کروم باشد. در نهایت، رنگ را با hsl (200، 100، 50%) روی آبی تیره قرار می دهید.

تغییرات خود را در styles.css ذخیره کنید، سپس به مرورگر خود بازگردید و صفحه را بازخوانی کنید. یک بار دیگر، مرورگر نحوه نمایش طرح کلی را تعیین می کند. تصویر زیر نشان می دهد که این سبک ها در فایرفاکس، سافاری و کروم از چپ به راست چگونه هستند:

در هر سه مرورگر، ویژگی outline کاملاً متفاوت نمایش داده می شود. فایرفاکس دور کل شکل گرد دکمه را محکم نگه می دارد. سافاری یک کادر با زاویه راست ایجاد می کند، اما لبه های دکمه را لمس می کند. کروم شبیه سافاری است، اما فضای اضافی بین دکمه و طرح کلی اضافه می کند.

برای ایجاد سبکی که در همه مرورگرها شبیه به فایرفاکس باشد، به جای طرح کلی، باید از box-shadow استفاده کنید.

برای شروع ایجاد حالت :focus سفارشی تر، به فایل styles.css خود در ویرایشگر متن خود بازگردید. اولین کاری که باید انجام دهید این است که سبک طرح کلی پیش فرض مرورگر را با تغییر مقدار .button:focus نمایه انتخابگر به none غیرفعال کنید، همانطور که در بلوک کد زیر مشخص شده است:

styles.css

...
.button {
  ...
}
.button:focus {
  outline: none;
}
...

سپس، به انتخابگرهای button-primary:hover و button-secondary:hover بروید و یک کاما به دنبال آن یک تغییر حالت :focus اضافه کنید، همانطور که در بلوک کد زیر مشخص شده است:

styles.css

...

.button-primary {
  ...
}
.button-primary:hover,
.button-primary:focus {
  ...
}
.button-secondary {
  ...
}
.button-secondary:hover,
.button-secondary:focus {
  ...
}

در نهایت، دو انتخابگر جدید برای هر دکمه ایجاد کنید: فوکوس، .button-primary: focus، و .button-secondary:focus. در داخل بلوک‌های انتخابگر جدید، یک ویژگی box-shadow جدید با همان سایه‌های داخلی از همتای :hover، :focus آن‌ها اضافه کنید. سپس، سایه دیگری را با offset ها به مجموعه اضافه کنید و همه را روی 0 تار کنید. پس از آن، یک اسپرد 0.25rem اضافه کنید، که یک خط ثابت و غیر تار در اطراف عنصر ایجاد می کند. در نهایت رنگ یکسان را به هر دو نمونه اضافه کنید. CSS هایلایت شده در بلوک کد زیر نشان می دهد که چگونه این نوشته شده است:

styles.css

...

.button-primary {
  ...
}
.button-primary:hover,
.button-primary:focus {
  ...
}
.button-primary:focus {
  box-shadow: inset 0 1px hsl(200, 100%, 45%),
              inset 0 -1px hsl(200, 100%, 10%),
              0 0 0 0.25rem hsl(200, 100%, 50%);
}
.button-secondary {
  ...
}
.button-secondary:hover,
.button-secondary:focus<^> {
  ...
}
.button-secondary:focus {
  box-shadow: inset 0 1px hsl(200, 10%, 45%),
              inset 0 -1px hsl(200, 10%, 10%),
              0 0 0 0.25rem hsl(200, 100%, 50%);
}

این تغییرات را در styles.css ذخیره کنید و برای بازخوانی index.html به مرورگر خود بازگردید. اکنون، همانطور که از کلید TAB برای پیمایش در صفحه استفاده می کنید. صرف نظر از مرورگر، سبک :focus روی دکمه ها اکنون یکسان به نظر می رسد. تصویر زیر نشان می دهد که چگونه نسخه box-shadow یک طرح کلی به همراه کل صفحه در مرورگر ظاهر می شود:

این بخش آخر شما را با ویژگی outline و نحوه استفاده هر مرورگر از آن به روش های مختلف آشنا کرد. حداقل، یک نشانگر :focus برای دسترسی مورد نیاز است و ویژگی outline کار را انجام می دهد. با گسترش این موضوع، شما همچنین با ایجاد یک جعبه سایه با ارزش گسترش زیاد، یک سبک فوکوس پیشرفته‌تر و سازگارتر از نظر بصری ایجاد کردید.

نتیجه

سبک دادن به لبه های عناصر به طراحی یک وب سایت اجازه می دهد تا تنوع و توجه را به خود جلب کند. ویژگی border می تواند به ارائه تعریف و تفکیک بین محتوا کمک کند. ویژگی حاشیه-شعاع زیبایی شناسی را نرم می کند و به تعریف نگرش طرح کمک می کند. سایه های روی متن و جعبه ها عمق می بخشد و به جلب توجه به محتوا کمک می کند. در نهایت، ویژگی outline راه‌های در دسترس را برای جلب توجه به عناصر با فوکوس صفحه کلید فراهم می‌کند. در این آموزش، شما از تمام این ویژگی ها برای ایجاد یک صفحه وب از نظر بصری جالب و قابل استفاده استفاده کردید. درک هر یک از این ویژگی ها و نحوه و زمان استفاده از آنها به حل انواع مشکلات رابط فرانت اند و ایجاد تجربیات جدید کمک می کند.

 

 

https://vpsgol.net/product/vps-germany/

 

https://vpsgol.net/product/vps-usa/

 

https://vpsgol.net/product/vps-france/

 

https://vpsgol.net/product/vps-canada/

 

https://vpsgol.net/product/vps-poland/

 

https://vpsgol.net/product/vps-netherlands/

 

https://vpsgol.net/product/vps-england/

 

برچسب‌ها:CSSVPS یا سرور مجازیآشنایی با خواص رنگ در CSSایجاد سرور مجازیایجاد یکborder-radiusخرید سرور مجازیراه اندازی پایه HTMLراه اندازی پایه HTML و CSSسرورمجازیسرورمجازی آمریکا

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه بازنشانی رمز عبور MySQL یا MariaDB Root در اوبونتو 20.04

ورود به سایت

معرفی

رمز عبور پایگاه داده خود را فراموش کرده اید؟ برای بهترین ما اتفاق می افتد. اگر رمز عبور اصلی پایگاه داده MySQL یا MariaDB خود را فراموش کرده یا گم کرده اید، اگر به سرور و یک حساب کاربری با امتیازات sudo دسترسی دارید، همچنان می توانید دسترسی داشته باشید و رمز عبور را بازنشانی کنید.

این آموزش نشان می دهد که چگونه رمز عبور ریشه برای پایگاه های داده MySQL و MariaDB نصب شده با مدیر بسته apt در اوبونتو 20.04 را بازنشانی کنید. روش تغییر رمز عبور ریشه بسته به اینکه MySQL یا MariaDB را نصب کرده باشید و پیکربندی سیستمی پیش‌فرض که با توزیع یا بسته‌های فروشندگان دیگر ارسال می‌شود، متفاوت است. در حالی که دستورالعمل‌های این آموزش ممکن است با سایر نسخه‌های سرور سیستم یا پایگاه داده کار کند، اما با Ubuntu 20.04 و بسته‌های عرضه‌شده توسط توزیع آزمایش شده‌اند.

پیش نیازها

برای بازیابی رمز عبور ریشه MySQL یا MariaDB، به موارد زیر نیاز دارید:

  • دسترسی به سرور اوبونتو 20.04 در حال اجرا MySQL یا MariaDB با کاربر sudo یا راه دیگری برای دسترسی به سرور با امتیازات ریشه.
  • برای اینکه روش های بازیابی را در این آموزش بدون تاثیر روی سرور تولید خود آزمایش کنید، یک سرور آزمایشی ایجاد کنید و سپس آموزش اولیه راه اندازی سرور ما را دنبال کنید. مطمئن شوید که یک کاربر معمولی و غیر ریشه با امتیازات sudo ایجاد کنید. سپس MySQL را طبق راهنمای ما در مورد نحوه نصب MySQL در اوبونتو 20.04 نصب کنید یا MariaDB را به دنبال نحوه نصب MariaDB در اوبونتو 20.04 نصب کنید.

مرحله 1 – شناسایی نسخه پایگاه داده و توقف سرور

اوبونتو 20.04 یا MySQL یا MariaDB را اجرا می‌کند—یک جایگزین محبوب که با MySQL سازگار است. بسته به اینکه کدام یک از آنها را نصب کرده اید، باید از دستورات مختلفی برای بازیابی رمز عبور root استفاده کنید، بنابراین مراحل این بخش را دنبال کنید تا مشخص کنید کدام سرور پایگاه داده را اجرا می کنید.

نسخه خود را با دستور زیر بررسی کنید:

mysql –version

اگر MariaDB را اجرا می کنید، “MariaDB” را با شماره نسخه در خروجی مشاهده خواهید کرد:

 

MariaDB output

mysql  Ver 15.1 Distrib 10.3.25-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2

اگر MySQL را اجرا می کنید، خروجی مانند زیر را خواهید دید:

 

MySQL output

mysql  Ver 8.0.22-0ubuntu0.20.04.3 for Linux on x86_64 ((Ubuntu))

به پایگاه داده ای که در حال اجرا هستید توجه کنید. این دستورات مناسب را برای دنبال کردن در ادامه این آموزش تعیین می کند.

برای تغییر رمز عبور ریشه، باید سرور پایگاه داده را خاموش کنید. اگر MariaDB را اجرا می کنید، می توانید این کار را با دستور زیر انجام دهید:

sudo systemctl stop mariadb

برای MySQL، سرور پایگاه داده را با اجرای زیر خاموش کنید:

sudo systemctl stop mysql

با توقف پایگاه داده، می توانید آن را در حالت ایمن راه اندازی مجدد کنید تا رمز عبور ریشه را بازنشانی کنید.

مرحله 2 – راه اندازی مجدد سرور پایگاه داده بدون بررسی مجوز

اجرای MySQL و MariaDB بدون بررسی مجوز امکان دسترسی به خط فرمان پایگاه داده با امتیازات root را بدون ارائه رمز عبور معتبر فراهم می کند. برای انجام این کار، باید پایگاه داده را از بارگیری جداول کمک هزینه، که اطلاعات امتیازات کاربر را ذخیره می کند، متوقف کنید. از آنجایی که این کمی یک خطر امنیتی است، ممکن است بخواهید شبکه را غیرفعال کنید تا از اتصال سایر کلاینت ها به سرور آسیب پذیر موقت جلوگیری کنید.

بسته به سرور پایگاه داده ای که نصب کرده اید، نحوه راه اندازی سرور بدون بارگیری جداول کمک هزینه متفاوت است.

پیکربندی MariaDB برای شروع بدون Grant Tables

برای راه‌اندازی سرور MariaDB بدون جداول کمک هزینه، از فایل unit systemd برای تنظیم پارامترهای اضافی برای سرور MariaDB استفاده می‌کنیم.

دستور زیر را اجرا کنید، که متغیر محیطی MYSQLD_OPTS مورد استفاده توسط MariaDB را هنگام راه اندازی تنظیم می کند. گزینه های –skip-grant-tables و –skip-networking به MariaDB می گویند که بدون بارگیری جداول کمک هزینه یا ویژگی های شبکه راه اندازی شود:

sudo systemctl set-environment MYSQLD_OPTS=”–skip-grant-tables –skip-networking”

سپس سرور MariaDB را راه اندازی کنید:

sudo systemctl start mariadb

این دستور هیچ خروجی تولید نمی کند، اما با در نظر گرفتن تنظیمات متغیر محیط جدید، سرور پایگاه داده را مجددا راه اندازی می کند.

می توانید مطمئن شوید که با sudo systemctl status mariadb شروع شده است.

اکنون باید بتوانید به عنوان کاربر ریشه MariaDB بدون ارائه رمز عبور به پایگاه داده متصل شوید:

sudo mysql -u root

بلافاصله یک درخواست پوسته پایگاه داده را خواهید دید

اکنون که به سرور پایگاه داده دسترسی دارید، می توانید رمز عبور root را همانطور که در مرحله 3 نشان داده شده است تغییر دهید.

پیکربندی MySQL برای شروع بدون Grant Tables

برای راه‌اندازی سرور MySQL بدون جداول کمکی آن، پیکربندی systemd را برای MySQL تغییر می‌دهید تا هنگام راه‌اندازی، پارامترهای اضافی خط فرمان را به سرور ارسال کنید.

برای این کار دستور زیر را اجرا کنید:

sudo systemctl edit mysql

این دستور یک فایل جدید را در ویرایشگر نانو باز می کند که از آن برای ویرایش سرویس های MySQL استفاده می کنید. اینها پارامترهای سرویس پیش فرض MySQL را تغییر می دهند.

این فایل خالی خواهد بود. مطالب زیر را اضافه کنید:

MySQL service overrides

[Service]
ExecStart=
ExecStart=/usr/sbin/mysqld --skip-grant-tables --skip-networking

اولین عبارت ExecStart مقدار پیش‌فرض را پاک می‌کند، در حالی که دستور دوم دستور راه‌اندازی جدید، از جمله پارامترهایی برای غیرفعال کردن بارگیری جداول اعطایی و قابلیت‌های شبکه را در اختیار systemd قرار می‌دهد.

CTRL-x را برای خروج از فایل فشار دهید، سپس Y را فشار دهید تا تغییراتی که ایجاد کرده اید ذخیره شود، سپس برای تایید نام فایل، ENTER را فشار دهید.

برای اعمال این تغییرات، پیکربندی systemd را دوباره بارگیری کنید:

sudo systemctl daemon-reload

اکنون سرور MySQL را راه اندازی کنید:

sudo systemctl start mysql

فرمان هیچ خروجی نشان نمی دهد، اما سرور پایگاه داده شروع به کار می کند. جداول کمک هزینه و شبکه فعال نخواهد شد.

به عنوان کاربر ریشه به پایگاه داده متصل شوید:

sudo mysql -u root

بلافاصله یک درخواست پوسته پایگاه داده را خواهید دید

اکنون که به سرور دسترسی دارید، می توانید رمز عبور root را تغییر دهید.

مرحله 3 – تغییر رمز عبور ریشه

سرور پایگاه داده اکنون در حالت محدود در حال اجرا است. جداول کمک هزینه بارگیری نمی شوند و هیچ پشتیبانی شبکه ای فعال نیست. این به شما امکان می دهد بدون ارائه رمز عبور به سرور دسترسی داشته باشید، اما شما را از اجرای دستوراتی که داده ها را تغییر می دهند منع می کند. برای بازنشانی رمز عبور ریشه، اکنون که به سرور دسترسی پیدا کرده اید، باید جداول کمک هزینه را بارگیری کنید.

با صدور دستور FLUSH PRIVILEGES به سرور پایگاه داده بگویید جداول کمک هزینه را دوباره بارگیری کند:

FLUSH PRIVILEGES;

اکنون می توانید رمز عبور root را تغییر دهید. روشی که استفاده می کنید بستگی به این دارد که آیا از MariaDB یا MySQL استفاده می کنید.

تغییر رمز عبور MariaDB

اگر از MariaDB استفاده می‌کنید، عبارت زیر را برای تنظیم رمز عبور برای حساب اصلی اجرا کنید، و مطمئن شوید که new_password را با یک رمز عبور قوی جدید جایگزین کنید که به خاطر بسپارید:

ALTER USER ‘root’@’localhost’ IDENTIFIED BY ‘new_password’;

این خروجی را خواهید دید که نشان می دهد رمز عبور تغییر کرده است:

 

Output

Query OK, 0 rows affected (0.001 sec)

MariaDB امکان استفاده از مکانیزم های احراز هویت سفارشی را فراهم می کند، بنابراین دو عبارت زیر را اجرا کنید تا مطمئن شوید که MariaDB از مکانیسم احراز هویت پیش فرض خود برای رمز عبور جدیدی که به حساب root اختصاص داده اید استفاده می کند:

UPDATE mysql.user SET authentication_string = ” WHERE user = ‘root’;
UPDATE mysql.user SET plugin = ” WHERE user = ‘root’;

خروجی زیر را برای هر عبارت خواهید دید:

 

Output

Query OK, 0 rows affected (0.01 sec)

رمز عبور اکنون تغییر کرده است. برای خروج از کنسول MariaDB عبارت exit را تایپ کنید و برای راه اندازی مجدد سرور پایگاه داده در حالت عادی به مرحله 4 بروید.

تغییر رمز عبور MySQL

برای MySQL، عبارت زیر را اجرا کنید تا رمز عبور کاربر اصلی را تغییر دهید، و new_password را با یک رمز عبور قوی که به خاطر بسپارید جایگزین کنید. MySQL امکان استفاده از مکانیسم‌های احراز هویت سفارشی را فراهم می‌کند، بنابراین عبارت زیر همچنین مطمئن می‌شود که MySQL از مکانیسم احراز هویت پیش‌فرض خود برای احراز هویت کاربر root با استفاده از رمز عبور جدید استفاده می‌کند:

ALTER USER ‘root’@’localhost’ IDENTIFIED WITH caching_sha2_password BY ‘new_password’;

این خروجی را مشاهده خواهید کرد که نشان می دهد رمز عبور با موفقیت تغییر کرده است:

 

Output

Query OK, 0 rows affected (0.01 sec)

رمز عبور اکنون تغییر کرده است. با تایپ exit از کنسول MySQL خارج شوید.

بیایید پایگاه داده را در حالت عملیاتی معمولی راه اندازی مجدد کنیم.

مرحله 4 – سرور پایگاه داده خود را به تنظیمات عادی برگردانید

برای راه اندازی مجدد سرور پایگاه داده در حالت عادی خود، باید تغییراتی را که ایجاد کرده اید برگردانید تا شبکه فعال شود و جداول کمک هزینه بارگذاری شوند. باز هم، روشی که استفاده می کنید بستگی به این دارد که آیا از MariaDB یا MySQL استفاده کرده اید.

برای MariaDB، متغیر محیطی MYSQLD_OPTS را که قبلا تنظیم کرده بودید، از حالت تنظیم خارج کنید:

sudo systemctl unset-environment MYSQLD_OPTS

سپس، سرویس را با استفاده از systemctl راه اندازی مجدد کنید:

sudo systemctl restart mariadb

برای MySQL، پیکربندی اصلاح شده systemd را حذف کنید:

sudo systemctl revert mysql

خروجی مشابه زیر را خواهید دید:

 

Output

Removed /etc/systemd/system/mysql.service.d/override.conf.
Removed /etc/systemd/system/mysql.service.d.

سپس، پیکربندی systemd را دوباره بارگیری کنید تا تغییرات اعمال شود:

sudo systemctl daemon-reload

در نهایت سرویس را مجددا راه اندازی کنید:

sudo systemctl restart mysql

اکنون پایگاه داده مجدداً راه اندازی شده و به حالت عادی خود بازگشته است. با ورود به عنوان کاربر اصلی با رمز عبور، تأیید کنید که رمز عبور جدید کار می کند:

mysql -u root -p

از شما یک رمز عبور خواسته می شود. رمز عبور جدید خود را وارد کنید و همانطور که انتظار می رود به اعلان پایگاه داده دسترسی پیدا خواهید کرد.

نتیجه

شما دسترسی مدیریتی به سرور MySQL یا MariaDB را بازیابی کرده اید. مطمئن شوید رمز عبور جدیدی که انتخاب کرده اید قوی و ایمن است و آن را در مکانی امن نگه دارید.

 

 

https://vpsgol.net/product/vps-germany/

 

https://vpsgol.net/product/vps-usa/

 

https://vpsgol.net/product/vps-france/

 

https://vpsgol.net/product/vps-canada/

 

https://vpsgol.net/product/vps-poland/

 

https://vpsgol.net/product/vps-netherlands/

 

https://vpsgol.net/product/vps-england/

 

MySQLاوبونتو 20.04بازیابی رمز عبور MariaDBپایگاه داده MySQLپیکربندی MariaDBخرید سرورخرید سرور لینوکسراه اندازی مجدد سرورراه‌اندازی سرور MySQLسرور مجازیفراموش کردن رمز پایگاه دادهنحوه بازنشانی رمز عبور MySQL

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه استفاده از Opacity و Transparency برای ایجاد یک Modal در CSS

ورود به سایت

معرفی

هنگام استایل‌سازی HTML با CSS، راه‌های متعددی برای تنظیم شفافیت عناصر و دلایل متعددی برای استفاده از این افکت در طراحی وجود دارد. کدورت می‌تواند به نرم کردن سایه، کاهش تاکید بر محتوای غیر ضروری در طول یک کار خاص، یا محو کردن محتوا در داخل یا خارج از دید کمک کند. شما می‌توانید این افکت‌ها را با ویژگی opacity، نام رنگ شفاف یا کانال‌های آلفا، که بسط مقادیر رنگ با یک بخش اضافی برای کنترل کدورت هستند، انجام دهید.

در طول این آموزش، شما از روش‌های مختلفی برای اعمال کدورت و خواص اضافی برای انجام مؤثر جلوه‌های خاص استفاده خواهید کرد. شما یک مودال ایجاد خواهید کرد که با رویکرد بدون جاوا اسکریپت با استفاده از کلاس شبه :target و ویژگی های opacity، pointer-events و transition ظاهر می شود. سپس از هر یک از مقادیر رنگ کانال آلفا برای ایجاد همپوشانی سایه، حاشیه و محتوا استفاده خواهید کرد. شما همچنین از مقدار رنگ شفاف برای کمک به ایجاد شیب متحرک رنگ ها در یک رویداد :hover استفاده خواهید کرد.

پیش نیازها

  • درک درستی از ویژگی‌های آبشار و ویژگی‌های CSS، که می‌توانید با خواندن نحوه اعمال سبک‌های CSS در HTML با Cascade و Specificity به آن دست پیدا کنید.
  • آشنایی با انتخابگرهای نوع، انتخابگرهای ترکیب‌کننده و گروه‌های انتخابگر، که می‌توانید در نحوه انتخاب عناصر HTML به سبک با CSS بیابید.
  • درک خواص رنگ .
  • آشنایی با گرادیان های CSS با ویژگی های پس زمینه. نحوه اعمال سبک‌های پس‌زمینه به عناصر HTML با CSS را بررسی کنید تا تجربه ایجاد پس‌زمینه گرادیان را به دست آورید.
  • ویژگی box-shadow را تجربه کنید،
  • یک فایل HTML خالی که در دستگاه محلی شما به عنوان index.html ذخیره شده است که می توانید از ویرایشگر متن و مرورگر وب انتخابی خود به آن دسترسی داشته باشید. برای شروع، آموزش نحوه تنظیم پروژه HTML خود را بررسی کنید و نحوه استفاده و درک عناصر HTML را برای دستورالعمل‌هایی در مورد نحوه مشاهده HTML خود در مرورگر خود دنبال کنید. اگر در HTML تازه کار هستید، کل نحوه ساخت یک وب سایت در سری HTML را امتحان کنید.

راه اندازی پایه HTML و CSS

در این بخش اول، HTML را برای سبک های بصری که در طول آموزش خواهید نوشت، تنظیم خواهید کرد. شما همچنین فایل styles.css خود را ایجاد کرده و سبک هایی را اضافه می کنید که طرح بندی محتوا را تنظیم می کند.

برای شروع، فایل index.html را در ویرایشگر متن خود باز کنید. سپس HTML زیر را به فایل اضافه کنید:

index.html

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Destination: Moon</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=MuseoModerno:wght@400;700&display=swap" rel="stylesheet">
    <link href="styles.css" rel="stylesheet" />
  </head>
  <body>
  </body>
</html>

چندین تنظیمات صفحه در عنصر <head> HTML تعریف شده است. عنصر <meta> مجموعه کاراکتری را برای استفاده از متن تعریف می‌کند، که به مرورگر می‌گوید چگونه کاراکترهای خاص را بدون استفاده از کدهای کاراکتر HTML تفسیر کند. عنصر <title> عنوان صفحه را در اختیار مرورگر قرار می دهد. عناصر <link> در سبک های صفحه بارگیری می شوند. سه مورد اول در فونت، Museo Moderno، از فونت‌های Google بارگیری می‌شوند، و آخرین مورد، سبک‌هایی را که به styles.css اضافه می‌کنید، بارگیری می‌کند.

در مرحله بعد، صفحه برای استایل دادن به محتوا نیاز دارد. شما از محتوای نمونه از Sagan Ipsum به عنوان کپی پرکننده برای استفاده با سبک ها استفاده خواهید کرد. شما همچنین HTML را برای سرصفحه سایت، حاوی نام سایت و یک نوار ناوبری کوچک اعمال خواهید کرد. در ویرایشگر متن خود به index.html برگردید و HTML برجسته شده را از بلوک کد زیر اضافه کنید:

index.html

<!doctype html>
<html>
  <head>
    ...
  </head>
  <body>
    <header class="site-header">
      <h1 class="site-name">Destination: <strong>Moon</strong></h1>
      <nav>
        <ul class="nav-list">
          <li><a href="#" class="nav-link">Base Station</a></li>
          <li><a href="#" class="nav-link">Travel Packages</a></li>
          <li><a href="#" class="nav-link">Accommodations</a></li>
          <li><a href="#" class="nav-link">Plan Your Trip</a></li>
      </ul>
      </nav>
    </header>
    <main>
      <section>
        <h2>Schedule Your Trip</h2>
        <p>Sea of Tranquility great turbulent clouds with pretty stories for which there's little good evidence extraordinary claims require extraordinary evidence. Citizens of distant epochs rings of Uranus intelligent beings birth take root and flourish across the centuries. Corpus callosum invent the universe as a patch of light the only home we've ever known a mote of dust suspended in a sunbeam made in the interiors of collapsing stars. Kindling the energy hidden in matter Orion's sword.</p>
        <p>Vastness is bearable only through love emerged into consciousness not a sunrise but a galaxyrise emerged into consciousness courage of our questions across the centuries and billions upon billions upon billions upon billions upon billions upon billions upon billions.</p>
          <a href="#" class="button">Read the Disclaimer!</a>
      </section>
    </main>
  </body>
</html>

حتما فایل index.html خود را ذخیره کنید و آن را در ویرایشگر متن خود باز بگذارید. سپس یک فایل جدید به نام styles.css ایجاد کنید و آن را در ویرایشگر متن باز کنید. این فایلی است که در عنصر <head> index.html ارجاع داده شده است. در فایل styles.css کد زیر را اضافه کنید:

styles.css

body {
  margin: 0;
  font: 100%/1.5 sans-serif;
}

main {
  margin: 6rem auto;
  width: 75ch;
  font-size: 1.125rem;
}

h2 {
  font: 400 1.875rem/1.25 MuseoModerno, sans-serif;
  color: #6b2d6b;
}

.site-header {
  font: 1.125rem / 1.25 MuseoModerno, sans-serif;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 2rem;
  color: white;
  background: linear-gradient(135deg, #8e3d8e, #230f23);
}

.site-name {
  margin: 0;
  font-size: 1.75rem;
  font-weight: 400;
}

.nav-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  align-items: stretch;
}

.nav-link {
  color: inherit;
  display: block;
  text-decoration: none;
  padding: 1.25rem 1.5rem;
}

.nav-link:hover,
.nav-link:focus {
  color: #230f23;
  background-color: white;
}

.button {
  text-decoration: none;
  display: inline-block;
  padding: 0.5rem 1.25rem;
  color: white;
  background: #4c90b2;
  border: 1px solid #2d566b;
  border-radius: 0.5rem;
}

.button:hover,
.button:focus {
  background-color: #2d566b;
}

این سبک‌ها زیبایی‌شناسی و چیدمان کلی صفحه را با سبک‌های اعمال شده روی بدنه و عناصر اصلی تنظیم می‌کنند. انتخابگرهای .site-header، site-name، .nav-list و .nav-link همگی سبک ها را در سرصفحه صفحه تعریف می کنند. قوانین .button و .button:hover یک عنصر <a> را تغییر می دهند تا مانند یک دکمه بزرگ و قابل کلیک ظاهر شود.

تغییرات خود را در styles.css ذخیره کنید، سپس یک مرورگر وب باز کنید. آیتم منوی File را انتخاب کرده و سپس گزینه Open را انتخاب کنید. سپس به پوشه پروژه خود بروید و فایل index.html خود را در مرورگر بارگذاری کنید. تصویر زیر نحوه نمایش صفحه در مرورگر را نشان می دهد:

CSS که تا به حال نوشته اید یک هدر بنفش در بالای صفحه با عنوان سایت و پیمایش در متن سفید ایجاد می کند. در زیر، محتوا از یک عنوان بنفش و دو پاراگراف متن تشکیل شده است. عرض محتوا به 75 کاراکتر با مقدار ویژگی max-width: 76ch در انتخابگر عنصر اصلی محدود شده است. در نهایت، دکمه آبی با متن Read the Disclaimer! یک عنصر بزرگ و تعاملی در زیر محتوا است.

در سراسر این بخش شما HTML خود را در فایل index.html تنظیم کرده و سبک های پایه را در فایل styles.css ایجاد می کنید. در بخش بعدی، از ویژگی opacity برای ناپدید شدن یک عنصر جدید و ظاهر شدن مجدد با کلاس :target شبه استفاده خواهید کرد.

ایجاد :target State با opacity برای نمایش و پنهان کردن عناصر

یکی از کاربردهای مفید ویژگی opacity این است که باعث محو شدن و محو شدن محتوا در صفحه می شود. یکی از نمونه‌های چنین جلوه‌ای زمانی است که یک مودال، یک عنصر رابط کاربری (که به عنوان جعبه نور نیز شناخته می‌شود) که در جلوی بقیه محتوای صفحه شما ظاهر می‌شود، به نمایش تبدیل می‌شود. می توانید این افکت را با ترکیبی از ویژگی های opacity و pointer-events و شبه کلاس :target ایجاد کنید.

با باز کردن index.html برای ایجاد محتویات مدال شروع کنید. HTML برجسته شده را از بلوک کد زیر بین تگ های بسته </section> و </main> اضافه کنید:

index.html

<!doctype html>
<html>
  <head>
    ...
  </head>
  <body>
    ...
    <main>
      <section>
        ...
      </section>
      <div class="modal-container">
        <section class="modal">
          <header class="modal-header">
            <h2 class="modal-title">Destination: Moon Disclaimer</h2>
            <a href="#" class="modal-close">Close</a>
          </header>
          <div class="modal-content">
            <p><strong>Disclaimer:</strong> Vastness is bearable only through love emerged into consciousness not a sunrise but a galaxyrise emerged into consciousness courage of our questions across the centuries and billions upon billions upon billions upon billions upon billions upon billions upon billions.</p>
          </div>
        </section>
      </div>
    </main>
  </body>
</html>

تغییرات خود را در index.html ذخیره کنید، سپس به styles.css در ویرایشگر متن خود بازگردید و CSS هایلایت شده را در بلوک کد زیر به فایل خود اضافه کنید:

styles.css

...

.button:hover {
  background-color: #2d566b;
}

.modal-container {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1000;
  background-color: black;
  display: flex;
}

.modal {
  margin: auto;
  width: 90%;
  max-width: 40rem;
  background-color: white;
  border-radius: 1.5rem;
}

.modal-header,
.modal-content {
  padding: 1.5rem;
}

کلاس .modal-container ناحیه ای را تعریف می کند که فضای کامل قابل مشاهده را با یک عنصر ثابت پوشش می دهد. سپس صفحه نمایش: خم شدن در کانتینر .modal همراه با حاشیه: خودکار در انتخابگر .modal، محتوا را به صورت عمودی و افقی روی صفحه متمرکز می کند.

تغییرات خود را در styles.css ذخیره کنید و برای بازخوانی index.html به مرورگر خود بازگردید. همانطور که در تصویر زیر نشان داده شده است، محتوای صفحه دیگر قابل مشاهده نیست زیرا یک پوشش سیاه روی صفحه با یک ظرف سفید پوشانده شده است:

اکنون که مدال در جای خود قرار دارد و محتویات صفحه را پوشش می‌دهد، باید تا زمانی که نمونه‌سازی شود، پنهان شود. ویژگی opacity یک ویژگی قدیمی است که اجازه می دهد تا شفافیت روی یک عنصر و محتویات آن قرار گیرد. مقدار ویژگی opacity می تواند از 0 تا 1 با هر نقطه اعشاری بین آن متغیر باشد.

برای شروع استفاده از ویژگی opacity، به styles.css در ویرایشگر متن خود بازگردید. در انتخابگر کلاس .modal، یک ویژگی opacity با مقدار 0 اضافه کنید، همانطور که در بلوک کد زیر مشخص شده است:

styles.css

...
.modal-container {
   position: fixed;
   top: 0;
   right: 0;
   bottom: 0;
   left: 0;
   z-index: 1000;
   background-color: black;
   display: flex;
  opacity: 0;
}
...

این باعث می شود که کل نمای مودال به صورت بصری روی صفحه پنهان شود. مودال فقط باید زمانی قابل مشاهده باشد که لازم باشد. برای دستیابی به این ظاهر شرطی، می توانید از شبه کلاس :target استفاده کنید.

بعد از انتخابگر .modal-container، یک انتخابگر جدید برای .modal-container:target اضافه کنید. در داخل بلوک انتخابگر، یکی دیگر از ویژگی های opacity را به مقدار 1 تنظیم کنید. CSS برجسته شده در بلوک کد زیر، نحوه قالب بندی آن را نشان می دهد:

styles.css

...
.modal-container {
  ...
  opacity: 0;
}

.modal-container:target {
  opacity: 1;
}
...

این تغییرات را در styles.css ذخیره کنید.

:target زمانی که یک عنصر دارای تمرکز URL باشد، نمونه سازی می شود. در مرورگرهای وب، ویژگی id در یک عنصر HTML را می توان در URL همانطور که با نماد پوند یا هش (#) نشان می دهد ارجاع داد. برای اینکه .modal-container:target فعال شود، همان عنصر به یک عنصر id نیاز دارد و صفحه به راهی برای فعال کردن آن URL نیاز دارد.

در ویرایشگر متن خود به index.html برگردید. در عنصر <div class=”modal-container”>، یک مجموعه ویژگی id را به سلب مسئولیت مقدار اضافه کنید. سپس، در عنصر <a href=”#” class=”button”>، مقدار href را از # به #سلب مسئولیت تغییر دهید. برای نحوه نوشتن به HTML برجسته شده در بلوک کد زیر مراجعه کنید:

index.html

<!doctype html>
<html>
  <head>
    ...
  </head>
  <body>
    ...
    <main>
      <section>
         ...
         <a href="#disclaimer" class="button">Read the Disclaimer!</a>
       </section>
       <div id="disclaimer" class="modal-container">
         ...
       </div>
    </main>
  </body>
</html>

تغییر در مقدار href به مرورگر می‌گوید که به عنصری با مقدار شناسه سلب مسئولیت صفحه فعلی برود. هنگامی که #سلب مسئولیت به URL اضافه شد، سپس :target در CSS فعال می شود.

این تغییرات را در index.html ذخیره کنید، سپس به styles.css بازگردید.

همانطور که صفحه اکنون ساختار یافته است، مودال تمام رویدادهای کلیک و لمسی را که از تعامل ماوس یا صفحه لمسی حاصل می شود، ضبط می کند. این به این دلیل است که اگرچه کاملاً شفاف است، اما عنصر مدال هنوز کل صفحه را پوشش می دهد. برای حذف تعامل از عنصر، یک ویژگی pointer-events با مقدار هیچ به انتخابگر .modal-container اضافه می‌کنید. سپس، هنگامی که مدال قابل مشاهده است، باید بتواند دوباره رویدادهای تعامل را دریافت کند. در شبه کلاس :target، اشاره گر رویدادها را به همه اضافه کنید، همانطور که در بلوک کد زیر مشخص شده است:

styles.css

...
.modal-container {
  ...
  opacity: 0;
  pointer-events: none;
}

.modal-container:target {
  opacity: 1;
  pointer-events: all;
}
...

ویژگی pointer-events نحوه تعامل یک عنصر با ماوس یا دستگاه ورودی مبتنی بر لمس را تغییر می دهد. با تنظیم مقدار روی هیچ، این عنصر نه تنها برای کاربران بینا، بلکه برای دستگاه های ورودی مبتنی بر اشاره گر نیز نامرئی می شود. سپس، مقدار all تعامل را دوباره برقرار می‌کند، اما تنها زمانی که .modal-container در URL فعال و قابل مشاهده باشد.

در نهایت، برای اینکه مدال در داخل و خارج از دید محو شود، یک ویژگی انتقال برای متحرک سازی بین 0 و 1 مقادیر برای کدورت اضافه می‌کنید.

به styles.css برگردید و یک ویژگی انتقال به انتخابگر .modal-container اضافه کنید، همانطور که در بلوک کد زیر مشخص شده است:

styles.css

...
.modal-container {
  ...
  opacity: 0;
  pointer-events: none;
  transition: opacity 250ms ease;
}

.modal-container:target {
  opacity: 1;
  pointer-events: all;
}
...

ویژگی transition مختصر یک سری از خواص است. کدورت به مرورگر می گوید که این ویژگی برای انتقال بین است. 250 میلی‌ثانیه زمانی است که انتقال باید تکمیل شود و واحد برای میلی‌ثانیه ایستاده است. در نهایت، سهولت توضیح می دهد که چگونه انتقال رخ خواهد داد. در این مورد، ease به این معنی است که آهسته شروع می‌شود، سرعت می‌گیرد و سپس در نزدیکی پایان انتقال دوباره کاهش می‌یابد.

انتقال زمانی کار خواهد کرد که مودال ظاهر شود و با فشار دادن پیوند بستن در داخل مدال ناپدید شود. این پیوند بستن دارای یک مقدار href است که روی # تنظیم شده است، که URL را از #سلب مسئولیت به # تغییر می‌دهد و حالت :target را حذف می‌کند.

تغییرات خود را در styles.css ذخیره کنید و index.html را در مرورگر refresh کنید. انیمیشن زیر نحوه ظاهر و ناپدید شدن مودال را نشان می دهد

این بخش شما را با خاصیت opacity آشنا کرد که از آن برای پنهان کردن بصری یک ظرف مدال استفاده کردید. شما همچنین از ویژگی شبه کلاس :target، ویژگی pointer-events و ویژگی transition برای ایجاد یک افکت fade-in و fade-out استفاده کردید. در بخش بعدی، از رنگ‌هایی با کانال‌های آلفا برای شفاف‌تر کردن مودال استفاده خواهید کرد.

استفاده از کانال های آلفا برای ایجاد مقادیر رنگ شفاف

یک کانال آلفا مانند ویژگی opacity است، اما در عوض یک بخش اضافی برای یک مقدار رنگ است که از طریق rgb()، hsl() یا هگزادسیمال تعریف شده است. در جایی که ویژگی opacity کل عنصر و فرزندان آن را تنظیم می کند، کانال آلفا فقط کدورت رنگ را در یک ویژگی مشخص تنظیم می کند. در طول این بخش، شما از هر یک از مقادیر رنگ کانال آلفا استفاده کرده و آنها را عملی خواهید کرد.

برای شروع کار با مقادیر رنگ کانال آلفا، stlyes.css را در ویرایشگر متن خود باز کنید. سپس به انتخابگر کلاس .modal-container بروید. همانطور که در بلوک کد زیر مشخص شده است، مقدار ویژگی پس زمینه رنگ را از #000 به rgba (0، 0، 0، 0.75) تغییر دهید:

styles.css

...
.modal-container {
  ...
  background-color: rgba(0,0,0,0.75);
  ...
}
...

مقدار رنگ rgba () مانند rgb () عمل می کند که شامل سه عدد جدا شده با کاما است که سطح نور قرمز، سبز و آبی را نشان می دهد. وقتی یکی از مقادیر رنگ روی 0 تنظیم شود، کاملاً خاموش است (سیاه) و 255 به این معنی است که در روشنایی کامل (سفید) است. بین این سه کانال رنگی می توان میلیون ها رنگ تولید کرد. عدد چهارم کانال آلفا است که مانند خاصیت opacity کار می کند و یک مقدار اعشاری از 0 تا 1 است. تنظیم کانال آلفا باعث شفاف شدن رنگ می شود و به محتوای پشت آن اجازه می دهد از طریق رنگ قابل مشاهده باشد.

تغییرات خود را در styles.css ذخیره کنید و index.html را در یک مرورگر وب باز کنید. خواندن سلب مسئولیت را فشار دهید! را فشار دهید تا مودال فعال شود. پس‌زمینه پوشش سیاه همچنان سیاه است، اما اکنون نیز شفاف است و صفحه پشت آن را آشکار می‌کند:

اکنون که روکش شفاف است، به مدال بچرخید و با تغییر پس‌زمینه به یک گرادیان بنفش با متن سفید، استایل بصری بیشتری به آن بدهید. در ویرایشگر متن خود به styles.css برگردید و CSS هایلایت شده زیر را از بلوک کد بعدی اضافه کنید:

styles.css

...
.modal {
  margin: auto;
  width: 90%;
  max-width: 40rem;
  background: linear-gradient(135deg, hsl(300, 40%, 20%),hsl(300, 40%, 5%));
  border-radius: 1.5rem;
}

.modal-header,
.modal-content {
  padding: 1.5rem;
}

.modal-header {
  display: flex;
  justify-content: space-between;
}

.modal-title {
  margin: 0;
  color: white;
}

.modal-close {
  color: white;
}

.modal-content {
  color: white;
}

این به روز رسانی را در styles.css ذخیره کنید، سپس index.html را در مرورگر خود بازخوانی کنید. سبک مودال همانطور که در تصویر زیر نشان داده شده است به روز می شود و ارائه می شود:

اکنون در ویرایشگر متن خود به styles.css بازگردید. اکنون از مقدار رنگ ()hsla برای روشن کردن رنگ هدر modal استفاده خواهید کرد. همچنین باید گوشه های بالایی را طوری تنظیم کنید که یک مقدار شعاع مرزی مطابق با مدال داشته باشد، بنابراین هدر خارج از ناحیه مدال ظاهر نشود. CSS هایلایت شده در بلوک کد زیر نحوه تنظیم این را نشان می دهد:

styles.css

...
.modal-header {
  display: flex;
  justify-content: space-between;
  background-color: hsla(300, 80%, 90%, 0.2);
  border-radius: 1.5rem 1.5rem 0 0;
}
...

مقدار پس زمینه رنگ از فرمت hsla() استفاده می کند و مانند مقدار rgba()، فرمت hsl() است اما با کانال آلفا. hsl() از سه بخش تشکیل شده است: یک مقدار درجه از چرخه رنگ، یک مقدار درصد اشباع، و یک مقدار درصد روشنایی، که رنگ نهایی را ایجاد می کند. 300 مقدار رنگ را بین آبی و قرمز در چرخه رنگ قرار می دهد، 80٪ اشباع سنگین به معنای رنگ بیشتر و خاکستری کمتر است، و 90٪ رنگ نهایی را روشن می کند. در نهایت، کانال آلفا مانند خاصیت opacity کار می کند و 0.2 مقدار را نزدیک به کاملا شفاف می کند. این یک پوشش روشن در بالای گرادیان ایجاد می کند و تعریفی را برای هدر ارائه می دهد.

این تغییرات را در styles.css ذخیره کنید و برای بازخوانی index.html به مرورگر بازگردید. سرصفحه مدال اکنون دارای یک برجسته صورتی تر در ناحیه است که آن را از محتوای مدال متمایز می کند. تصویر زیر نشان می دهد که چگونه هدر مدال اکنون در مرورگر رندر می شود:

راه دیگر برای ایجاد مقادیر رنگ شفاف، استفاده از مقادیر هگزادسیمال است. مقادیر رنگ هگزادسیمال از سه جفت ترکیبی از 0 تا 9 یا a تا f تشکیل شده و معادل عددی از 0 تا 255 است. سه رقم اول یک مقدار قرمز، سبز و آبی هستند که به صورت #RRGGBB فرمت شده اند. برای ایجاد یک کانال آلفا، مجموعه چهارم اضافه می شود و الگوی #RRGGBBAA را می سازد.

برای شروع کار با کانال های آلفای هگزادسیمال، به styles.css در ویرایشگر متن خود بازگردید. اکنون یک حاشیه به قسمت سرصفحه و محتوای مدال اضافه می‌کنید تا تعریف بیشتری به آن بدهید. این مرزها از مقدار هگزادسیمال یکسانی استفاده می کنند، اما مقادیر متفاوتی برای کانال آلفا به آنها داده می شود. CSS هایلایت شده از بلوک کد زیر نحوه نوشتن این سبک ها را نشان می دهد:

styles.css

...
.modal-header {
  display: flex;
  justify-content: space-between;
  background-color: hsla(300, 80%, 90%, 0.2);
  border-radius: 1.5rem 1.5rem 0 0;
  border: 4px solid #f7baf72f;
  border-bottom: none;
}
...
.modal-content {
  color: white;
  border-radius: 0 0 1.5rem 1.5rem;
  border: 4px solid #f7baf744;
  border-top: none;
}
...

هدر و محتوا هر کدام یک رنگ هگزادسیمال با #f7baf7 دارند، اما مقادیر کانال آلفای متفاوتی دارند. رنگ حاشیه انتخابگر هدر مدال دارای یک کانال آلفا تنظیم شده روی 2f است که شفاف تر است، زیرا 00 یک مقدار کانال آلفا کاملاً شفاف است. کانال آلفای .modal-content روی 44 تنظیم شده است که باعث شفاف‌تر شدن آن می‌شود.

تغییرات خود را در styles.css ذخیره کنید و index.html را در مرورگر وب بازخوانی کنید. تصویر زیر نحوه نمایش این حاشیه ها در مرورگر را نشان می دهد:

در نهایت، یک رنگ شش رقمی هگزا دسیمال را می توان به صورت خلاصه سه رقمی نوشت، که در آن #33ccee همان #3ce است. به همین ترتیب، یک مقدار هگزادسیمال با یک کانال آلفا را می توان به صورت خلاصه چهار رقمی نوشت به طوری که #33ccee99 را بتوان به #3ce9 کوتاه کرد و یک رنگ باشد.

برای شروع کار با یک هگزادسیمال کوتاه با کانال آلفا، به stlyes.css در ویرایشگر متن خود بازگردید. سپس، به انتخابگر کلاس .modal بروید و یک ویژگی box-shadow اضافه کنید. در اینجا یک سایه بزرگ روی مدال ایجاد می کنید که سیاه است اما توسط یک کانال آلفا نرم می شود. CSS هایلایت شده را در بلوک کد زیر به بلوک انتخابگر .modal خود اضافه کنید:

styles.css

...
.modal {
  margin: auto;
  width: 90%;
  max-width: 40rem;
  background: linear-gradient(135deg, hsl(300, 40%, 20%),hsl(300, 40%, 5%));
  border-radius: 1.5rem;
  box-shadow: 0 1rem 2rem #000a;
}
...

این سایه محور x را 1 rem پایین می آورد و تاری 2 rem را پخش می کند. در مرحله بعد، مقدار #000a با خاموش کردن هر سه مقدار رنگ، یک رنگ سیاه کامل را مشخص می کند. a که معادل aa است و دارای مقدار عددی 170 است، کانال آلفا را با شفافیت تقریباً 66٪ ارائه می کند. این کار سایه را کمی کم می کند، اما آن را به اندازه کافی قابل توجه نگه می دارد تا عمق زیر مودال را فراهم کند.

حتما این افزودنی را در styles.css ذخیره کنید، سپس index.html را در مرورگر refresh کنید. مدال اکنون تعریف و عمق بیشتری دارد. تصویر زیر رندر مودال را با مقادیر رنگ های مختلف ارائه می دهد:

در این بخش، شما از سه مقدار رنگ مختلف با کانال های آلفا برای اعمال کدورت به رنگ ها در ویژگی های خاص استفاده کردید. شما این رنگ ها را به ویژگی های پس زمینه رنگ، ویژگی های حاشیه و ویژگی box-shadow اضافه کردید. در بخش بعدی، از مقدار رنگ نام‌گذاری شده شفاف برای ایجاد گرادینت‌های منحصر به فرد و مخفی کردن محتوا استفاده می‌کنید.

افزودن مقدار رنگ شفاف به گرادیان خطی

مقادیر مختلف رنگی که از کانال های آلفا پشتیبانی می کنند برای زمانی که یک رنگ هنوز نیاز به شناسایی دارد مفید است. با این حال، زمانی که هیچ رنگی مورد نیاز نیست، رنگ شفاف به نام مفید می شود. در این بخش، دکمه Close را در حالت مخفی می‌کنید و یک شکل X با یک خطی-gradient() ایجاد می‌کنید که همه اینها با استفاده از مقدار شفاف است.

برای شروع استفاده از مقدار شفاف، styles.css را در ویرایشگر متن خود باز کنید. سپس، به انتخابگر کلاس .modal-close که قبلا اضافه کردید بروید. در داخل انتخابگر، همانطور که در بلوک کد زیر مشخص شده است، مقدار ویژگی رنگ را از سفید به شفاف تغییر دهید:

styles.css

...
.modal-close {
  color: transparent;
}
...

این تغییر متن را از فضای خالی حذف نمی کند. فقط آن را از رندر بصری در صفحه حذف می کند.

بعد، یک مربع از پیوند نزدیک ایجاد می کنید تا جایی برای ایجاد شکل X وجود داشته باشد. با افزودن یک ویژگی نمایشگر به بلاک شروع کنید، که به <a> امکان پیکربندی بصری بیشتری را می دهد. در مرحله بعد، یک ویژگی height و width ایجاد کنید و هر کدام را روی 1.5rem قرار دهید که شکل مربع را ایجاد می کند. در نهایت، یک ویژگی overflow را به hidden اضافه کنید، که از خروج متن به خارج از ظرف و افزودن فضای تعاملی جلوگیری می کند. CSS هایلایت شده از بلوک کد زیر نحوه تنظیم مربع را نشان می دهد:

styles.css

...
.modal-close {
  color: transparent;
  display: block;
  height: 1.5rem;
  width: 1.5rem;
  overflow: hidden;
}
...

بخش آخر ایجاد شکل X با یک نمونه پس زمینه چندگانه متشکل از دو مقدار خطی-gradient() است. برای تنظیم این، کد برجسته شده را از بلوک کد زیر اضافه کنید:

styles.css

...
.modal-close {
  color: transparent;
  display: block;
  height: 1.5rem;
  width: 1.5rem;
  overflow: hidden;
  background-image:
    linear-gradient(
      to top right,
      transparent 48%,
      white 48%,
      white 52%,
      transparent 52%
    ),
    linear-gradient(
      to top left,
      transparent 48%,
      white 48%,
      white 52%,
      transparent 52%
    );
}
...

اولین چیزی که در مورد این کد باید به آن توجه کرد این است که بخش های مختلف خطی-gradient() در خطوط جداگانه قرار دارند، که برای کمک به درک و خوانایی بیشتر پس زمینه پیچیده انجام می شود. این CSS هنوز معتبر است و نیازی نیست که مقادیر در یک خط با ویژگی باشند. سپس، مقادیر تکراری درصد برای شفاف و سفید به این معنی است که درجه بندی وجود نخواهد داشت. در عوض رنگ بلافاصله از شفاف به سفید تغییر می کند. در نهایت، سمت راست و بالا دو شیب در زوایای 45 درجه ایجاد می کند که همپوشانی دارند.

این تغییر را در styles.css ذخیره کنید و index.html را در یک مرورگر وب باز کنید. خواندن سلب مسئولیت را انتخاب کنید! دکمه و مدال اکنون به جای پیوند نزدیک، یک شکل X بزرگ و نازک خواهد داشت، همانطور که در تصویر زیر ارائه شده است:

در نهایت، حالت :hover و :focus مورد نیاز است تا به شکل X زمانی که مرکز تعامل است بیشتر قابل توجه باشد. برای این کار، گرادیان های قبلی را کپی می کنید و موقعیت را برای رشد ناحیه سفید جامد تنظیم می کنید.

برای ایجاد یک حالت تعاملی برای X، به styles.css در ویرایشگر متن خود بازگردید. به دنبال انتخابگر کلاس .modal-close، یک انتخابگر گروه جدید متشکل از .modal-close:hover و .modal-close:focus ایجاد کنید. سپس، ویژگی و مقدار background-image را از .modal-close در انتخابگر جدید کپی کنید. در نهایت، بخش های 48 درصدی را به 46 درصد کاهش دهید و 52 درصد را به 54 درصد افزایش دهید.

style.css

...
.modal-close {
  ...
}

.modal-close:hover,
.modal-close:focus {
  background-image:
    linear-gradient(
      to top right,
      transparent 46%,
      white 46%,
      white 54%,
      transparent 54%
    ),
    linear-gradient(
      to top left,
      transparent 46%,
      white 46%,
      white 54%,
      transparent 54%
    );
}
...

این تغییرات را در styles.css ذخیره کنید و صفحه را در مرورگر خود بازخوانی کنید. اکنون، زمانی که X روی ماوس قرار می‌گیرد یا فوکوس صفحه‌کلید به آن داده می‌شود، اندازه شیب‌هایی که شکل را ایجاد می‌کنند افزایش می‌یابد و جلوه‌ای می‌دهد که گویی X پررنگ است. انیمیشن زیر نشان می دهد که چگونه این افکت در یک مرورگر در طول یک رویداد شناور ارائه می شود:

این بخش شما را با ویژگی transparent آشنا می کند و شما از آن برای مخفی کردن محتوا و ایجاد نماد X با استفاده از مقادیر ()linear-gradient استفاده می کنید. در بخش آخر، از مقدار شفاف بر روی یک گرادیان برای کمک به ارائه افکت انیمیشن بر روی یک عنصر استایل دکمه ای استفاده خواهید کرد.

با استفاده از حالت :hover برای انتقال بین مقادیر رنگ شفاف

یکی از جنبه‌های ویژگی انتقال که گاهی به راه‌حل‌های خلاقانه نیاز دارد این است که همه ویژگی‌ها را نمی‌توان متحرک کرد. یکی از این ویژگی ها تصویر پس زمینه است، به این معنی که مقادیر یک گرادیان خطی در این ویژگی نمی توانند متحرک شوند. با این حال، مقدار رنگ پس‌زمینه حتی اگر تصویر پس‌زمینه وجود داشته باشد، می‌تواند متحرک شود. در این بخش، با استفاده از مقادیر رنگی شفاف و کانال آلفا، یک انیمیشن انتقال ایجاد می کنید که به نظر می رسد یک انیمیشن گرادیان باشد.

برای ایجاد یک گرادیان متحرک، styles.css را در ویرایشگر متن خود باز کنید. سپس به انتخابگر کلاس .button بروید. کلاس .button از قبل تغییری در رنگ پس زمینه بین انتخابگر خود و دکمه .:hover دارد. ویژگی و مقدار انتقال برجسته شده را از بلوک کد زیر به فایل styles.css خود اضافه کنید:

styles.css

...
.button {
  text-decoration: none;
  display: inline-block;
  padding: 0.5rem 1.25rem;
  color: white;
  background: #4c90b2;
  border: 1px solid #2d566b;
  border-radius: 0.5rem;
  transition: background-color 250ms ease;
}

.button:hover,
.button:focus {
  background-color: #2d566b;
}
...

تغییرات خود را در styles.css ذخیره کنید و index.html را در مرورگر وب خود باز کنید. نگه داشتن دکمه با مکان نما اکنون باعث می شود که رنگ پس زمینه بین آبی روشن و آبی تیره متحرک شود. انیمیشن زیر نشان می دهد که چگونه این در مرورگر ارائه می شود:

اکنون، برای افزودن گرادیان، به styles.css در ویرایشگر متن خود برگردید. به انتخابگر دکمه .برگردید و یک ویژگی پس زمینه تصویر با یک خطی-gradient() اضافه کنید. جهت گرادیان به سمت پایین خواهد بود و با یک کانال آلفا آبی روشن شروع می شود و سپس به سمت شفاف می رود. انیمیشن با کانال آلفا آبی تیره به پایان می رسد. CSS هایلایت شده در بلوک کد زیر نحوه نوشتن این گرادیان را نشان می دهد:

styles.css

...
.button {
  text-decoration: none;
  display: inline-block;
  padding: 0.5rem 1.25rem;
  color: white;
  background: #4c90b2;
  border: 1px solid #2d566b;
  border-radius: 0.5rem;
  background-image:
    linear-gradient(
      to bottom,
      hsla(200, 40%, 80%, 0.4),
      transparent,
      hsla(200, 40%, 20%, 0.6)
    );
  transition: background-color 250ms ease;
}
...

این گرادیان رنگ پس‌زمینه را پوشش می‌دهد و به این شکل ظاهر می‌شود که گرادیان از آبی روشن به آبی میانی و سپس آبی تیره می‌گذرد. هنگامی که دکمه با یک رویداد تعاملی روبرو می شود، رنگ پس زمینه به آبی تیره تر تغییر می کند و این توهم ایجاد می کند که شیب کلی تیره شده است.

این به روز رسانی ها را در styles.css ذخیره کنید و سپس به فایل index.html خود در مرورگر بازگردید و صفحه را بازخوانی کنید. همانطور که در انیمیشن زیر نشان داده شده است، هنگامی که مکان نما روی دکمه حرکت می کند، به نظر می رسد گرادیان از یک گرادیان آبی روشن به یک گرادیان آبی تیره متحرک می شود:

در این بخش آخر، از مقادیر رنگ، مقدار شفاف نامگذاری شده و ویژگی transition برای ایجاد توهم متحرک سازی گرادیان استفاده کردید. با توجه به این، شما همچنین یاد گرفتید که چه نوع ویژگی هایی را می توان متحرک کرد.

نتیجه

در طول این آموزش، از ویژگی opacity و مقادیر رنگی زیادی با کانال های آلفا استفاده کردید. شما از کدورت با رویدادهای اشاره گر و انتقال برای ایجاد یک افکت محو برای نمایش یک مدال در صورت تقاضا استفاده کردید. شما همچنین از مقادیر مختلف رنگ موجود برای کنترل شفافیت و پوشش رنگ روی محتوا استفاده کردید. شما از مقدار با نام شفاف برای ایجاد یک نماد X برای بستن مدال استفاده کردید. در نهایت، شما از ترکیبی از رنگ‌ها، مقدار شفاف، گرادیان‌ها و انتقال برای ایجاد توهم شیب متحرک روی یک دکمه استفاده کردید.

دلایل مفید زیادی برای استفاده از رنگ‌های شفاف و شفاف در طراحی وب وجود دارد. ویژگی opacity را می توان برای متحرک سازی یک افکت محو و محو بر روی عناصری که قرار است در صورت نیاز قابل مشاهده باشند، استفاده کرد. مقادیر رنگ های مختلف که امکان کنترل شفافیت را فراهم می کند، راه های بسیاری را برای ترکیب رنگ ها و محتوا با یکدیگر فراهم می کند. در مجموع، این روش‌های ایجاد شفافیت می‌توانند جلوه‌ها و سبک‌های منحصربه‌فردی را ایجاد کنند.

برچسب‌ها:CSSاستایل‌سازی HTML با CSSانواع سرور مجازیایجاد سرور مجازیایجاد یک Modal در CSSخرید سرور لینوکسراه اندازی پایه HTML و CSSسرور مجازی

 

https://vpsgol.net/product/vps-germany/

 

https://vpsgol.net/product/vps-usa/

 

https://vpsgol.net/product/vps-france/

 

https://vpsgol.net/product/vps-canada/

 

https://vpsgol.net/product/vps-poland/

 

https://vpsgol.net/product/vps-netherlands/

 

https://vpsgol.net/product/vps-england/

  • behnam gol mohamadi