Category: طراحی سایت

غلبه بر چالش های تولید محتوا برای وب سایت های اطلاعاتی – مجله Smashing

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

  1. به گزارش گروه نورمن نیلسن، کاربران تنها 20 تا 28 درصد از یک صفحه وب را می خوانند.
  2. اکثر افرادی که محتوا را برای وب می نویسند فاقد مهارت های لازم هستند که منجر به تولید محتوای بی کیفیت می شود.

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

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

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

تکنیک شماره 1: ارائه آموزش سازندگان محتوا

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

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

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

  • چگونه یک صفحه را برای موتورهای جستجو بهینه کنیم.
  • چگونه اطمینان حاصل کنیم که صفحه شما در دسترس است
  • چگونه محتوای خود را ساختار دهید
  • چگونه عناوین واضح و جذاب بنویسیم.
  • چگونه محتوا را جذاب تر کنیم

و غیره.

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

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

تکنیک شماره 2: تولیدکنندگان محتوا را پاسخگو کنید

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

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

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

ممکن است در برابر این ایده با مقاومت روبرو شوید زیرا افراد نقش ها را تغییر می دهند و بنابراین مسئولیت ها تغییر می کنند. با این حال، به همین دلیل است که صفحات باید صاحب خاصی داشته باشند. خیلی اوقات، وقتی افراد به سمت جلو حرکت می کنند، صفحات تحویل داده نمی شوند، و اینها صفحات یتیم رها شده و منجر به ROT محتوا می شود (محتوای زائد، قدیمی یا بی اهمیت).

اطمینان از مرتبط بودن و به روز بودن محتوا ضروری است، که من را به تکنیک سوم خود هدایت می کند.

بیشتر بعد از پرش! ادامه مطلب زیر ↓

تکنیک شماره 3: ایجاد حاکمیت در اطراف محتوای وب سایت

تنها راهی که محتوا به‌روز می‌ماند، مرور منظم آن است. و برای دستیابی به آن، نیاز به حاکمیتی داریم که به تولیدکنندگان محتوا انگیزه دهد تا دقیقاً همین کار را با صفحاتی که مسئولیت آنها را بر عهده دارند، انجام دهند.

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

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

با این حال، به عنوان حداقل مطلق، شما باید نیاز به بررسی منظم صفحات دارد – میزان منظم به محتوا و موقعیت شما بستگی دارد.

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

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

یک صفحه وب سایت با بنری که نشان می دهد محتوا به روز نیست و حاوی اطلاعات تماس صاحب صفحه است.
صفحاتی که به روز نمی شوند باید یک بنر آرشیو حاوی اطلاعات تماس صاحب صفحه داشته باشند. (پیش نمایش بزرگ)

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

تکنیک شماره 4: ارائه بازخورد خوب به سازندگان محتوا

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

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

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

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

یک صفحه وب سایت با یک نظرسنجی کوتاه یک سوالی
افزودن یک نظرسنجی کوتاه یک سوالی به هر صفحه بازخوردی را برای سازندگان محتوا فراهم می کند. (پیش نمایش بزرگ)

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

همچنین می‌توانید با اهدای جوایز و جوایز (مثل کارمند ماه) از موفق‌ترین سازندگان محتوا یا بهبود یافته‌ترین صفحات تجلیل کنید.

آوردن آن همه با هم

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

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

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

در نهایت، ما می توانیم آموزش را مستقیماً در داشبورد ادغام کنید در قالب راهنمایی های سریع (مانند مثال برنامه همینگوی) و توصیه های دقیق تر در مورد نحوه رسیدگی به سؤالاتی که سازندگان محتوا ممکن است در آن مرحله داشته باشند.

داشبوردی با پیوندهایی به مطالب آموزشی
با ادغام مطالب آموزشی به طور مستقیم در داشبورد، سازندگان محتوا نیازی به جستجوی پاسخ برای سوالات خاص ندارند. (پیش نمایش بزرگ)

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

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

مطالعه بیشتر در SmashingMag

سرمقاله Smashing
(vf، yk، il)

Read More

بین المللی سازی در Next.js 13 با اجزای سرور React – مجله Smashing

با معرفی Next.js 13 و انتشار نسخه بتا App Router، React Server Components در دسترس عموم قرار گرفت. این پارادایم جدید به اجزایی اجازه می دهد که به ویژگی های تعاملی React نیازی نداشته باشند، مانند useState و useEffect، فقط در سمت سرور باقی بماند.

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

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

در این مقاله، یک اپلیکیشن چند زبانه را بررسی می کنیم که تصاویر عکاسی خیابانی را از Unsplash نمایش می دهد. استفاده خواهیم کرد next-intl برای پیاده‌سازی تمام نیازهای بین‌المللی‌سازی خود در React Server Components، و به تکنیکی برای معرفی تعامل با یک ردپای مینیمالیستی سمت مشتری نگاه خواهیم کرد.

قاب نهایی برنامه
شما همچنین می توانید بررسی کنید نسخه ی نمایشی تعاملی. (پیش نمایش بزرگ)

واکشی عکس ها از Unsplash

یکی از مزایای کلیدی کامپوننت‌های سرور، توانایی واکشی مستقیم داده‌ها از داخل اجزای داخلی است async/await. می‌توانیم از این برای واکشی عکس‌ها از Unsplash در مؤلفه صفحه‌مان استفاده کنیم.

اما ابتدا باید کلاینت API خود را بر اساس Unsplash SDK رسمی ایجاد کنیم.

import {createApi} from 'unsplash-js';

export default createApi({
  accessKey: process.env.UNSPLASH_ACCESS_KEY
});

وقتی مشتری Unsplash API خود را داشتیم، می‌توانیم از آن در مؤلفه صفحه خود استفاده کنیم.

import {OrderBy} from 'unsplash-js';
import UnsplashApiClient from './UnsplashApiClient';

export default async function Index() {
  const topicSlug = 'street-photography';

  const [topicRequest, photosRequest] = await Promise.all([
    UnsplashApiClient.topics.get({topicIdOrSlug: topicSlug}),
    UnsplashApiClient.topics.getPhotos({
      topicIdOrSlug: topicSlug,
      perPage: 4
    })
  ]);

  return (
    <PhotoViewer
      coverPhoto={topicRequest.response.cover_photo}
      photos={photosRequest.response.results}
    />
  );
}

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

در این مرحله، برنامه ما یک شبکه عکس ساده را ارائه می دهد.

برنامه ای که یک شبکه عکس ساده را ارائه می دهد
(پیش نمایش بزرگ)

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

بیشتر بعد از پرش! ادامه مطلب زیر ↓

افزودن بین المللی سازی با next-intl

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

قالب بندی تاریخ ها

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

یک بار next-intl تنظیم شده است، می‌توانیم با استفاده از آن، قالب‌بندی را برطرف کنیم format.relativeTime عملکرد در مؤلفه ای که هر عکس را ارائه می دهد.

import {useFormatter} from 'next-intl';

export default function PhotoGridItem({photo}) {
  const format = useFormatter();
  const updatedAt = new Date(photo.updated_at);

  return (
    <a href={photo.links.html}>
        {/* ... */}
        <p>{format.relativeTime(updatedAt)}</p>
      </div>
    </a>
  );
}

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

زمان عکس برنامه با تاریخ قالب‌بندی شده
(پیش نمایش بزرگ)

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

هولا! 👋 ترجمه برنامه ما به اسپانیایی

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

import {useTranslations} from 'next-intl';

export default function PhotoViewer(/* ... */) {
  const t = useTranslations('PhotoViewer');

  return (
    <>
      <Header
        title={t('title')}
        description={t('description')}
      />
      {/* ... */}
    </>
  );
}

برای هر برچسب بین المللی که اضافه می کنیم، باید مطمئن شویم که یک ورودی مناسب برای همه زبان ها تنظیم شده است.

// en.json
{
  "PhotoViewer": {
    "title": "Street photography",
    "description": "Street photography captures real-life moments and human interactions in public places. It is a way to tell visual stories and freeze fleeting moments of time, turning the ordinary into the extraordinary."
  }
}
// es.json
{
  "PhotoViewer": {
    "title": "Street photography",
    "description": "La fotografía callejera capta momentos de la vida real y interacciones humanas en lugares públicos. Es una forma de contar historias visuales y congelar momentos fugaces del tiempo, convirtiendo lo ordinario en lo extraordinario."
  }
}

نکته: next-intl یک ادغام TypeScript را فراهم می کند که به شما کمک می کند مطمئن شوید که فقط به کلیدهای پیام معتبر ارجاع می دهید.

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

نسخه اسپانیایی برنامه
(پیش نمایش بزرگ)

تا اینجای کار خیلی خوبه!

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

به طور پیش فرض، Unsplash API محبوب ترین عکس ها را برمی گرداند. ما می خواهیم کاربر بتواند ابتدا ترتیب نمایش جدیدترین عکس ها را تغییر دهد.

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

آیا جایگزینی داریم؟ آره. و این قابلیتی است که برای قرن ها در وب وجود داشته است: پارامترهای جستجو (گاهی اوقات به عنوان پارامترهای پرس و جو). چیزی که پارامترهای جستجو را به یک گزینه عالی برای مورد استفاده ما تبدیل می کند این است که می توان آنها را در سمت سرور خواند.

بنابراین اجازه دهید جزء صفحه خود را برای دریافت تغییر دهیم searchParams از طریق وسایل

