معرفی Kendo UI
ASP.NET MVC #21
آیا استفاده از این افزونه http://awesome.codeplex.com/ رایگان است؟
چرا vuetify ؟
دلایل زیادی برای استفاده از این framework وجود دارد که از جمله آنها میتوان به مواردی از قبیل رابط کاربری خوب برای طرح بندی صفحه برنامه، پشتیبانی از تمام مرورگرها، پشتیبانی از RTL (راست به چپ کردن صفحه)، پشتیبانی از cli3 و موارد دیگر میتوان اشاره نمود.
روش نصب vuetify
vue add vuetify
ساختار grid
grid برای طرح بندی، یا بخش بندی محتوای برنامه استفاده میشود .vuetify همانند bootstrap، از سیستم بخش بندی 12 تایی برای تقسیم بندی صفحه استفاده میکند. در این روش ما به 5 حالت مختلف میتوانیم صفحه را بخش بندی کنیم:
طریقهی استفاده
ساختار برنامهی ما شامل یک سری از کامپوننتهای از پیش تعیین شده برای راحتی و سادگی کار میباشد که در زیر به آنها اشاره شدهاست.
ساختار برنامه ما باید دارای یک v-container باشد تا به درستی کار کند. این کامپوننت در بر گیرندهی تمام صفحهی برنامه است. هر کامپوننت میتواند تنظیمات خاص خود را داشته باشد.
برای مثال در کد پایین، تنظیم fluid باعث میشود تا کامپوننت v-container تمام عرض صفحهی ما را در بر بگیرد.
<v-container fluid></v-container>
کامپوننت v-layout برای کار با ردیفها مورد استفاده قرار میگیرد که تنظیمات مخصوص به خود را دارد.
برای بخش بندی هر ستون در صفحه میتوان از کامپوننت v-flex استفاده کرد.
نکته: در توضیح کد پایین، در قسمت تعریف v-layout به وسیله row مشخص میکنیم که میخواهیم یک ردیف را ایجاد کنیم و در قسمت تعریف v-flex به وسیله md6 مشخص میکنیم که 6 خانه از 12 خانه موجود در ردیف را میخواهیم در اختیار داشته باشیم:
<v-container> <v-layout row> <v-flex md6> ... </v-flex> <v-flex md6> ... </v-flex> </v-layout> </v-container>
نتیجهی قطعه کد بالا بدین ترتیب است:
به وسیله breakpointها میتوانیم مشخص کنیم که هر المان درون هر مدیا (موبایل، تبلت، کامپیوتر و ...) به چه صورتی نمایش داده شود. در حالت کلی پنج نوع breakpoint وجود دارند که به ترتیب شامل:
<v-flex xs6 sm5> </v-flex>
<v-flex xs5 md8> </v-flex>
<div id="app"> <v-app id="inspire"> <v-container grid-list-xl text-xs-center> <v-layout row wrap> <v-flex xs10 offset-xs1> <v-card dark color="purple"> <v-card-text>xs10 offset-xs1</v-card-text> </v-card> </v-flex> <v-flex xs7 offset-xs5 offset-md2 offset-lg5> <v-card dark color="secondary"> <v-card-text>xs7 offset-(xs5 | md2 | lg5)</v-card-text> </v-card> </v-flex> <v-flex xs12 sm5 md3> <v-card dark color="primary"> <v-card-text>(xs12 | sm5 | md3)</v-card-text> </v-card> </v-flex> <v-flex xs12 sm5 md5 offset-xs0 offset-lg2> <v-card dark color="green"> <v-card-text>(xs12 | sm5 | md5) offset-(xs0 | lg2)</v-card-text> </v-card> </v-flex> </v-layout> </v-container> </v-app> </div>
نتیجهی قطعه کد بالا بدین صورت است:
هدایت سراسری و خودکار کاربران اعتبارسنجی نشده به صفحهی لاگین
در برنامهی این سری، اگر کاربری که به سیستم وارد نشدهاست، بر روی دکمهی Book یک اتاق کلیک کند، فقط پیام «Not Authorized» را مشاهده خواهد کرد که تجربهی کاربری مطلوبی بهشمار نمیرود. بهتر است در یک چنین حالتی، کاربر را به صورت خودکار به صفحهی لاگین هدایت کرد و پس از لاگین موفق، مجددا او را به همین آدرس درخواستی پیش از نمایش صفحهی لاگین، هدایت کرد. برای مدیریت این مساله کامپوننت جدید RedirectToLogin را طراحی میکنیم که جایگزین پیام «Not Authorized» در کامپوننت ریشهای BlazorWasm.Client\App.razor خواهد شد. بنابراین ابتدا فایل جدید BlazorWasm.Client\Pages\Authentication\RedirectToLogin.razor را ایجاد میکنیم. چون این کامپوننت بدون مسیریابی خواهد بود و قرار است مستقیما داخل کامپوننت دیگری درج شود، نیاز است فضای نام آنرا نیز به فایل BlazorWasm.Client\_Imports.razor اضافه کرد:
@using BlazorWasm.Client.Pages.Authentication
@using System.Security.Claims @inject NavigationManager NavigationManager if(AuthState is not null) { <div class="alert alert-danger"> <p>You [@AuthState.User.Identity.Name] do not have access to the requested page</p> <div> Your roles: <ul> @foreach (var claim in AuthState.User.Claims.Where(c => c.Type == ClaimTypes.Role)) { <li>@claim.Value</li> } </ul> </div> </div> } @code { [CascadingParameter] private Task<AuthenticationState> AuthenticationState {set; get;} AuthenticationState AuthState; protected override async Task OnInitializedAsync() { AuthState = await AuthenticationState; if (!IsAuthenticated(AuthState)) { var returnUrl = NavigationManager.ToBaseRelativePath(NavigationManager.Uri); if (string.IsNullOrEmpty(returnUrl)) { NavigationManager.NavigateTo("login"); } else { NavigationManager.NavigateTo($"login?returnUrl={Uri.EscapeDataString(returnUrl)}"); } } } private bool IsAuthenticated(AuthenticationState authState) => authState?.User?.Identity is not null && authState.User.Identity.IsAuthenticated; }
در اینجا روش کار کردن با AuthenticationState را از طریق کدنویسی ملاحظه میکنید. در زمان بارگذاری اولیهی این کامپوننت، بررسی میشود که آیا کاربر جاری، به سیستم وارد شدهاست یا خیر؟ اگر خیر، او را به سمت صفحهی لاگین هدایت میکنیم. اما اگر کاربر پیشتر به سیستم وارد شده باشد، متن شما دسترسی ندارید، به همراه لیست نقشهای او در صفحه ظاهر میشوند که برای دیباگ برنامه مفید است و دیگر به سمت صفحهی لاگین هدایت نمیشود.
در ادامه برای استفاده از این کامپوننت، به کامپوننت ریشهای BlazorWasm.Client\App.razor مراجعه کرده و قسمت NotAuthorized آنرا به صورت زیر، با معرفی کامپوننت RedirectToLogin، جایگزین میکنیم:
<NotAuthorized> <RedirectToLogin></RedirectToLogin> </NotAuthorized>
چگونه دسترسی نقش ثابت Admin را به تمام صفحات محافظت شده برقرار کنیم؟
اگر خاطرتان باشد در زمان ثبت کاربر ادمین Identity، تنها نقشی را که برای او ثبت کردیم، Admin بود که در تصویر فوق هم مشخص است؛ اما ویژگی Authorize استفاده شده جهت محافظت از کامپوننت (attribute [Authorize(Roles = ConstantRoles.Customer)]@)، تنها نیاز به نقش Customer را دارد. به همین جهت است که کاربر وارد شدهی به سیستم، هرچند از دیدگاه ما ادمین است، اما به این صفحه دسترسی ندارد. بنابراین اکنون این سؤال مطرح است که چگونه میتوان به صورت خودکار دسترسی نقش Admin را به تمام صفحات محافظت شدهی با نقشهای مختلف، برقرار کرد؟
برای رفع این مشکل همانطور که پیشتر نیز ذکر شد، نیاز است تمام نقشهای مدنظر را با یک کاما از هم جدا کرد و به خاصیت Roles ویژگی Authorize انتساب داد؛ و یا میتوان این عملیات را به صورت زیر نیز خلاصه کرد:
using System; using BlazorServer.Common; using Microsoft.AspNetCore.Authorization; namespace BlazorWasm.Client.Utils { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] public class RolesAttribute : AuthorizeAttribute { public RolesAttribute(params string[] roles) { Roles = $"{ConstantRoles.Admin},{string.Join(",", roles)}"; } } }
پس از این تعریف میتوان در کامپوننتها، ویژگی Authorize نقش دار را با ویژگی جدید Roles، جایگزین کرد که همواره دسترسی کاربر Admin را نیز برقرار میکند:
@attribute [Roles(ConstantRoles.Customer, ConstantRoles.Employee)]
مدیریت سراسری خطاهای حاصل از درخواستهای HttpClient
تا اینجا نتایج حاصل از شکست اعتبارسنجی سمت کلاینت را به صورت سراسری مدیریت کردیم. اما برنامههای سمت کلاینت، به کمک HttpClient خود نیز میتوانند درخواستهایی را به سمت سرور ارسال کرده و در پاسخ، برای مثال not authorized و یا forbidden را دریافت کنند و یا حتی internal server error ای را در صورت بروز استثنایی در سمت سرور.
فرض کنید Web API Endpoint جدید زیر را تعریف کردهایم که نقش ادیتور را میپذیرد. این نقش، جزو نقشهای تعریف شدهی در برنامه و سیستم Identity ما نیست. بنابراین هر درخواستی که به سمت آن ارسال شود، برگشت خواهد خورد و پردازش نمیشود:
namespace BlazorWasm.WebApi.Controllers { [Route("api/[controller]")] [Authorize(Roles = "Editor")] public class MyProtectedEditorsApiController : Controller { [HttpGet] public IActionResult Get() { return Ok(new ProtectedEditorsApiDTO { Id = 1, Title = "Hello from My Protected Editors Controller!", Username = this.User.Identity.Name }); } } }
namespace BlazorWasm.Client.Services { public class ClientHttpInterceptorService : DelegatingHandler { private readonly NavigationManager _navigationManager; private readonly ILocalStorageService _localStorage; private readonly IJSRuntime _jsRuntime; public ClientHttpInterceptorService( NavigationManager navigationManager, ILocalStorageService localStorage, IJSRuntime JsRuntime) { _navigationManager = navigationManager ?? throw new ArgumentNullException(nameof(navigationManager)); _localStorage = localStorage ?? throw new ArgumentNullException(nameof(localStorage)); _jsRuntime = JsRuntime ?? throw new ArgumentNullException(nameof(JsRuntime)); } protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { // How to add a JWT to all of the requests var token = await _localStorage.GetItemAsync<string>(ConstantKeys.LocalToken); if (token is not null) { request.Headers.Authorization = new AuthenticationHeaderValue("bearer", token); } var response = await base.SendAsync(request, cancellationToken); if (!response.IsSuccessStatusCode) { await _jsRuntime.ToastrError($"Failed to call `{request.RequestUri}`. StatusCode: {response.StatusCode}."); switch (response.StatusCode) { case HttpStatusCode.NotFound: _navigationManager.NavigateTo("/404"); break; case HttpStatusCode.Forbidden: // 403 case HttpStatusCode.Unauthorized: // 401 _navigationManager.NavigateTo("/unauthorized"); break; default: _navigationManager.NavigateTo("/500"); break; } } return response; } } }
با ارثبری از کلاس پایهی DelegatingHandler میتوان متد SendAsync تمام درخواستهای ارسالی توسط برنامه را بازنویسی کرد و تحت نظر قرار داد. برای مثال در اینجا، پیش از فراخوانی await base.SendAsync کلاس پایه (یا همان درخواست اصلی که در قسمتی از برنامه صادر شدهاست)، یک توکن را به هدرهای درخواست، اضافه کردهایم و یا پس از این فراخوانی (که معادل فراخوانی اصل کد در حال اجرای برنامه است)، با بررسی StatusCode بازگشتی از سمت سرور، کاربر را به یکی از صفحات یافت نشد، خطایی رخ دادهاست و یا دسترسی ندارید، هدایت کردهایم. برای نمونه کامپوننت Unauthorized.razor را با محتوای زیر تعریف کردهایم:
@page "/unauthorized" <div class="alert alert-danger mt-3"> <p>You don't have access to the requested resource.</p> </div>
پس از تدارک این Interceptor سراسری، نوبت به معرفی آن به برنامهاست که ... در ابتدا نیاز به نصب بستهی نیوگت زیر را دارد:
dotnet add package Microsoft.Extensions.Http
namespace BlazorWasm.Client { public class Program { public static async Task Main(string[] args) { var builder = WebAssemblyHostBuilder.CreateDefault(args); //... // builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); /*builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.Configuration.GetValue<string>("BaseAPIUrl")) });*/ // dotnet add package Microsoft.Extensions.Http builder.Services.AddHttpClient( name: "ServerAPI", configureClient: client => { client.BaseAddress = new Uri(builder.Configuration.GetValue<string>("BaseAPIUrl")); client.DefaultRequestHeaders.Add("User-Agent", "BlazorWasm.Client 1.0"); } ) .AddHttpMessageHandler<ClientHttpInterceptorService>(); builder.Services.AddScoped<ClientHttpInterceptorService>(); builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("ServerAPI")); //... } } }
کدهای کامل این مطلب را از اینجا میتوانید دریافت کنید: Blazor-5x-Part-33.zip
Bridge Network Driver
The bridge
networking driver is the first driver on our list. It’s simple to understand, simple to use, and simple to troubleshoot, which makes it a good networking choice for developers and those new to Docker. The bridge
driver creates a private network internal to the host so containers on this network can communicate. External access is granted by exposing ports to containers. Docker secures the network by managing rules that block connectivity between different Docker networks.
Overlay Network Driver
The built-in Docker overlay
network driver radically simplifies many of the complexities in multi-host networking. It is a swarm scope driver, which means that it operates across an entire Swarm or UCP cluster rather than individual hosts. With the overlay
driver, multi-host networks are first-class citizens inside Docker without external provisioning or components. IPAM, service discovery, multi-host connectivity, encryption, and load balancing are built right in. For control, the overlay
driver uses the encrypted Swarm control plane to manage large scale clusters at low convergence times.
MACVLAN Driver
The macvlan
driver is the newest built-in network driver and offers several unique characteristics. It’s a very lightweight driver, because rather than using any Linux bridging or port mapping, it connects container interfaces directly to host interfaces. Containers are addressed with routable IP addresses that are on the subnet of the external network.
As a result of routable IP addresses, containers communicate directly with resources that exist outside a Swarm cluster without the use of NAT and port mapping. This can aid in network visibility and troubleshooting. Additionally, the direct traffic path between containers and the host interface helps reduce latency. macvlan
is a local scope network driver which is configured per-host. As a result, there are stricter dependencies between MACVLAN and external networks, which is both a constraint and an advantage that is different from overlay
or bridge
.
This webcast is a code-focused introduction to developing workflow-enabled Microsoft Windows platform applications. We cover the basics of developing, designing, and debugging workflow solutions. Gain the knowledge and insight you need to be confident choosing workflow for everyday applications.
Intro to Windows Workflow Foundation (Part 2 of 7): Simple Human Workflow Using E-mail (Level 200)
Have you thought about how you might apply the workflow concept to e-mail? In this webcast New Zealand based regional director, Chris Auld, leads attendees through a simple worked example of the use of SMTP e-mail as part of a workflow solution. Chris demonstrates how to create custom activities to query Active Directory to retrieve user data, send e-mail, and wait for e-mail responses to continue the workflow process. This code-intensive session gives users taking their first steps with workflow a good grounding in some of the key extensibility concepts.
Intro to Windows Workflow Foundation (Part 3 of 7): Hosting and Communications Options in Workflow Scenarios (Level 300)
The session looks at options for hosting workflow applications. We cover managing events, instance tracking, and persistence, and provide a close look at the simple communications mechanisms that are available for you to use in your workflow applications.
Intro to Windows Workflow Foundation (Part 4 of 7): Workflow, Messaging, and Services: Developing Distributed Applications with Workflows (Level 300)
Web service technologies have typically taken a "do-it-yourself" approach to maintaining the interoperation state of services. Using workflow, developers now have tools that allow them to describe the long-running state of their services and delegate much of the state management to the underlying platform. Managing this state correctly becomes even more challenging in applications that coordinate work across multiple services either within an organization or at an Internet scale. This session looks at how developers who use either Microsoft ASMX or Microsoft's framework for building service-oriented applications, code-named "Indigo", can create workflow-oriented applications that are both faster to write and more manageable and flexible once deployed.
Intro to Windows Workflow Foundation (Part 5 of 7): Developing Event Driven State Machine Workflows (Level 300)
State machines used to be something that you had to first draw on paper and then implement in code. This session shows how to use technologies to create event-driven workflows and how to apply this to a typical programming problem. We introduce the concept of a flexible process and show how this can help with modeling real-world processes using state and sequential workflow. Plenty of coding is included to illustrate how you can seamlessly merge state machine design and your code.
Intro to Windows Workflow Foundation (Part 6 of 7): Extending Workflow Capabilities with Custom Activities (Level 300)
It is helpful to think of activities as controls within a workflow, similar to controls used with Microsoft ASP.NET Pages or Microsoft Windows Forms. You can use activities to encapsulate execution logic, communicate with the host and decompose a workflow into reusable components. This session examines the simple process of creating custom activities. If you want to expose activities to other developers designing workflows, you are likely to find this session valuable.
Intro to Windows Workflow Foundation (Part 7 of 7): Developing Rules Driven Workflows (Level 300)
Rules can be a powerful business tool when combined with workflow. In this session, learn how to develop more advanced activities that support the modeling of rich business behavior such as human workflow. Understand when to use rules for business logic, and see how rule policies allow for the description of sophisticated behavior in an integrated and flexible way. This session gives you an interesting insight into the power of using workflow at the core of a line of business application.
اولین کاری را که باید جهت شروع به کار با بوت استرپ 4 انجام داد، نصب و افزودن آن به صفحهی HTML جاری است. روشهای زیادی برای انجام اینکار وجود دارند:
الف) استفاده از نگارش SASS آن
بوت استرپ 4 در اصل مبتنی بر SASS توسعه یافتهاست و فایلهای آن با فرمت scss. ارائه میشوند. مزیت کار با این روش، امکان سفارشی سازی بوت استرپ 4 و یا مشارکت در پروژهی آن است و بدیهی است پس از آن باید SASS را به CSS کامپایل و مورد استفاده قرار داد.
ب) استفاده از CDN و یا Content delivery network
- مزیت آن بالا رفتن سرعت سایت با کش شدن آن در شبکه و یا شبکههای توزیع محتوا است.
- اما این روش محدودیت و الزام کار آنلاین با فایلهای بوت استرپ را نیز به همراه دارد.
برای کار با CDNهای بوت استرپ، مطابق راهنمای آن، تنها کافی است مدخل فایل css آنرا به head صفحه و مداخل فایلهای js ذیل را پیش از بسته شدن تگ body قرار دهید:
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
- jquery-3.3.1.slim : در اینجا slim یک نگارش بسیار کوچک از jQuery میباشد که بوت استرپ 4 بر مبنای آن کار میکند. البته در یک پروژهی واقعی احتمالا نیاز به نگارش کامل آنرا خواهید داشت و یا اگر قصد حذف کردن جیکوئری را دارید، این نگارش، کمحجمترین آن است.
- popper.min.js : برای نمونه Bootstrap dropdown برای کارکرد صحیح آن در نگارش 4، نیاز به این وابستگی جدید را دارد.
ج) استفاده از فایلهای از پیش پردازش شده
فایلهای از پیش آماده شدهی آنرا میتوان مستقیما از سایت بوت استرپ، با کلیک بر روی دکمهی download واقع در منوی راهبری سایت آن، دریافت کرد. مزیت این روش، امکان کار و توسعهی آفلاین صفحات مبتنی بر بوت استرپ است.
مشکل این روش عدم اطلاع رسانی خودکار از ارائهی نگارشهای جدید و نیاز به دریافت دستی مجدد این بسته، به ازای هر نگارش جدید آن میباشد.
د) استفاده از ابزارهای مدیریت بستهها
روشی را که ما در اینجا از آن استفاده خواهیم کرد، دریافت و نصب وابستگیهای مورد نیاز جهت کار با بوت استرپ 4، توسط npm است. به همین جهت یک فایل جدید package.json را با محتوای ذیل ایجاد کنید:
{ "name": "bootstrap.4", "version": "1.0.0", "description": "client side resources of the project", "scripts": {}, "author": "VahidN", "license": "ISC", "dependencies": { "bootstrap": "^4.1.3", "components-font-awesome": "5.0.6", "jquery": "^3.3.1", "popper.js": "^1.14.4" } }
در اینجا font-awesome را نیز مشاهده میکنید؛ از این جهت که بوت استرپ 4 برخلاف نگارش 3 آن، به همراه گلیف آیکنهای پیشفرض آن نیست.
ایجاد قالب ابتدایی شروع به کار با بوت استرپ 4
پس از دریافت وابستگیهای مورد نیاز جهت شروع به کار با بوت استرپ 4 که هم اکنون باید در پوشهی node_modules واقع در ریشهی پوشهی جاری موجود باشند، در ادامه حداقل قالبی را که برای کار با آن نیاز است، مرور میکنیم:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="/node_modules/components-font-awesome/css/fa-solid.min.css"> <link rel="stylesheet" href="/node_modules/components-font-awesome/css/fontawesome.min.css"> <title>Bootstrap</title> </head> <body> <div class="container"> </div> <script src="/node_modules/jquery/dist/jquery.min.js"></script> <script src="/node_modules/popper.js/dist/umd/popper.min.js"></script> <script src="/node_modules/bootstrap/dist/js/bootstrap.min.js"></script> </body> </html>
- سپس viewport استاندارد، جهت تعیین اینکه این صفحه با ابزارهای موبایل نیز سازگار است، تعریف شدهاست.
- در قسمت head، مدخل فایل bootstrap.min.css تعریف شدهاست. همچنین مداخل مورد نیاز جهت کار با font-awesome را نیز مشاهده میکنید.
- پیش از بسته شدن تگ body، تعاریف jQuery، کتابخانهی popper و سپس bootstrap.min.js قید شدهاند. کتابخانهی popper از مسیر umd آن دریافت شدهاست تا همه جا کار کند.
نکتهی مهم!
در نگارش نهایی برنامهی شما، مسیرهای فایلهای شروع شدهی با /node_modules/ نباید وجود داشته باشند. این فایلها را بهتر است توسط ابزارهای bundling & minification یکی و سپس به صفحه اضافه کنید.
غنی سازی ویرایشگر VSCode برای کار سادهتر با بوت استرپ
VSCode یک ویرایشگر حرفهای چندسکویی است که برای ویندوز، مک و لینوکس تهیه شدهاست. این ویرایشگر را میتوان توسط افزونههای زیر برای کار سادهتر با بوت استرپ غنی کرد:
Bootstrap 4, Font awesome 4, Font Awesome 5 Free & Pro snippets: ساده سازی تشکیل تگهای بوت استرپ
Path Autocomplete: کار وارد کردن مسیر فایلها و تصاویر را ساده میکند.
HTML CSS Support: کار آن غنی سازی intellisense این ویرایشگر جهت کار با ویژگیها و همچنین کلاسهای CSS است.
IntelliSense for CSS class names in HTML: انتخاب کلاسهای CSS بوت استرپ را سادهتر میکند.
Live Server: کار آن راه اندازی یک وب سرور آزمایشی و سپس امکان مشاهدهی آنی تغییرات در برنامه و فایل HTML جاری، در مرورگر میباشد.
برای کار با آن، در حالیکه صفحهی HTML جاری در VSCode باز است، بر روی دکمهی Go Live اضافه شدهی در status bar آن کلیک کنید. پس از آن، یک وب سرور آزمایشی را بر روی پورت 5500 آغاز کرده و صفحهی جاری را در آدرس http://127.0.0.1:5500/index.html در مرورگر پیشفرض سیستم نمایش میدهد. اکنون فایل HTML خود را در VSCode ویرایش کنید. ملاحظه خواهید کرد که بلافاصله این تغییرات در مرورگر قابل مشاهده هستند.
نگارشهای راست به چپ بوت استرپ 4
قرار است بوت استرپ 4 نگارش رسمی راست به چپ نیز داشته باشد. به همین منظور میتوانید در اینجا رای خود را اظهار کنید.
همچنین پروژههای زیر نیز چنین قابلیتی را ارائه میدهند:
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید: Bootstrap4_01.zip