فصل پنجم: روح پارسی در Calendar و Talk: سفارشی‌سازی با طعم جلالی

هدف فصل: خلق تجربه‌ای بومی و یکپارچه

تصور کنید تقویمی که با چرخه خورشیدی ایران می‌رقصد و پیام‌رسانی که به زبان پارسی و با تاریخ‌های شمسی با شما سخن می‌گوید! در این فصل، اپلیکیشن‌های Calendar و Talk (Spreed) در Nextcloud ۳۲.۰.۰ را به یک تجربه کاملاً پارسی تبدیل می‌کنیم. از ترجمه‌های روان و جهت‌گیری راست‌به‌چپ (RTL) تا ادغام تقویم جلالی با انتخاب‌گر تاریخ، این فصل اپلیکیشن‌های شما را به شاهکارهایی کاربرپسند و بومی‌شده تبدیل می‌کند. آماده‌اید که Calendar و Talk را به رنگ و بوی ایران درآورید؟


۵.۱ اپلیکیشن Calendar: تقویمی که پارسی نفس می‌کشد

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

۵.۱.۱ فارسی‌سازی: زبان رویدادها

  1. ایجاد فایل ترجمه: فایل: apps/calendar/l10n/fa.json
   {
       "translations": {
           "Event": "رویداد",
           "New event": "رویداد جدید",
           "Today": "امروز",
           "Tomorrow": "فردا",
           "All day": "تمام‌روز",
           "Delete": "حذف",
           "Share": "اشتراک‌گذاری"
       },
       "pluralForm": "nplurals=2; plural=(n != 1);"
   }
  1. بارگذاری ترجمه‌ها: فایل: apps/calendar/appinfo/app.php
   <?php
   \OC::$server->getL10N('calendar')->load();
  1. استفاده در Vue: فایل: apps/calendar/src/components/EventForm.vue
   <template>
       <div>
           <h2>{{ t('New event') }}</h2>
           <button>{{ t('Save') }}</button>
       </div>
   </template>
   <script>
   import { getTranslator } from '@nextcloud/l10n';
   export default {
       methods: {
           t(key) {
               return getTranslator('calendar').t(key);
           }
       }
   }
   </script>

۵.۱.۲ جلالی‌سازی: رقص خورشیدی تقویم

  1. نصب وابستگی‌ها:
   npm install jalaali-js
  1. پیکربندی FullCalendar: فایل: apps/calendar/js/fullcalendar.js
   import { toJalaali } from 'jalaali-js';
   import { format } from 'date-fns-jalali';

   FullCalendar.globalLocales.push({
       code: 'fa',
       week: {
           dow: 6,
           doy: 12
       },
       direction: 'rtl',
       buttonText: {
           month: 'ماه',
           week: 'هفته',
           day: 'روز',
           list: 'فهرست'
       },
       monthNames: [
           'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور',
           'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'
       ],
       monthNamesShort: [
           'فرو', 'ارد', 'خرد', 'تیر', 'مرد', 'شهر',
           'مهر', 'آبا', 'آذر', 'دی', 'بهم', 'اسف'
       ],
       formatDate: (date) => OC.Util.formatJalaliDate(date, 'yyyy/MM/dd'),
       eventTimeFormat: {
           hour: '2-digit',
           minute: '2-digit',
           meridiem: false
       }
   });
  1. اعمال RTL: فایل: apps/calendar/css/style.css
   [dir="rtl"] .fc {
       direction: rtl;
       text-align: right;
   }
   .fc-daygrid-day-number {
       font-family: 'Vazir', sans-serif;
       color: #2a5db0;
   }