export default async function Index({searchParams}) {
  const orderBy = searchParams.orderBy || OrderBy.POPULAR;

  const [/* ... */, photosRequest] = await Promise.all([
    /* ... */,
    UnsplashApiClient.topics.getPhotos({orderBy, /* ... */})
  ]);

پس از این تغییر، کاربر می تواند به /?orderBy=latest برای تغییر ترتیب عکس های نمایش داده شده

برای اینکه کاربر به راحتی بتواند مقدار پارامتر جستجو را تغییر دهد، می‌خواهیم یک تصویر تعاملی ارائه کنیم. select عنصر از درون یک جزء

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

ما می توانیم جزء را با علامت گذاری کنیم 'use client'; برای پیوست کردن یک کنترل کننده رویداد و پردازش رویدادهای تغییر از select عنصر با این وجود، ما می خواهیم نگرانی های بین المللی سازی را در سمت سرور حفظ کنیم تا اندازه بسته نرم افزاری مشتری کاهش یابد.

بیایید به نشانه گذاری مورد نیاز برای ما نگاهی بیندازیم select عنصر

<select>
  <option value="popular">Popular</option>
  <option value="latest">Latest</option>
</select>

می توانیم این نشانه گذاری را به دو قسمت تقسیم کنیم:

  1. رندر کنید select عنصر با یک مؤلفه مشتری تعاملی.
  2. بین المللی شده را ارائه دهید option عناصر با یک کامپوننت سرور و ارسال آنها به عنوان children به select عنصر

بیایید پیاده سازی کنیم select عنصر برای سمت مشتری

'use client';

import {useRouter} from 'next-intl/client';

export default function OrderBySelect({orderBy, children}) {
  const router = useRouter();

  function onChange(event) {
    // The `useRouter` hook from `next-intl` automatically
    // considers a potential locale prefix of the pathname.
    router.replace('/?orderBy=' + event.target.value);
  }

  return (
    <select defaultValue={orderBy} onChange={onChange}>
      {children}
    </select>
  );
}

حالا بیایید از کامپوننت خود استفاده کنیم PhotoViewer و بومی سازی شده را ارائه دهید option عناصر به عنوان children.

import {useTranslations} from 'next-intl';
import OrderBySelect from './OrderBySelect';

export default function PhotoViewer({orderBy, /* ... */}) {
  const t = useTranslations('PhotoViewer');

  return (
    <>
      {/* ... */}
      <OrderBySelect orderBy={orderBy}>
        <option value="popular">{t('orderBy.popular')}</option>
        <option value="latest">{t('orderBy.latest')}</option>
      </OrderBySelect>
    </>
  );
}

با این الگو، نشانه گذاری برای option عناصر اکنون در سمت سرور تولید شده و به سرور ارسال می شود OrderBySelect، که رویداد تغییر را در سمت مشتری مدیریت می کند.

نکته: از آنجایی که هنگام تغییر سفارش باید منتظر بمانیم تا نشانه‌گذاری به‌روز شده در سمت سرور ایجاد شود، ممکن است بخواهیم وضعیت بارگیری را به کاربر نشان دهیم. React 18 معرفی شد را useTransition قلاب، که با اجزای سرور یکپارچه شده است. این به ما این امکان را می دهد که غیرفعال کنیم select عنصر در حالی که منتظر پاسخ از سرور است.

import {useRouter} from 'next-intl/client';
import {useTransition} from 'react';

export default function OrderBySelect({orderBy, children}) {
  const [isTransitioning, startTransition] = useTransition();
  const router = useRouter();

  function onChange(event) {
    startTransition(() => {
      router.replace('/?orderBy=' + event.target.value);
    });
  }

  return (
    <select disabled={isTransitioning} /* ... */>
      {children}
    </select>
  );
}

افزودن تعامل بیشتر: کنترل های صفحه

همان الگویی که برای تغییر ترتیب بررسی کردیم را می توان با معرفی a در کنترل های صفحه اعمال کرد page پارامتر جستجو

صفحه بندی برنامه
(پیش نمایش بزرگ)

توجه داشته باشید که زبان ها قوانین متفاوتی برای مدیریت جداکننده های اعشاری و هزار دارند. علاوه بر این، زبان‌ها اشکال مختلفی از کثرت‌سازی دارند: در حالی که انگلیسی فقط بین یک و صفر/چند عنصر تمایز دستوری قائل می‌شود، برای مثال، کرواتی یک شکل جداگانه برای عناصر «چند» دارد.

next-intl استفاده می کند نحو آی سی یو که بیان این ظرافت های زبانی را ممکن می سازد.

// en.json
{
  "Pagination": {
    "info": "Page {page, number} of {totalPages, number} ({totalElements, plural, =1 {one result} other {# results}} in total)",
    // ...
  }
}

این بار نیازی نیست که یک جزء را با آن علامت گذاری کنیم 'use client';. در عوض، ما می توانیم این را با تگ های لنگر معمولی پیاده سازی کنیم.

import {ArrowLeftIcon, ArrowRightIcon} from '@heroicons/react/24/solid';
import {Link, useTranslations} from 'next-intl';

export default function Pagination({pageInfo, orderBy}) {
  const t = useTranslations('Pagination');
  const totalPages = Math.ceil(pageInfo.totalElements / pageInfo.size);

  function getHref(page) {
    return {
      // Since we're using `Link` from next-intl, a potential locale
      // prefix of the pathname is automatically considered.
      pathname: '/',
      // Keep a potentially existing `orderBy` parameter. 
      query: {orderBy, page}
    };
  }

  return (
    <>
      {pageInfo.page > 1 && (
        <Link aria-label={t('prev')} href={getHref(pageInfo.page - 1)}>
          <ArrowLeftIcon />
        </Link>
      )}
      <p>{t('info', {...pageInfo, totalPages})}</p>
      {pageInfo.page < totalPages && (
        <Link aria-label={t('prev')} href={getHref(pageInfo.page + 1)}>
          <ArrowRightIcon />
        </Link>
      )}
    </>
  );
}

نتیجه

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

بین‌المللی‌سازی بخش مهمی از تجربه کاربر است، چه از چندین زبان پشتیبانی کنید و چه بخواهید از ظرافت‌های یک زبان به درستی استفاده کنید. یک کتابخانه مانند next-intl می تواند در هر دو مورد کمک کند.

پیاده‌سازی بین‌المللی‌سازی در برنامه‌های Next.js از لحاظ تاریخی با یک معاوضه عملکرد همراه بوده است، اما در مورد مؤلفه‌های سرور، دیگر اینطور نیست. با این حال، کاوش و یادگیری الگوهایی که به شما کمک می کند نگرانی های بین المللی خود را در سمت سرور حفظ کنید، ممکن است کمی طول بکشد.

در برنامه نمایشگر عکاسی خیابانی ما، فقط باید یک جزء را به سمت مشتری منتقل کنیم: OrderBySelect.

اجزای برنامه
(پیش نمایش بزرگ)

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

پارامترهای جستجو یک جایگزین عالی برای useState

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

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

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

البته توجه داشته باشید که وجود دارند معاوضه هایی که باید در نظر گرفته شوند:

  • مقادیر پارامترهای جستجو رشته‌ها هستند، بنابراین ممکن است لازم باشد انواع داده‌ها را سریال‌سازی کنید و سریال‌سازی کنید.
  • URL بخشی از رابط کاربری است، بنابراین استفاده از بسیاری از پارامترهای جستجو ممکن است بر خوانایی تأثیر بگذارد.

شما می توانید نگاهی به کامل داشته باشید کد نمونه در GitHub.

با تشکر فراوان از دلبا دی اولیویرا از Vercel برای ارائه بازخورد برای این مقاله!

مطالعه بیشتر در SmashingMag

سرمقاله Smashing
(yk, il)

Read More

راهنمای عملگرا برای تحقیقات ناب کاربر – مجله Smashing

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

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

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

میدونم به چی فکر میکنی:

من اجازه انجام تحقیق نخواهم داشت. به من می گویند که وقت نیست.»

پس بیایید از آنجا شروع کنیم.

تحقیقات کاربر ناب به جای اینکه هزینه کند در زمان صرفه جویی می کند

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

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

مقدار کمی از تحقیقات کاربر می تواند بسیاری از آن را حل کند. می تواند نظرات، بحث ها و تجدید نظرهای بی پایان را با داده ها جایگزین کند.

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

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

خوب، بله و نه.

در مورد تحقیقات اولیه چطور؟

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

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

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

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

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

در هر صورت،

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

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

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

نمونه سایت Jotjar با یک جلسه کاربر
تماشای جلسات کاربر می تواند روشنگر باشد. اما، همچنین بسیار وقت گیر است. (پیش نمایش بزرگ)

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

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

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

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

تحقیقات کاربر خود را سبک نگه دارید

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

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

بیشتر بعد از پرش! ادامه مطلب زیر ↓

بررسی های سریع و کثیف را اجرا کنید

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

  • مقایسه دو برچسب برای یک ثانیه در یک وب سایت.
  • شناسایی وظایفی که کاربران می خواستند در یک وب سایت انجام دهند.
  • کشف اینکه چرا مردم برای یک دوره آزمایشی رایگان ثبت نام نمی کنند.
  • ارزیابی اینکه آیا مردم یک اینفوگرافیک را درک می کنند یا خیر.

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

نمونه ای از نظرسنجی با هدف خروج در یک سایت
یک نظرسنجی ساده با هدف خروج می تواند به سرعت به سؤالی مانند اینکه چرا کاربران خرید نمی کنند پاسخ دهد. (پیش نمایش بزرگ)

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

تصویری از وب‌سایت Pollfish که می‌گوید «پاسخ‌های نظرسنجی را مستقیماً از منبع بخرید»
ابزارهای نظرسنجی مانند Pollfish در صورتی که زمان صبر نداشته باشید، جذب شرکت کنندگان را مدیریت می کنند. (پیش نمایش بزرگ)

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

هنگامی که سؤالات شما در مورد یک رویکرد طراحی است که تولید کرده اید، می توانید به آزمایش بدون تسهیل روی بیاورید.

برخی از تست‌های غیرمستقیم را امتحان کنید

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

  • آیا کاربران آن را دیدند؟
  • آیا کاربران آن را درک کردند؟
  • آیا مردم می توانند از آن استفاده کنند؟
  • آیا آنها آن را دوست خواهند داشت؟

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

آیا کاربران آن را دیدند؟

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

آیا کاربران آن را درک کردند؟

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

آیا مردم می توانند از آن استفاده کنند؟

وقتی صحبت از “آیا مردم می توانند از آن استفاده کنند؟” سوال شما دو گزینه دارید

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

  1. وظیفه ای را که برای کامل شدن افراد نیاز دارید تعریف کنید.
  2. مستقیم ترین مسیر را برای تکمیل کار به Maze ارائه دهید.
  3. URL Maze را به شرکت کنندگان بدهید.

Maze داده های جمع آوری شده ای را در مورد مدت زمانی که افراد برای تکمیل کار و تعداد اشتباهاتی که مرتکب شده اند به شما ارائه می دهد.

تصویری از وب سایت Maze با معیارهای خودکار
Maze داده‌های انبوهی را ارائه می‌دهد، بنابراین مجبور نیستید هر کاربر را کامل یک کار را تماشا کنید. (پیش نمایش بزرگ)

اگر نمونه اولیه ندارید، جایگزین این است که a تست اولین کلیک:

  1. به کاربران یک مدل از وب سایت یا برنامه خود نشان دهید.
  2. بپرسید که برای تکمیل یک کار خاص کجا کلیک کنند.

با توجه به الف مطالعه قابلیت استفاده توسط باب بیلی و کاری ولفسون، اگر اولین کلیک درست باشد، کاربران 87٪ شانس دارند که عملکرد را به درستی انجام دهند، در حالی که اگر کلیک اول اشتباه باشد فقط 46٪ است. بنابراین، اگر افراد اولین کلیک خود را درست انجام دهند، می توانید نسبتاً مطمئن باشید که می توانند کار را با موفقیت انجام دهند.

Usability Hub می تواند به شما کمک کند تست اولین کلیک خود را اجرا کنید. آنها یک نقشه حرارتی ارائه می دهند که نتایج انبوهی را از جایی که همه کلیک کرده اند نشان می دهد، بنابراین نیازی به تجزیه و تحلیل دستی نتایج ندارید. این به شما امکان می دهد تقریباً بلافاصله پاسخ ها را دریافت کنید.

نمونه Usability Hub با یک نقشه حرارتی
Usability Hub نتایج آزمایش با اولین کلیک را به عنوان یک نقشه حرارتی برای مرجع سریع ارائه می دهد. (پیش نمایش بزرگ)

آیا مردم آن را دوست خواهند داشت؟

سوال آخر این است که “آیا مردم آن را دوست خواهند داشت؟” پاسخ دادن به این امر آسان نیست، زیرا ذینفعان مختلف ممکن است نظرات متفاوتی در مورد آنچه کار می کند داشته باشند.

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

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

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

یک بررسی معنایی با عملکرد یک کلمه کلیدی
بررسی تفاضلی معنایی روشی عالی برای مشاهده عملکرد سایت شما در برابر کلمات کلیدی انتخابی شما است. (پیش نمایش بزرگ)

رویکرد عملگرایانه

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

این نوع تحقیقات کاربر ناب همچنین می تواند نقطه شروع خوبی برای کارهای بزرگتر باشد. اگر بتوانید حتی برخی تحقیقات کاربر را به این فرآیند اضافه کنید، ذینفعان می توانند مزایای آن را ببینند و این می تواند به چیزهای بزرگتری منجر شود.

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

مطالعه بیشتر در SmashingMag

سرمقاله Smashing
(yk, il)

Read More

نحوه ایجاد نمودارهای دینامیک دونات با TailwindCSS و React — مجله Smashing

CSS شگفت‌انگیز است – من مرتباً از پیشرفت آن در سال‌هایی که از آن استفاده می‌کنم شگفت‌زده می‌شوم (~2005 – اکنون). یکی از این شگفتی‌ها زمانی رخ داد که متوجه این توییت شدم شروتی بالاسا که نحوه ایجاد نمودار دایره ای با استفاده از conic-gradient().

این نسبتاً ساده است. در اینجا یک قطعه کد آمده است:

div {
  background: conic-gradient(red 36deg, orange 36deg 170deg, yellow 170deg);
  border-radius: 50%;
}

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

نمودارهای شیب مخروطی CSS با نمودارهای دونات و نمودار دایره ای
(پیش نمایش بزرگ)

روزهای خوش!

بریلز، فکر کردم می‌توانم از این به‌جای یک کتابخانه نمودار برای پروژه داشبورد داده‌ای که دارم روی آن کار می‌کنم استفاده کنم. CockroachDB Cloud API، اما من یک مشکل داشتم. من مقادیر نمودار خود را از قبل نمی دانستم و مقادیری که از API دریافت می کردم بر حسب درجه نبودند!

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

مقادیر دینامیک داده

در اینجا برخی از داده های نمونه از a معمول پاسخ API که من بر اساس آن مرتب کرده ام value.

const data = [
  {
    name: 'Cluster 1',
    value: 210,
  },
  {
    name: 'Cluster 2',
    value: 30,
  },
  {
    name: 'Cluster 3',
    value: 180,
  },
  {
    name: 'Cluster 4',
    value: 260,
  },
  {
    name: 'Cluster 5',
    value: 60,
  },
].sort((a, b) => a.value - b.value);

می بینید که هر آیتم در آرایه دارای یک است name و الف value.

به منظور تبدیل value از یک عدد به a deg ارزش مورد استفاده در CSS، چند کار وجود دارد که باید انجام دهید:

  • مقدار کل همه مقادیر را محاسبه کنید.
  • از مقدار کل برای محاسبه درصدی که هر مقدار نشان می دهد استفاده کنید.
  • درصد را به درجه تبدیل کنید.

توجه داشته باشید: کدی که در مراحل زیر به آن اشاره خواهم کرد را می توانید در مخزن اینجا پیدا کنید: /components/donut-1.js.

بیشتر بعد از پرش! ادامه مطلب زیر ↓

مجموع مبلغ را محاسبه کنید

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

const total_value = data.reduce((a, b) => a + b.value, 0);

// => 740

محاسبه درصد

حالا که شما یک total_value، می توانید هر یک از مقادیر آرایه داده را با استفاده از یک تابع جاوا اسکریپت به درصد تبدیل کنید. من این تابع را صدا زدم covertToPercent.

توجه داشته باشید: من در این مثال از مقدار 210 از Cluster 1 استفاده کرده ام.

const convertToPercent = (num) => Math.round((num / total_value) * 100);

// convertToPercent(210) => 28

تبدیل درصد به درجه

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

const convertToDegrees = (num) => Math.round((num / 100) * 360);

// convertToDegrees(28) => 101

نتیجه

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

const test_output = data.map((item) => {
  const percentage = convertToPercent(item.value);
  const degrees = convertToDegrees(percentage);

  return `${degrees}deg`;
});

// => ['14deg', '29deg', '86deg', '101deg', '126deg']

مقدار بازگشتی از test_output آرایه ای از value (در درجه) + رشته deg.

این یکی از مشکلات دو قسمتی را حل می کند. حالا قسمت دیگر مشکل را توضیح می دهم.

برای ایجاد نمودار دایره ای با استفاده از conic-gradient()، شما به دو مورد نیاز دارید deg ارزش های. اولی زاویه ای است که شیب باید از آنجا شروع شود و دومی زاویه ای است که گرادیان باید متوقف شود. شما همچنین به یک رنگ برای هر بخش نیاز دارید، اما من در یک لحظه به آن خواهم رسید.

 ['red 🤷 14deg', 'blue 🤷 29deg', 'green 🤷 86deg', 'orange 🤷 101deg', 'pink 🤷 126deg']

با استفاده از مقادیر از test_output، من فقط مقدار پایانی را دارم (جایی که گرادیان باید متوقف شود). زاویه شروع برای هر بخش در واقع زاویه پایانی از آیتم قبلی در آرایه است و زاویه پایانی مقدار تجمعی تمام مقادیر پایانی قبلی به اضافه مقدار پایان فعلی است. و برای بدتر شدن اوضاع، مقدار شروع برای اولین زاویه باید به صورت دستی تنظیم شود 0 🥴.

در اینجا یک نمودار برای توضیح بهتر معنی آن وجود دارد:

نموداری که یک تابع را توضیح می دهد
(پیش نمایش بزرگ)

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

"#...", 0, 14,
"#...",, 14, 43,
"#...",, 43, 130,
"#...",, 130, 234,
"#...",, 234, 360,

عملکردی که می تواند همه اینها را انجام دهد

و در اینجا تابعی است که واقعاً می تواند همه اینها را انجام دهد. استفاده می کند reduce() برای تکرار روی آرایه داده، جمع لازم را برای محاسبه زوایا انجام می‌دهد و مجموعه جدیدی از اعداد را برمی‌گرداند که می‌توان از آنها برای ایجاد زوایای شروع و پایان صحیح برای استفاده در نمودار استفاده کرد.

const total_value = data.reduce((a, b) => a + b.value, 0);
const convertToPercent = (num) => Math.round((num / total_value) * 100);
const convertToDegrees = (num) => Math.round((num / 100) * 360);

const css_string = data
  .reduce((items, item, index, array) => {
    items.push(item);

    item.count = item.count || 0;
    item.count += array[index - 1]?.count || item.count;
    item.start_value = array[index - 1]?.count ? array[index - 1].count : 0;
    item.end_value = item.count += item.value;
    item.start_percent = convertToPercent(item.start_value);
    item.end_percent = convertToPercent(item.end_value);
    item.start_degrees = convertToDegrees(item.start_percent);
    item.end_degrees = convertToDegrees(item.end_percent);

    return items;
  }, [])
  .map((chart) => {
    const { color, start_degrees, end_degrees } = chart;
    return ` ${color} ${start_degrees}deg ${end_degrees}deg`;
  })
  .join();

من عمداً این را بسیار پرمخاطب گذاشته‌ام، بنابراین اضافه کردن آن آسان‌تر است console.log(). زمانی که این تابع را توسعه می‌دادم، متوجه شدم که این بسیار مفید است.

ممکن است متوجه موارد اضافی شوید map زنجیر شده تا انتهای reduce. با استفاده از a map من می توانم مقادیر بازگشتی را تغییر دهم و روی آن تثبیت کنم deg، سپس همه آنها را با هم به عنوان یک آرایه از رشته ها برگردانید.

استفاده كردن join درست در انتها آرایه را به یک واحد تبدیل می کند css_string، که می توان با آن استفاده کرد conic-gradient() 😅

"#..." 0deg 14deg,
"#..." 14deg 43deg,
"#..." 43deg 130deg,
"#..." 130deg 234deg,
"#..." 234deg 360deg

با استفاده از css_string با یک SVG foreignObject

الان متاسفانه نمیتونی استفاده کنی conic-gradient() با SVG. اما می توانید یک عنصر HTML را در داخل a قرار دهید foreignObject و سبک background با استفاده از a conic-gradient().

<svg viewBox='0 0 100 100' xmlns="http://www.w3.org/2000/svg" style={{ borderRadius: '100%' }}>
  <foreignObject x='0' y='0' width="100" height="100">
    <div
      xmlns="http://www.w3.org/1999/xhtml"
      style={{
        width: '100%',
        height: '100%',
        background: `conic-gradient(${css_string})`, // <- 🥳
      }}
    />
  </foreignObject>
</svg>

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

بیایید در مورد سوراخ صحبت کنیم

واقعاً تنها یک راه وجود دارد که می‌توانید از وسط نمودار دایره «ماسک» کنید تا پس‌زمینه را آشکار کنید. این رویکرد شامل استفاده از a clipPath. این رویکرد شبیه قطعه کد زیر است. من از این برای Donut 1 استفاده کردم.

توجه داشته باشید: را src برای Donut 1 را می توان در اینجا مشاهده کرد: components/donut-1.js.

<svg viewBox='0 0 100 100' xmlns="http://www.w3.org/2000/svg" style={{ borderRadius: '100%' }}>

  <clipPath id='hole'>
    <path d='M 50 0 a 50 50 0 0 1 0 100 50 50 0 0 1 0 -100 v 18 a 2 2 0 0 0 0 64 2 2 0 0 0 0 -64' />
  </clipPath>

  <foreignObject x='0' y='0' width="100" height="100" clipPath="url(#hole)">
    <div
      xmlns="http://www.w3.org/1999/xhtml"
      style={{
        width: '100%',
        height: '100%',
        background: `conic-gradient(${css_string})`
      }}
    />
  </foreignObject>
</svg>

با این حال، راه دیگری وجود دارد. این رویکرد شامل استفاده از a <circle /> عنصر و قرار دادن آن در مرکز نمودار دایره ای. این کار خواهد کرد اگر پر از <circle /> با رنگ پس‌زمینه هر چیزی که نمودار روی آن قرار می‌گیرد مطابقت دارد. در مثالم، من از یک پس‌زمینه الگو استفاده کرده‌ام، و اگر به Donut 3 دقت کنید متوجه خواهید شد که نمی‌توانید آن را ببینید. الگوی حباب از مرکز نمودار

توجه داشته باشید: را src برای Donut 3 را می توانید در اینجا ببینید: components/donut-3.js.

<svg viewBox='0 0 100 100' xmlns="http://www.w3.org/2000/svg" style={{ borderRadius: '100%' }}>
  <foreignObject x='0' y='0' width="100" height="100">
    <div
      xmlns="http://www.w3.org/1999/xhtml"
      style={{
        width: '100%',
        height: '100%',
        background: `conic-gradient(${css_string})`
      }}
    />
  </foreignObject>
  <circle cx='50' cy='50' r="32" fill="white" />
</svg>

IMO clipPath روش زیباتر است، اما اگر به چیزی مانند Figma یا Illustrator دسترسی ندارید، اصلاح نقاط مسیر برای به دست آوردن ضخامت مورد نظر سوراخ می تواند دشوارتر باشد.

بالاخره رنگ ها!

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

در سایت نمونه خود، من از آن استفاده می کنم باد دم به سبک “همه چیزها” و با استفاده از این ترفند، من می توانم متغیرهای CSS را در معرض نمایش قرار دهم تا بتوان با نام آنها به آنها اشاره کرد.

اگر می خواهید همین کار را انجام دهید، می توانید یک را اضافه کنید color کلید آرایه داده:

data={[
  {
    name: 'Cluster 1',
    value: 210,
    color: 'var(--color-fuchsia-400)',
  },
  {
    name: 'Cluster 2',
    value: 30,
    color: 'var(--color-fuchsia-100)',
  },
  {
    name: 'Cluster 3',
    value: 180,
    color: 'var(--color-fuchsia-300)',
  },
  {
    name: 'Cluster 4',
    value: 260,
    color: 'var(--color-fuchsia-500)',
  },
  {
    name: 'Cluster 5',
    value: 60,
    color: 'var(--color-fuchsia-200)',
  },
].sort((a, b) => a.value - b.value)

و سپس به color کلید در آرایه map تا آن را به عنوان بخشی از css_string. من از این روش در Donut 2 استفاده کرده ام.

توجه داشته باشید: می توانی ببینی src برای دونات 2 اینجا: components/donut-2.js.

.map((chart) => {
  const { color, start_degrees, end_degrees } = chart;
  return ` ${color} ${start_degrees}deg ${end_degrees}deg`;
})
.join();

شما حتی می توانید به صورت پویا نام رنگ را با استفاده از یک مقدار رمزگذاری شده ایجاد کنید (color-pink-) + the index از آرایه من از این روش در Donut 1 استفاده کرده ام.

توجه داشته باشید: می توانی ببینی src برای دونات 1 اینجا: components/donut-1.js.

.map((chart, index) => {
  const { start_degrees, end_degrees } = chart;
  return ` var(--color-pink-${(index + 1) * 100}) ${start_degrees}deg ${end_degrees}deg`;
})
.join();

اگر خوش شانس باشی!

با این حال، ممکن است خوش شانس باشید و با یک API کار کنید که در واقع مقادیر را با یک رنگ مرتبط برمی گرداند. این مورد در مورد است GitHub GraphQL API. بنابراین. آخرین نمونه را با هم جمع کردم.

GitHub GraphQL API با نمودار Github با ده زبان مختلف مرتبط با رنگ خود
(پیش نمایش بزرگ)

با مراجعه به این سایت می توانید این کار را در مرورگر خود مشاهده کنید /github، و src هم برای نمودار دونات GitHub و هم Legend را می توانید در اینجا پیدا کنید:

بسته بندی

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

من قبلاً یک بار با ایجاد نمودارهای Donut با استفاده از SVG و stroke-dashoffset. شما می توانید در مورد آن در مقاله من بخوانید، “یک نمودار دونات SVG از ابتدا برای وبلاگ گتسبی خود ایجاد کنید” این رویکرد واقعاً خوب کار کرد، اما فکر می‌کنم رویکردی را که در این پست توضیح داده شده ترجیح می‌دهم. CSS به سادگی بهترین است!

اگر می‌خواهید درباره هر یک از روش‌هایی که من در اینجا استفاده کرده‌ام بحث کنید، لطفاً مرا در توییتر پیدا کنید: @PaulieScanlon.

شما را در سراسر اینترنت می بینم!

سرمقاله Smashing
(yk, il)

Read More

Meet Penpot، یک پلتفرم طراحی منبع باز ساخته شده برای طراحان و توسعه دهندگان یکسان — مجله Smashing

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

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

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

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

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

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

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

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

معنای آن در عمل نه تنها سازگاری بهتر با فناوری های وب بلکه برابری طبیعی بین طرح ها و کدها است. با Penpot، شما مجبور نیستید صادرات به SVG، گرافیک شما SVG هستند، طبق تعریف

همین کار با ترجمه سبک ها از طرح ها به کد انجام می شود. Penpot نیازی به تولید هیچ مقدار CSS ندارد. فقط می تواند مقادیر CSS را مستقیماً از طرح ها بخواند و برآورده کند.

یک مثال عالی از آن در عمل Flex Layout است، یعنی ویژگی طرح بندی Penpot که نه تنها دقیقاً مانند CSS Flexbox کار می کند. این به سادگی CSS Flexbox است. در قسمت بعدی مقاله با هم آن را بررسی خواهیم کرد!

منبع باز و چرا باید به شما اهمیت دهد

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

این بدان معنی است که رایگان است

در دنیای برنامه نویسی، منبع باز معمولاً به این معنی است که کد منبع ابزار، برنامه یا چارچوب برای مشاهده، تغییر و توزیع برای هر کسی در دسترس است. اما چرا این برای شما و انتخاب یک ابزار طراحی مهم است؟

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

این به معنای امنیت و کنترل بهتر است

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

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

این به معنای سفارشی سازی بی پایان است

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

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

این بدان معنی است که شما می توانید آن را خودتان اجرا کنید

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

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

امیدوارم که تا به حال شکی در مورد مزایایی که برای کار با ابزارهای منبع باز به همراه دارد، نداشته باشید. حالا بیایید نگاهی به خود Penpot بیندازیم.

جایی که Penpot می درخشد…

اگر اخیراً با یکی از محبوب ترین ابزارهای طراحی Penpot کار کرده اید، احساس خوبی در خانه خواهید داشت. رابط کاربری آن باید آشنا و قابل پیش بینی باشد و همچنین تمام ویژگی های اساسی را که می توانید به دنبال آن هستید ارائه دهد.

رابط کاربری محجوب است، عملکرد درک شده خوب است و همه چیز همانطور که انتظار می رود کار می کند. اما این ویژگی های مربوط به دستیابی است که Penpot واقعاً می درخشد.

قبلاً به Flex Layout، ویژگی چیدمان خود Penpot اشاره کردم. اگر تا به حال از مدل Flexbox در CSS استفاده کرده باشید، ممکن است به طرز عجیبی آشنا به نظر برسد. در واقع، دقیقاً همین است: CSS flexbox در داخل یک برنامه طراحی.

و این بدان معناست که نه تنها برابری بهتری با کد نسبت به سایر برنامه های طراحی (حداقل تا زمانی که قصد دارید از CSS flexbox در کد خود استفاده کنید) بلکه به معنای دامنه بهتری از امکانات در داخل خود ابزار طراحی است (مثلاً می توانید مواردی از طرح بندی خودکار در چندین ردیف).

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

نقطه های شکست مختلف Penpot
(پیش نمایش بزرگ)

اگر تب عالی Inspect نبود، همه اینها به خوبی نبود. Penpot تمام CSS هایی را که ممکن است در دسترس داشته باشید و همچنین کد منبع SVG هر جزء را که انتخاب می کنید در اختیار شما قرار می دهد.

بسیار تمیز!

…و جایی که نیست (هنوز)

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

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

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

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

با دیدن کارهایی که Penpot امروز می‌تواند انجام دهد، من شخصاً نمی‌توانم منتظر بمانم تا ببینم بعدی چه خواهد بود.

به عنوان مثال، با نگاهی به اجرای Penpot از Flex Layout، فکر کنید چقدر جالب است که یک ابزار مشابه برای CSS Grid داشته باشید. چه کسی در مکانی بهتر از Penpot برای ساخت آن است؟ هشدار اسپویلر: اگر به آنها نگاه کنید نقشه راه عمومی به اندازه کافی از نزدیک، متوجه خواهید شد که آنها از قبل روی آن کار می کنند.

افکار نهایی

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

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

اگر می‌خواهید Penpot را امتحان کنید، اکنون نسخه بتا تمام شده و برای شما و تیمتان در دسترس است — کاملا رایگان

منابع

سرمقاله Smashing
(il)
Read More

با SmashingConf Antwerp 2023 آشنا شوید 🇧🇪 — مجله Smashing

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

آستین ها را بالا بزنید و ملاقات کنید SmashingConf Antwerp 🇧🇪، کنفرانس جدید درخشان ما برای طراحان و مهندسان رابط کاربری کسانی که عاشق طراحی، UX و وب هستند. بر سیستم های طراحی، قابلیت استفاده، طراحی محصول، دسترسی و رابط های کاربری پیچیده. 1 آهنگ، 2 روز، 4 کارگاه آموزشی تمام روز، رمز و راز و شبکه دوستانه. یک جواهر جدید درخشان در قلب بلژیک – سرزمین شکلات های باورنکردنی، وافل و سیب زمینی سرخ کرده واقعی بلژیکی! 🍫 🧇 🍟 🍺

SmashingConf Antwerp 2023

آه، شاید شما مدیر نیاز به کمی قانع کردن دارد? ما پشت شما را گرفته ایم! PDF رئیس خود را متقاعد کنید تا کفه ترازو را به نفع شما برگرداند. و ما یک “نامه به رئیس” قالب برای شما نیز هست. موفق باشید! 🤞🤞🏼🤞🏾

چه چیزی باید انتظار داشته باشید؟

SmashingConfs همیشه درباره نحوه کار، شکست و موفقیت ما بوده است. ما سخنرانان را تشویق می کنیم که به اشتراک بگذارند درس های آموخته شده و نحوه کار آنها را نشان دهند. از نشستن بلندگوها و نمایش روند طراحی خود، یا راه اندازی یک برد Figma و طراحی زنده با مخاطب بررسی کنید SmashingConfs چگونه است (+ ویدئو).

تئاتر بورلا
ماجراجویی جدید ما: SmashingConf در فضای باشکوه اتفاق خواهد افتاد تئاتر بورلا در قلب تاریخی آنتورپ، بلژیک در 9 تا 11 اکتبر 2023.

انتظار گفتگوهای تصویری بزرگ یا مفاهیم انتزاعی نداشته باشید – کنفرانس های Smashing همیشه هستند صادق، عملی و پرشور. سخنرانان نیز بسیار قابل دسترس هستند و زمان کافی برای شما وجود دارد که بتوانید تمام سوالات خود را بپرسید و همه پاسخ ها را در مکالمات 1:1 یا در میزهای گرد دریافت کنید.

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

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

تئاتر بورلا
یعنی بورلا، مکانی باشکوه در قلب تاریخی آنتورپ، بلژیک. (پیش نمایش بزرگ)

ما انتخاب نمی کنیم مکان های برگزاری به طور تصادفی یا ما تضاد مکان های تاریخی زیبا و هنر دیجیتال را دوست داریم. بنابراین برای آنتورپ، ما انتخاب کردیم بورلا شووبرگ، یک تئاتر نئوکلاسیک فراموش نشدنی در قلب آنتورپ، در دهه 1820 با دقت طراحی و ساخته شد و با مجسمه های آپولو و نه موز تزئین شده است (برای اینکه خلاقیت شما جاری شود!). این تئاتر بورلا خانه شما برای هر دو روز کنفرانس خواهد بود.

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

برای طراحان و مهندسان UI

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

SmashingConf Antwerp 2023
همه کارگاه ها عملی و کاربردی هستند، بنابراین می توانید مهارت های جدید خود را فوراً اعمال کنید.

شیرجه خواهیم زد:

  • سیستم های طراحی،
  • الگوهای طراحی،
  • قابلیت استفاده و تحقیقات UX،
  • طراحی محصول و گردش کار،
  • UX سازمانی و رابط های کاربری پیچیده،
  • طراحی فراگیر و دسترسی،
  • تکنیک های جدید طراحی (در فیگما، میرو و غیره)،
  • طراحی پایدار و سازگار با سن،
  • نوشتن تجربه کاربری

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

بلیط تیم؟ 👫👭

کل تیم را به SmashingConf بیاوریدو مقداری از بودجه آموزشی خود را نیز در طول مسیر ذخیره کنید. با ما بلیط بسته های دوستانه و تخفیف تیم، ما پشت شما را گرفته ایم! اگر می خواهید با یک تیم بزرگ بیایید یا به چیز خاصی علاقه مند هستید، لطفا یک ایمیل کوتاه برای ما ارسال کنید و ما فوراً با شما تماس خواهیم گرفت!

ما نمی توانیم برای دیدن شما صبر کنیم!

همانطور که ما برای این رویداد آماده می شویم، نمی توانیم بیشتر از این هیجان زده باشیم که شما را در آنتورپ ملاقات کنیم. بیایید مهارت های طراحی و UX خود را با هم تقویت کنیم و خلق کنیم تجربیات به یاد ماندنی که برای مدتی ادامه خواهد داشت ❤️

SmashingConf Antwerp 2023
سرمقاله Smashing
(cm, il)
Read More

بین المللی سازی (i18n) درست با ریمیکس و CMS بدون سر – مجله Smashing

هنوز در قرن بیست و یکم چقدر مانع زبانی وجود دارد؟ شما به عنوان خواننده احتمالاً با زبان انگلیسی آشنایی کامل دارید، اما دیگران چطور؟

امروزه اغلب ما اهمیت دسترسی، عملکرد بهتر و UX یا DX بهتر را شنیده ایم. ممکن است درباره i18n در مقایسه با این موضوعات نشنیده باشید یا اغلب آن را نبینید. اما اگر حقایق و اعداد را از آمار مشاهده کنید، ممکن است نتایج شگفت انگیزی در مورد i18n و تأثیر آن پیدا کنید. بیایید با هم در مورد آن پی ببریم.

i18n و l10n

قبل از بررسی تاثیر i18n، بیایید تفاوت بین این دو اصطلاح را بیاموزیم.

  • i18n
    i18n مخفف بین المللی سازی است. بین اولین کاراکتر “i” و آخرین کاراکتر “n” از این کلمه، 18 کاراکتر وجود دارد. i18n پیاده‌سازی ساختارها و ویژگی‌های برنامه‌های شما را توضیح می‌دهد تا آماده بومی‌سازی محتوا باشند.
  • l10n
    l10n مخفف محلی سازی است. بین اولین کاراکتر “l” و آخرین کاراکتر “n” از این کلمه، ده کاراکتر وجود دارد. l10n به معنای ترجمه محتوا به زبان برای کاربرانی است که از مناطق خاصی به آن دسترسی دارند.

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

چرا i18n اینقدر اهمیت دارد؟

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

  • 5.07 میلیارد
  • 25.9٪
  • 74.1٪
  • چین
  • آسیا

اولین واقعیت تعداد زیادی از اعداد را نشان می دهد. 5.07 میلیارد تعداد کاربران این جهان در سال 2020 است. جمعیت جهان در سال 2021 7.837 میلیارد نفر بوده است، نزدیک به 8 میلیارد. بیش از نیمی از جمعیت جهان به محتوای اینترنت و اپلیکیشن ها دسترسی دارند.

بر اساس تعداد کاربران این دنیا، تحقیق دیگری در مورد رایج ترین زبان های مورد استفاده در اینترنت وجود دارد. با نگاهی به نمودار، اکثر ما به بالاترین عدد در این نمودار توجه می کنیم: 25.9٪، انگلیسی.

رایج ترین زبان های مورد استفاده در اینترنت از ژانویه 2020، بر اساس سهم کاربران اینترنت
(منبع تصویر: Statista) (پیش نمایش بزرگ)

دومین زبان بقیه با 23.1 درصد بالاترین. همچنین فرض کنید بقیه درصد را به جز انگلیسی جمع آوری کنید. در این صورت، ممکن است متوجه شوید که از بیش از 5 میلیارد کاربر، 74.1٪ از کاربران به محتوا به هر زبان دیگری دسترسی دارند.

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

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

چگونه i18n در یک سطح پایه کار می کند

صرف نظر از فناوری پیاده سازی i18n، سه راه برای تعیین زبان ها و مناطق وجود دارد.

  1. محل آدرس IP
  2. پذیرش-زبان سرتیتر/Navigator.languages
  3. شناسه ها در URL ها

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

استفاده كردن پذیرش-زبان سرصفحه یا Navigator.languages یکی دیگر از روش های ممکن برای پیاده سازی i18n است. با این حال، این رویکرد اطلاعات زبان را ارائه می دهد اما اطلاعات منطقه ای را ارائه نمی دهد.

i18n فقط برای بومی سازی محتوا نیست. این شامل بهبود UX نیز می شود. به عنوان مثال، ایجاد شناسه در URL ها UX را افزایش می دهد. همچنین به تقسیم محتوای محلی به سیستم اختصاصی کمک می کند. ما چگونگی پیاده سازی چنین سیستمی را در ” توضیح خواهیم داد.ترکیبی از ریمیکس و CMS” بخش.

به طور معمول، شناسه ها در URL ها در سه الگوی مختلف وجود دارند:

  1. تمایز بر اساس دامنه (به عنوان مثال hello.es، hello.jp)
  2. پارامترهای URL (به عنوان مثال hello.com?loc=de)
  3. دایرکتوری های فرعی محلی شده (به عنوان مثال hello.com/es، hello.com/ja)

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

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

کتابخانه ها

برای اینکه هر زمان که می‌خواهیم i18n را در پروژه‌های خود پیاده‌سازی کنیم، چرخ را دوباره اختراع نکنیم، توسعه‌دهندگان کتابخانه‌ها، ابزارها و سرویس‌های مختلفی دارند که می‌توان از آنها برای تسهیل کار استفاده کرد. اگر با چارچوب‌های React یا React کار می‌کنیم، گزینه‌های مختلفی در دسترس داریم. بیایید در مورد برخی از آنها صحبت کنیم.

Format.js

Format.js مجموعه‌ای مدولار از کتابخانه‌های جاوا اسکریپت است که می‌توانیم از آن برای پیاده‌سازی منطق i18n در کلاینت و سرور استفاده کنیم. این گروه از کتابخانه ها بر قالب بندی اعداد، تاریخ ها و رشته ها متمرکز هستند. این قابلیت ها و ابزارهای مختلفی را ارائه می دهد و در مرورگر و همچنین در زمان اجرا Node.js اجرا می شود. با فریمورک های مختلفی مانند Vue و React ادغام می شود تا بتوانیم از قابلیت های آن در پروژه های Remix خود استفاده کنیم. می توانید در مورد آن بیشتر بخوانید اسناد رسمی React Intl.

i18 بعدی

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

در مورد ریمیکس چطور؟

هنگام ایجاد یک وب سایت با استفاده از Remix، ما باید گزینه های مختلفی را در نظر بگیریم. از آنجایی که این یک چارچوب مبتنی بر React است، می‌توانیم از هر یک از کتابخانه‌های ذکر شده قبلی استفاده کنیم. با این حال، ما دو رویکرد را بررسی خواهیم کرد که می توانند در پروژه های Remix شما بهتر جا بیفتند. ابتدا، نحوه بومی سازی محتوا را با استفاده از remix-i18next، یک کتابخانه خاص Remix برای i18n خواهیم دید. دوم، ما از یک سیستم مدیریت محتوای بدون سر به عنوان منبع زبان/محل های مختلف محتوای خود استفاده خواهیم کرد.

remix-i18next

بر اساس i18next، سرجیو زالامبری، یکی از مشارکت کنندگان اصلی ریمیکس، ایجاد شد remix-i18next. این کتابخانه ویژگی ها و ماژول های مشابه کتابخانه جاوا اسکریپت را ارائه می دهد اما بر مفاهیم و رویکردهای Remix تمرکز دارد. راه اندازی و استفاده آسان، آماده تولید، و بدون هیچ نیاز یا وابستگی. بیایید نگاهی دقیق‌تر به نحوه پیاده‌سازی i18n در پروژه‌های Remix با استفاده از remix-i18next داشته باشیم.

اول از همه، باید چند بسته npm را نصب کنیم:

npm install remix-i18next i18next react-i18next i18next-browser-languagedetector i18next-http-backend i18next-fs-backend

همه آنها به ما کمک می کنند i18n را هم در سمت سرور و هم در سمت مشتری وب سایت خود مدیریت کنیم. ما همچنین از آنها برای راه اندازی backend خود و تعریف منطقی که زبان کاربر را تشخیص می دهد استفاده خواهیم کرد.

اکنون، باید تنظیماتی را اضافه کنیم که در سرتاسر وب سایت هم از سمت کلاینت و هم از سمت سرور استفاده می شود. بیایید چند فایل JSON با ترجمه رشته های کاراکترهای مختلف که در وب سایت خود استفاده خواهیم کرد ایجاد کنیم:

{
  "intro": "Hello everyone!"
}
{
  "intro": "Hola a todos!"
}

با نام گذاری فایل ها به “common.json”، فضای نام رشته ها را تعریف می کنیم که ما در آنها لیست خواهیم کرد.

حالا بیایید یک فایل به نام بسازیم i18n.js. این فایل حاوی تنظیمات پیکربندی مختلفی است که ما در لحظه شروع به کار سرور i18n خود از آنها استفاده خواهیم کرد.

export default {
  supportedLngs: ["en", "es"],
  fallbackLng: "en",
  defaultNS: "common",
  // Disabling suspense is recommended
  react: { useSuspense: false },
};

می توانید گزینه های پیکربندی بیشتری را در قسمت مشاهده کنید اسناد رسمی i18next.

حال، فایل را ایجاد کنید i18next.server.js، که حاوی منطقی است که در آن استفاده خواهد شد entry.server.jsx فایل پروژه ریمیکس ما

import Backend from "i18next-fs-backend";
    import { resolve } from "node:path";
    import { RemixI18Next } from "remix-i18next";
    import i18n from "~/i18n"; // The configuration file we created
    
    let i18next = new RemixI18Next({
      detection: {
        supportedLanguages: i18n.supportedLngs,
        fallbackLanguage: i18n.fallbackLng,
      },
      i18next: {
        ...i18n,
        backend: {
          loadPath: resolve('./public/locales/{{lng}}/{{ns}}.json'),
        },
      },
      backend: Backend,
    });
    
    export default i18next;

ما اساساً در حال راه اندازی یک سرور جدید i18n هستیم که با باطن Remix ما اجرا می شود. ما محل فایل‌های JSON حاوی ترجمه‌های مورد استفاده را مشخص می‌کنیم. بیایید این ویژگی ها را به فایل های پیکربندی Remix اصلی خود اضافه کنیم. ابتدا مقداری منطق اضافه می کنیم تا بتوانیم سمت مشتری محتوا را ترجمه کنیم. برای انجام این کار، اجازه دهید فایل «entry.client.jsx» خود را ویرایش کنیم:

import i18next from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import Backend from "i18next-http-backend";
import { I18nextProvider, initReactI18next } from "react-i18next";
import { getInitialNamespaces } from "remix-i18next";
import i18n from "./i18n"; // The configuration file we created

i18next
  .use(initReactI18next)
  .use(LanguageDetector)
  .use(Backend)
  .init({
    ...i18n, // The same config we created for the server
    ns: getInitialNamespaces(),
    backend: {
      loadPath: "/locales/{{lng}}/{{ns}}.json",
    },
    detection: {
      order: ["htmlTag"],
      caches: [],
    },
  })
  .then(() => {
    // After i18next init, hydrate the app
    hydrateRoot(
      document,
      // Wrap RemixBrowser in I18nextProvider
      <I18nextProvider i18n={i18next}>
        <RemixBrowser />
      </I18nextProvider>
    );
  });

ما باید منتظر بمانیم تا مطمئن شویم ترجمه‌ها قبل از هیدراتاسیون بارگیری می‌شوند تا برنامه وب خود را تعاملی نگه داریم.

بیایید منطق را به آن اضافه کنیم entry.server.jsx اکنون فایل کنید:

import { createInstance } from "i18next";
import Backend from "i18next-fs-backend";
import { resolve } from "node:path";
import { I18nextProvider, initReactI18next } from "react-i18next";
import i18next from "./i18next.server"; // The backend file we created
import i18n from "./i18n"; // The configuration file we created

...

export default async function handleRequest(
...
) {
  // We create a new instance of i18next
  let instance = createInstance();

  // We can detect the specific locale from each request
  let lng = await i18next.getLocale(request);
  // The namespaces the routes about to render wants to use
  let ns = i18next.getRouteNamespaces(remixContext);

  await instance
    .use(initReactI18next)
    .use(Backend)
    .init({
      ...i18n,// The config we created
      lng, // The locale we detected from the request
      ns,
      backend: {
        loadPath: resolve("./public/locales/{{lng}}/{{ns}}.json"),
      },
    });

  return new Promise((resolve, reject) => {
    ...

    let { pipe, abort } = renderToPipeableStream(
      
        {" "}
      ,
      ...
    );
    ...
  });
}

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

اکنون می‌توانیم با استفاده از قابلیت‌های ارائه‌شده توسط remix-i18next برای شناسایی موقعیت کاربر و ارائه محتوای ترجمه‌شده بر اساس آن، شروع کنیم. بیایید ویرایش کنیم root.jsx فایل:

...

import { json } from "@remix-run/node";
import { useChangeLanguage } from "remix-i18next";
import { useTranslation } from "react-i18next";
import i18next from "~/i18next.server";

...

export let loader = async ({ request }) => {
  let locale = await i18next.getLocale(request);
  return json({ locale });
};

export let handle = {
  i18n: "common",
};

export default function App() {
  // Get the locale from the loader
  let { locale } = useLoaderData();
  let { i18n } = useTranslation();

  useChangeLanguage(locale);

  return (
    <html lang={locale} dir={i18n.dir()}>
      ...
    </html>
  );
}

این useChangeLanguage hook زبان نمونه را به محلی شناسایی شده توسط لودر تغییر می دهد. هر زمان که کاری برای تغییر زبان انجام دهیم، این زبان تغییر می‌کند و i18next ترجمه‌های صحیح را بارگیری می‌کند.

اکنون، ما می توانیم محتوا را در هر مسیری ترجمه کنیم:

import { useTranslation } from "react-i18next";

export default function MyPage() {
  let { t } = useTranslation();
  return <h1>{t("intro")}</h1>;
}

ما استفاده می کنیم t() تابعی برای نمایش رشته های ترجمه شده بر اساس لیست پیام هایی که در فایل های JSON خود تعریف کرده ایم.

در این مثال، ما از یک فضای نام پیش‌فرض استفاده می‌کنیم، اما اگر بخواهیم می‌توانیم چندین فضای نام را تنظیم کنیم. می توانید در مورد آن بیشتر بخوانید t() عملکرد در اسناد رسمی i18next.

در صورتی که بخواهیم سمت سرور محتوا را ترجمه کنیم، می توانیم از آن استفاده کنیم getFixedT روش داخل لودرها و اقدامات ما:

import i18next from "~/i18next.server";

...

export let loader = async ({ request }) => {
  let t = await i18next.getFixedT(request);
  let title = t("intro");
  return json({ title });
};

ترکیبی از ریمیکس و CMS

با هم، گزینه های موجود برای پیاده سازی i18n با Remix را بررسی کردیم. در ابتدای این مقاله، متوجه شدیم که i18n می‌تواند منجر به بهبود بسیار زیاد UX و SEOUX و SEO شود. به عنوان بخشی از UX، گنجاندن DX بهتر نیز مهم است.

رویکرد بالا فایل های ترجمه را در سطح کد منبع ایجاد می کند. همچنین، منطق پیاده سازی شناسه ها در URL ها را نداریم. برای رسیدن به این هدف، بیایید به رویکرد یکپارچه سازی CMS نگاه کنیم. در این مقاله، از Storyblok استفاده خواهیم کرد، که سه رویکرد متفاوت برای بومی‌سازی محتوا و دسته‌ها برای تعیین زبان‌ها و مناطق ارائه می‌دهد.

توجه داشته باشید: اگر می خواهید بین برنامه Remix خود و Storyblok ارتباط برقرار کنید، وجود دارد یک آموزش 5 دقیقه ای که نحوه انجام آن را توضیح می دهد.

پس از آن، با استفاده از این لینک جادویی می توانید به سرعت یک فضای شروع را کلون کنید تا تمام اجزا و انواع فیلدهای لازم را داشته باشید. این فضای مثال رویکردی به نام ترجمه در سطح پوشه را پوشش می دهد. در بخش بعدی به آن خواهیم پرداخت.
https://app.storyblok.com/#!/build/181387

بین سه رویکرد انتخاب کنید

Storyblok سه راه برای ایجاد طرح بندی برای ذخیره محتوای محلی و تعیین زبان ها و مناطق دارد.

  1. ترجمه در سطح پوشه: محتوای محلی شده را در سطح پوشه تقسیم کنید.
  2. ترجمه در سطح زمینه: ترجمه در سطح نوع زمینه.
  3. ترجمه در سطح فضا: فضاها (محیط ها یا مخازن) را به محتوای محلی خاص اختصاص دهید.

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

ترجمه سطح پوشه
(پیش نمایش بزرگ)

همچنین، شناسه ها را می توان از تنظیمات پوشه از طریق Slug تغییر داد.

تنظیمات پوشه
(پیش نمایش بزرگ)

با تغییر Slug از صفحه تنظیمات پوشه، این شناسه محلی سازی شده در URL در تمام داستان های داخل این پوشه ژاپنی ظاهر می شود. به عنوان مثال، صفحه about در داخل پوشه ژاپنی قبلاً یک شناسه محلی در URL دارد.

تیزر عمومی صفحه Storyblok
(پیش نمایش بزرگ)

برای تولید صفحات محتوا به صورت برنامه نویسی، Remix دارای ویژگی به نام است اسپلتس، گرفتن همه راب ها بدون توجه به سطوح تو در تو. نام گذاری یک فایل $.jsx تابع اساسی catch-all slug را فعال می کند.

app
├── root.jsx
└── routes
    ├── files
    │   └── $.jsx
    └── files.jsx

تفاوت میان بخش های پویا از Remix این است که splats هنوز هم در بعدی مطابقت دارد /. بنابراین، splats همه چیز را در مسیر ضبط می کند. اگر مسیر URL است hello.com/ja/about/something، مسیر splat دارای یک پارامتر ویژه برای گرفتن بخش های انتهایی URL است.

export async function loader({ params }) {
  params["*"]; // "ja/about/something"
}

با استفاده از پارامتر ویژه مسیر splat، اجازه دهید ویرایش کنیم $.jsx فایل.

export default function Page() {
 // useLoaderData returns JSON parsed data from loader func
 let story = useLoaderData();
 story = useStoryblokState(story, {
   resolveRelations: ["featured-posts.posts", "selected-posts.posts"]
 });
 return <StoryblokComponent blok={story.content} />
};
// loader is Backend API & Wired up through useLoaderData
export const loader = async ({ params, preview = false }) => {
 let slug = params["*"] ?? "home";
 slug = slug.endsWith("/") ? slug.slice(0, -1) : slug;
 let sbParams = {
   version: "draft",
   resolve_relations: ["featured-posts.posts", "selected-posts.posts"],
 };
 // …
 let { data } = await getStoryblokApi().get(`cdn/stories/${slug}`,
 sbParams);
 return json(data?.story, preview);
};

اشاره: در بخش “انتخاب بین 3 رویکرد”، ما هر سه رویکرد را پوشش ندادیم، اما اگر می‌خواهید بیشتر بدانید، همه رویکردها در زیر مستند شده‌اند.

خلاصه

ما با هم حقایق و آمار را یاد گرفتیم تا تأثیرات و اهمیت i18n را بدانیم و دیدیم که چگونه Remix چندین گزینه را برای پیاده سازی i18n پیشرفته مدیریت می کند. جالب است که تجربه بهتر i18n SEO و UX بهتری را ارائه می دهد. امیدواریم این مقاله دانش جدید و آموخته های روشنگری را در اختیار شما قرار داده باشد.

سرمقاله Smashing
(vf, il)
Read More

متحرک سازی ماشین ها با HTML و SVG – مجله Smashing

سلام! و اگر HTML را دوست دارید، به جای درستی آمده اید!

من عاشق HTML هستم. به‌عنوان یک توسعه‌دهنده فرانت‌اند قدیمی، فکر می‌کنم این یک مهارت بسیار دست کم گرفته شده است. من از سال 2005 تا کنون HTML می نویسم، و امروزه مرورگر به تنهایی می تواند تقریباً تمام کارهایی را که Flash می توانست تقریباً دو دهه پیش انجام دهد، انجام دهد!

یکی مثل فوت و فن HTML در حال حاضر نامیده می شود <animateMotion> – کسانی که با فلش آشنا هستند این را به خاطر خواهند داشت راهنمای حرکت. من این ویدیو را از 14 سال پیش پیدا کردم، اما روش قبل از آن مدتی وجود داشت:

در یوتیوب تماشا کنید)”>
آموزش فلش – 5 – لایه های راهنمای حرکت (در یوتیوب تماشا کنید)

ایده این است که شما مسیری را ایجاد می‌کنید تا عناصر دنبال شوند… و تمام!

در اینجا نمونه ای از کارهایی است که می توانید انجام دهید <animateMotion>:

اگر نگاهی به اسناد MDN، یک مثال ساده از یک دایره قرمز را خواهید دید که مسیری را در یک حلقه بی نهایت دنبال می کند. ماشین‌های مسابقه در پیش‌نمایش زنده از همان قوانین ساده پیروی می‌کنند و دقیقاً مانند این کار می‌کنند!

سه ماشین متحرک در رنگ های آبی، سبز و صورتی که خطوط چین را دنبال می کنند
یک مثال ساده از آنچه می توان با استفاده از آن به دست آورد animateMotion. (انیمیشن را ببینید)

استفاده از SVG animateMotion

اینجا یک نسخه ساده شده که من از آن برای توضیح برخی از جزئیات دقیق استفاده خواهم کرد.

توجه داشته باشید: من برخی از مقادیر مسیر را برای اختصار حذف کرده ام، اما می توانید ببینید src برای قطعه زیر در simple-version.html.)

