آموزش معرفی و بررسی

چگونه با 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/