۵.۱.۳ انتخاب‌گر تاریخ جلالی

  1. نصب پلاگین:
   npm install flatpickr flatpickr-jalali
  1. ایجاد کامپوننت Vue: فایل: apps/calendar/src/components/JalaliPicker.vue
   <template>
       <input ref="picker" type="text" class="jalali-picker" />
   </template>
   <script>
   import Flatpickr from 'flatpickr';
   import 'flatpickr-jalali';
   import 'flatpickr/dist/flatpickr.min.css';

   export default {
       name: 'JalaliPicker',
       props: {
           value: String
       },
       mounted() {
           Flatpickr(this.$refs.picker, {
               calendar: 'jalali',
               locale: 'fa',
               dateFormat: 'Y/m/d',
               defaultDate: this.value,
               onChange: (selectedDates) => {
                   this.$emit('input', OC.Util.formatJalaliDate(selectedDates[0]));
               }
           });
       }
   }
   </script>
   <style>
   .jalali-picker {
       font-family: 'Vazir', sans-serif;
       direction: rtl;
       padding: 0.5rem;
       border: 1px solid #2a5db0;
       border-radius: 4px;
   }
   </style>
  1. استفاده در Calendar: فایل: apps/calendar/src/components/EventForm.vue
   <template>
       <jalali-picker v-model="eventDate" />
   </template>
   <script>
   import JalaliPicker from './JalaliPicker.vue';
   export default {
       components: { JalaliPicker },
       data() {
           return { eventDate: '' };
       }
   }
   </script>

۵.۲ اپلیکیشن Talk: چت‌هایی با طعم پارسی

۵.۲.۱ فارسی‌سازی

  1. ایجاد فایل ترجمه: فایل: apps/spreed/l10n/fa.json
   {
       "translations": {
           "Message": "پیام",
           "Send": "ارسال",
           "Chat": "گفت‌وگو",
           "New message": "پیام جدید",
           "Participants": "شرکت‌کنندگان"
       },
       "pluralForm": "nplurals=2; plural=(n != 1);"
   }
  1. بارگذاری ترجمه‌ها: فایل: apps/spreed/appinfo/app.php
   <?php
   \OC::$server->getL10N('spreed')->load();
  1. استفاده در Vue: فایل: apps/spreed/src/components/Chat.vue
   <template>
       <button>{{ t('Send') }}</button>
   </template>
   <script>
   import { getTranslator } from '@nextcloud/l10n';
   export default {
       methods: {
           t(key) {
               return getTranslator('spreed').t(key);
           }
       }
   }
   </script>

۵.۲.۲ جلالی‌سازی

  1. اصلاح مدل پیام: فایل: apps/spreed/js/models/message.js
   export default {
       computed: {
           timestamp() {
               return OC.Util.formatJalaliDate(
                   new Date(this.message.created_at),
                   'yyyy/MM/dd HH:mm'
               );
           }
       }
   }
  1. اعمال RTL: فایل: apps/spreed/css/style.css
   [dir="rtl"] .message {
       direction: rtl;
       text-align: right;
       font-family: 'Vazir', sans-serif;
   }
   .message-timestamp {
       color: #2a5db0;
       font-size: 0.9rem;
   }

۵.۳ تست: اطمینان از تجربه پارسی

  1. فعال‌سازی اپلیکیشن‌ها:
   php occ app:enable calendar spreed
  1. تست Calendar:
  2. به http://localhost:8080 بروید و Calendar را باز کنید.
  3. یک رویداد جدید بسازید و چک کنید:

    • تاریخ‌ها به‌صورت جلالی هستند.
    • Datepicker درست کار می‌کند.
    • متن‌ها به فارسی هستند.
  4. تست Talk:

  5. یک گفت‌وگو شروع کنید.
  6. بررسی کنید:

    • پیام‌ها راست‌چین و با فونت Vazir هستند.
    • زمان‌ها به‌صورت جلالی نمایش داده می‌شوند.
  7. تست‌های لبه:

  8. سال کبیسه جلالی.
  9. سینک با Google Calendar یا Outlook.
  10. تغییر زبان به انگلیسی و بازگشت.

تست در مرورگر:

FullCalendar.globalLocales.find(l => l.code === 'fa').formatDate(new Date('2025-03-21'));
OC.Util.formatJalaliDate(new Date('2025-03-21T14:30:00'));

نکات حرفه‌ای

  • دسترسی‌پذیری: با Lighthouse کنتراست را بررسی کنید.
  • کشینگ:
  const cache = new Map();
  OC.Util.formatJalaliDate = (date, pattern) => {
      const key = `${date.toISOString()}_${pattern}`;
      if (cache.has(key)) return cache.get(key);
      const formatted = format(new Date(date), pattern, { calendar: 'jalali' });
      cache.set(key, formatted);
      return formatted;
  };
  • مستندسازی: در README.fa.md توضیح دهید.
  • تجربه کاربر: گزینه انتخاب تقویم جلالی/گرگوری اضافه کنید.