<!DOCTYPE html>
<html>
  <head>
    <title>Simple Example</title>
  </head>
  <body>
    <main>
      <svg viewBox="0 0 307 184" xmlns="http://www.w3.org/2000/svg">
        <g id="track">
          <g id="track-lines">
            <path fill="none" stroke="#facc15" d="M167.88,111.3..." />
          </g>

          <g id="pink-car">
            <animateMotion dur="4s" repeatCount="indefinite" rotate="auto" path="M167.88,111.3..." />
            <path fill="#EC4899" d="M13.71,18.65c0.25-0.5..." />
          </g>
        </g>
      </svg>
    </main>
  </body>
</html>

اولین چیزی که باید به آن نگاه کرد این است <g> عنصر با id از track-lines. این خط چین زرد است که نشان دهنده مسیری است که خودرو طی خواهد کرد.

دیگری را نیز خواهید دید <g> عنصر با id از pink-car. در این گروه قرار دارد <animateMotion> عنصر یک ویژگی دارد path. اعدادی که برای تشکیل این مسیر استفاده می شوند با اعدادی که مسیر را تشکیل می دهند یکسان است track-lines. یک <animateMotion> عنصر نامرئی است و تنها هدف آن ارائه مسیری برای یک عنصر است که باید آن را دنبال کند.

صحبت از آن، در زیر <animateMotion> عنصر دیگری است <path> عنصر، این ماشین صورتی است و مسیر نزدیکترین همسایه خود را دنبال می کند.

animateMotion ویژگی های

برخی از ویژگی های اضافی وجود دارد که <animateMotion> عنصر می پذیرد. اینها به شرح زیر است:

  • dur: مدت زمان انیمیشن.
  • repeatCount: تعداد دفعاتی که انیمیشن باید حلقه بزند.
  • rotate: این را می توان جهت گیری مسیر در نظر گرفت. این اطمینان حاصل می کند که عنصری که در اطراف مسیر متحرک است همیشه در جهت حرکت قرار دارد.
  • path: همانطور که توضیح داده شد، این مسیر واقعی یک عنصر است.

را اسناد MDN نشان دادن <animateMotion> عنصر به عنوان فرزند یک Svg <circle> شکل به عنوان مثال:

<circle r="5" fill="red">
  <animateMotion
    dur="10s"
    repeatCount="indefinite"
    path="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" />
</circle>

در حالی که این رویکرد برای اشکال کار می کند، تنها در صورتی کار خواهد کرد که عنصر بتواند کودکی را بپذیرد. عنصر مسیر SVG نمی تواند، بنابراین همه چیز را در آن قرار دهید <g> عنصر به HTML اجازه می دهد تا مشخص کند که سیستم مختصات باید از کجا شروع شود و کدام عناصر باید مسیر را دنبال کنند. یواشکی ay!

و بس. من مسیر و سایر عناصری که روی آن دیده می شود را طراحی کردم لینک پیش نمایش در Adobe Illustrator و همه چیز را به عنوان یک SVG صادر کرد. سپس کمی بازسازی دستی انجام دادم تا مطمئن شوم خودروها در مجاورت یک قرار دارند <animateMotion> عنصر و voilà! یک مسیر مسابقه!

دسترسی

یک مشکل کوچک، <animateMotion> عنصر به صورت بومی مشاهده نمی کند ترجیح می دهد-کاهش-حرکت. برای حل این مشکل در پیش‌نمایش، یک را اضافه کرده‌ام پرس و جو رسانه ای که هر عنصری را با نام کلاس تنظیم می کند car به display: none;. ایده آل نیست، اما حداقل حرکت ایمن است!

امیدوارم از این پست لذت برده باشید، و اگر سوالی دارید، لطفا بیایید و من را در توییتر پیدا کنید. @PaulieScanlon، اوه و اگر شما تصویرگر بهتری از من هستید، لطفاً در طراحی مجدد مسیر مسابقه و اتومبیل‌ها احساس راحتی کنید، و من خوشحال می‌شوم که آن را به کد تبدیل کنم!

شما را در سراسر اینترنت می بینم!

مطالعه بیشتر در SmashingMag

سرمقاله Smashing
(yk, il)

Read More

چگونه طراحان باید بازخورد با کیفیت بالا بخواهند (و دریافت کنند) – مجله Smashing

این نسبتاً معمول است که می بینیم طراحان از بازخورد بی کیفیتی که از سهامداران یا مشتریان دریافت کرده اند شکایت دارند. “آنها به معنای واقعی کلمه به من گفتند که لوگو را بزرگتر کنم!” آنها ممکن است شوخی کنند، یا “آنها به من گفتند که “احساس درستی به نظر نمی رسد” اما نمی توانند دلیل آن را توضیح دهند. قرار است با آن چه کنم؟» پاسخ ما معمولاً همدردی با همکار فقیرمان است – بالاخره همه ما قبلاً آنجا بوده ایم – و به حماقت مشتریان بخندیم.

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

چه اتفاقی می افتد

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

“اول، من این را امتحان کردم. سپس آن را امتحان کردم. من دوست نداشتم که چگونه این کار می کند، بنابراین من این مورد دیگر را امتحان کردم و احساس بهتری داشتم.

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

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

“خب چی فکر می کنی؟”

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

این خیلی بزرگ به نظر می رسد. این مسطح به نظر می رسد. من این رنگ را دوست ندارم آیا می‌توانید این منطقه را کمی بیشتر کنید؟»

نظرات، نظرات، نظرات. این دقیقا همان چیزی است که طراح نکرد خواستن

بنابراین، چگونه می توانید این چرخه را بشکنید؟

قاب بندی درخواست بازخورد

به جای ارائه یک مطالعه موردی خطی که هر بازنگری طراحی را نشان می دهد، اولین کاری که باید انجام دهید این است که مشکل را چارچوب بندی کنید – اساساً توضیح بده چه مشکلی داره با طراحی فعلی و چه مشکلی را می خواهید حل کنید با نسخه جدید از این گذشته، طراحی به جای تصاویر زیبا، به معنای حل مسئله است، درست است؟

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

در عوض، زمانی که طرح نهایی را ارائه می‌کنید، با ذینفعان در سطح استراتژیک تعامل داشته باشید توضیح دهید که چگونه طرح جدید مشکل موجود را حل می کند. یا حتی بهتر: توضیح دهید که چگونه می‌خواهید آزمایش/ثابت کنید چگونه مشکل را حل می‌کند و تا چه اندازه.

“ما این نسخه را هفته آینده منتشر خواهیم کرد و تا پایان ماه با برخی ارقام به شما باز خواهیم گشت.”

این خیلی بهتر از یک مبهم است، “نظر شما چیست؟”

بیشتر بعد از پرش! ادامه مطلب زیر ↓

خاص باشید

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

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

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

اگر مطمئن نیستید که بازخورد یک درخواست است یا خیر، در توضیح آن درنگ نکنید. اگر آن شخص DRI (فرد مستقیماً مسئول) نیست، به او اطلاع دهید که برای تأیید نهایی، آن را از DRI عبور خواهید داد. مدیران اغلب فقط سعی می کنند مفید باشند، بنابراین وظیفه شما این است که مشکل را طرح ریزی کنید و بازخورد آنها را به روش صحیح ارسال کنید.

از گفتن نترسید:

“در حال حاضر به دنبال بازخورد در مورد زبان بصری نیستیم، اما ما دوست داریم بازخورد X را دریافت کنیم!”

البته آن X هر چه باشد.

به دنبال اعتبارسنجی خارجی نباشید. بازخورد (واقعی) بخواهید

طراحان اغلب در پایان ارائه بازخورد درخواست می کنند، در حالی که واقعاً ضروری نیست. کاملاً منطقی است که یک ارائه را به‌عنوان یک به‌روزرسانی قاب کنیم و چیزی را در امتداد موارد زیر بیان کنیم:

“ما در این مرحله به دنبال بازخورد نیستیم.”

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

تو بگو:

“شما چی فکر میکنید؟”

وقتی واقعا منظورت اینه:

“لطفا به حمایت از نفس شکننده من کمک کنید و به من بگویید که چقدر عالی هستم!”

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

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

به این ترتیب، پاسخ صحیح به چنین بازخوردی این است:

“این بسیار جالب است – بیشتر به من بگویید!”

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

درس گرفتن از اشتباهاتمان

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

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

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

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

کار خود را زود و اغلب نشان دهید

این مشکل آخر کمی بزرگ است. من طراحان زیادی را می بینم که فقط می خواهند کاری را نشان دهند که فکر می کنند 95٪ انجام شده است و سپس وقتی از آنها خواسته می شود تغییراتی ایجاد کنند ناامید و دفاعی می شوند. می توانید بفهمید چرا. مثل رسیدن به خط پایان یک ماراتن است که فقط ده مایل دیگر طولانی شده است. خسته کننده و دلسرد کننده است، و شما کاملا مطمئن نیستید که به اندازه کافی “گاز باقی مانده در مخزن” برای ادامه کار دارید.

این رفتار اغلب با روانشناسی و احساس ارزشمندی یک طراح گره خورده است. ما از دریافت انتقاد خوشمان نمی آید – منظورم این است که چه کسی این کار را می کند؟ – از آنجایی که اغلب احساس می شود این ما هستیم که مورد انتقاد قرار می گیریم تا کاری که انجام داده ایم. بنابراین تا زمانی که مطمئن شویم که قبل از اینکه زیر نور چشمک زن خورشید قرار بگیریم، آن را میخکوب کرده ایم، خود را پنهان می کنیم، فقط برای اینکه برخی از مدیران پست رویاهای ما را زیر پا بگذارند.

پاسخ به طرز آزاردهنده ای ساده است.

به جای اینکه منتظر بمانید تا به کمال برسید، در نشان دادن کار در حال انجام راحت باشید – اولین پیش نویس های نامرتب که می دانید قرار است بازخورد را بخواهید.

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

فقط لحظه “افشای بزرگ” را بکشید – به آن نیاز ندارید!

نتیجه

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

بهترین طراحان این را می دانند. طراحان خوب امیدوارند ثابت شوند درست. با این حال، طراحان بزرگ می خواهند ثابت شوند اشتباه. چرا؟ زیرا این موثرترین راه برای یادگیری و بهتر شدن است.

بیشتر خواندن

منابع بسیار خوبی در مورد بازخورد طراحی وجود دارد! در اینجا تعدادی از موارد مورد علاقه شخصی من، از جمله چند مقاله عالی از مجله Smashing وجود دارد.

سرمقاله Smashing
(mb، yk، il)

Read More

با Pixo آشنا شوید، یک ویرایشگر عکس برای کاربران نهایی شما – مجله Smashing

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

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

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

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

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

یکی از ویرایشگرهای تصویری که ممکن است دوست داشته باشید در نظر بگیرید و امتحان کنید پیکسو. و برای قرار گرفتن در معرض کامل، این همان چیزی است که ما در حال حاضر روی آن کار می کنیم، با یک طرح رایگان دوستانه نیز موجود است. Pixo را می توان به دلیل ادغام آسان (فقط چند خط جاوا اسکریپت) و API غنی در هر وب سایت یا برنامه ای ادغام کرد. همچنین به عنوان یک افزونه برای وردپرس در دسترس است و جایگزین ویرایشگر تصویر پیش فرض در WP Admin می شود. Pixo Editor تمام ویژگی‌های ویرایشگر پیش‌فرض و چند ویژگی دیگر را دارد.

یکی از آنها است ویرایش دسته ای که به مدیر/ویرایشگر سایت اجازه می دهد تا تغییراتی را در یک عکس ایجاد کند و آنها را در کل دسته تکرار کند. به سادگی دسته ای از عکس ها را در کتابخانه رسانه انتخاب کنید و ویرایش دسته ای را انتخاب کنید. وقتی Pixo اولین عکس را برای ویرایش باز می‌کند، ویرایشگر سایت تغییراتی ایجاد می‌کند – فیلتری را انتخاب می‌کند، رنگ‌ها را تنظیم می‌کند و متن اضافه می‌کند. در ذخیره، تغییرات به بقیه عکس‌های دسته‌ای تکرار می‌شود!

ویرایشگر تصویر Pixo برای وردپرس

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

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

از آنجایی که Pixo یک SaaS است، می توان آن را در هر جایی با چند خط جاوا اسکریپت ادغام کرد. می تواند یک تصویر را از DOM یا از یک URL بارگیری کند، base64 رشته یا dataurl، از سیستم فایل محلی و موارد دیگر.

var image = document.getElementById('myimage'); // DOM image
var image="https://yourdomain.com/path/to/image.jpg"); // image url
var image="abfdSDFEWwq2332Wdsdsdf435esf345SDfdr4S="; // base64 encoded image
var image="data:image/png;base64,abfdSDFEWwq2332Wdsdsdf43.."; // dataurl
var image="{...}"; // previously exported image as JSON

var constructor_options = { apikey: 'abc123xyz000' }; // must be a valid API key issued by https://pixoeditor.com
new Pixo.Bridge(constructor_options).edit(image);

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

new Pixo.Bridge({
    apikey: 'abc123xyz000',
    onSave: function(image){
       // download the photo
       image.download();
       // or inject it into the DOM
       document.body.appendChild(image.toImage());
       // or serialize it as JSON
       image.toJSON();
       // or upload the photo
       var data = new FormData();
       data.append('image', image.toBlob());
       var request = new XMLHttpRequest();
       request.open('POST', 'http://yourdomain.com/path/to/upload.php');
       request.send(data);
    }
 }).edit('http://yourdomain.com/path/to/imagetoedit.jpg');

در اینجا یک مثال CodeSandbox وجود دارد که برخی از گزینه های ورودی و خروجی موجود را نشان می دهد:

ویژگی های ویرایش عکس

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

یکی از بهترین ویژگی ها ابزار Background است. این به کاربران نهایی امکان می دهد پس زمینه را با یک رنگ ثابت، تصویر دیگری از Unsplash یا یک تصویر سفارشی جایگزین کنند.

Pixo Editor: Background Tool

ابزارهای ترسیمی وجود دارد که به کاربران نهایی اجازه می دهد آزادانه بالای تصویر بکشند. ابزار Pencil برای چرخاندن برخی از قسمت‌های تصویر یا کشیدن فلش‌ها برای اشاره به چیزی مفید است. ابزار Blur برای پوشاندن بخش‌هایی از عکس – صفحات ماشین، چهره‌ها یا سایر اطلاعات حساس بسیار عالی است. ابزار Erase کاری را که می گوید انجام می دهد – قسمت هایی از برچسب های درج شده و سایر تصاویر را پاک می کند. متأسفانه ابزار Erase روی عکس منبع کار نمی کند.

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

Session Restore توضیح داده شد.

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

پشتیبانی از برچسب سفید

Pixo Editor دارای پشتیبانی کامل از برچسب سفید است. می‌توانید ظاهر و احساس ویرایشگر را کاملاً تغییر دهید تا با نام تجاری خود – آرم، رنگ‌ها، فونت‌ها و حتی طرح‌بندی مطابقت داشته باشد. API این امکان را می دهد که پالت رنگ خود را با چند ویژگی جاوا اسکریپت تعریف کنید. اما شما حتی می توانید یک فایل CSS سفارشی را با بازنویسی آپلود کنید و اساساً هر چیزی را تغییر دهید. این ویرایشگر دارای شش تم پیش‌فرض است که می‌توانید تم خود را در بالای آن بسازید.

قالب ها

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

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

در اینجا نمونه هایی از JSFiddle آورده شده است:

  1. سازنده قالب
    نمونه ای از Pixo که برای ایجاد یک الگو و ذخیره آن در localStorage برای سادگی استفاده می شود.
  2. مصرف کننده الگو
    نمونه ای از Pixo که برای انتخاب یک تصویر و اعمال الگو روی آن استفاده می شود.

API

Pixo یک API ارائه می‌کند که به توسعه‌دهندگان اجازه می‌دهد ویرایشگر را پیکربندی کنند، و همچنین دستورات را اجرا کرده و تغییرات را در عکس بارگذاری‌شده فعلی اعمال کنند. به عنوان مثال، می توانید کتابخانه استیکرهای سهام را با استیکرهای سفارشی خود به راحتی گسترش دهید:

pixo_instance.filterStickers(function (stock_stickers) {
   // merge or completely replace the stickers
   return my_stickers;
});

اگر می‌خواهید قاب‌های عکس استوک، فونت‌ها (برای ابزار متن) و اندازه‌های برش از پیش تعریف‌شده را اصلاح کنید، می‌توانید از رویکرد مشابهی استفاده کنید. و اگر می خواهید تغییری را به صورت برنامه ریزی شده در عکس فعلی اعمال کنید، می توانید آن را با exec فرمان شما می توانید تقریباً هر کاری را که کاربر نهایی می تواند در ویرایشگر انجام دهد – به سادگی با اجرای دستور مربوطه انجام دهید. این شامل اعمال فیلتر، درج برچسب، حذف پس‌زمینه، تصحیح رنگ، برش، تبدیل و غیره است. در ترکیب با برخی از CSS های سفارشی، می توانید به سرعت کنترل های خود را پیاده سازی کنید و فقط از بوم و منطق تجاری Pixo استفاده کنید:

در مثال بالا، کنترل های داخلی را با CSS مخفی می کنیم (display: none)، و ما فقط بوم را قابل مشاهده می گذاریم. و با مقداری HTML، CSS و جاوا اسکریپت که فراخوانی می کند exec API، ما اساساً کنترل های سفارشی خود را پیاده سازی می کنیم. اگر بنا به دلایلی نتوانیم رابط کاربری را به شکلی که می‌خواهیم فقط با CSS شخصی‌سازی کنیم، می‌تواند مفید باشد.

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

REST API

Pixo همچنین یک نقطه پایانی REST ارائه می دهد. می توانید آن را ارسال یک فایل باینری تصویر یا با URL به یک تصویر یا نمایش base64 آن نامید و همان تغییراتی را که کاربر نهایی می تواند در ویرایشگر انجام دهد اعمال کنید:

curl -X POST -F 'apikey=yourapikey' -F 'filter=Sepia' -F 'image=@input.jpeg' https://pixoeditor.com/api/image > output.jpeg

ادغام Pixo در برنامه های موبایل بومی

Pixo یک سرویس مبتنی بر جاوا اسکریپت است که برای وب‌سایت‌ها یا برنامه‌های کاربردی وب طراحی شده است، اما به لطف مؤلفه WebView که توسط iOS و Android پشتیبانی می‌شود، می‌توان آن را در برنامه‌های تلفن همراه بومی نیز ادغام کرد. جریان بسیار ساده است:

  1. کاربر یک عکس را برای ویرایش با استفاده از یک جزء اصلی Image Picker برمی‌دارد.
  2. عکس به رشته base64 کدگذاری شده است.
  3. Pixo در داخل یک مؤلفه WebView بارگذاری می شود.
  4. رشته base64 با استفاده از API پیام رسانی WebView به Pixo ارسال می شود.
  5. کاربر عکس را با ویرایشگر ویرایش می کند.
  6. کاربر از عکس ویرایش شده راضی است و آن را صادر می کند.
  7. Pixo یک تابع بومی را از طریق WebView API فراخوانی می کند و عکس ویرایش شده را به عنوان یک رشته base64 ارسال می کند.
  8. رشته base64 به یک تصویر بومی تبدیل می شود.

می توانید اینجا ببینید یک برنامه آزمایشی برای iOS که رویکرد فوق را اجرا می کند و یک برنامه برای iOS و Android که در Flutter پیاده سازی شده است.

همین رویکرد را می توان در یک برنامه دسکتاپ Electron پیاده سازی کرد.

مزایا و معایب

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

اما از آنجایی که این یک سرویس آنلاین است، این خطر وجود دارد که برای مدتی از کار بیفتد و در این مدت، کاربران نهایی شما نتوانند کار خود را انجام دهند. تا زمانی که برنامه یا وب‌سایت اصلی شما فعال باشد، راه‌حل خود میزبان همیشه فعال خواهد بود. با این حال، میانگین آپ تایم Pixo 99.993٪ است (طبق گزارش وضعیت عمومی) که آنقدرها هم بد نیست.

افکار نهایی

به نظر می رسد Pixo راه حل خوبی برای ویرایش تصویر برای همه وب سایت ها و برنامه های وب است که نیاز به ارائه ویرایش تصویر به عنوان یک ویژگی دارند. مستندات و نمونه های دقیق آن ادغام را بسیار آسان می کند. Pixo دارد یک دوره آزمایشی رایگان 30 روزه با امکانات کامل. پس از آن، می توانید به استفاده از ابزارهای ویرایش اولیه و API های آن به صورت رایگان ادامه دهید یا یک طرح اشتراک با ویژگی های کامل دریافت کنید.

منابع

سرمقاله Smashing
(vf, il)
Read More