فصل سوم: جادوی محلیسازی: آوردن طعم پارسی و تقویم جلالی به Nextcloud¶
هدف فصل: ساخت یک تجربه بومی و جذاب¶
تصور کنید Nextcloud را به یک فضای ابری کاملاً پارسی تبدیل کنید، جایی که هر منو به زبان فارسی سخن میگوید و تاریخها با تقویم جلالی، قلب فرهنگ ایران، نمایش داده میشوند! در این فصل، با فارسیسازی رابط کاربری و ادغام تقویم جلالی در هسته و اپلیکیشنهای Nextcloud ۳۲.۰.۰، شما را به یک سفر برنامهنویسی هیجانانگیز میبریم. از ترجمههای روان تا نمایش تاریخهای شمسی، این فصل پروژه شما را به یک اثر بومی و کاربرپسند تبدیل میکند.
۳.۱ فارسیسازی: صحبت به زبان کاربر¶
برای اینکه Nextcloud برای کاربران پارسیزبان آشنا و دلنشین باشد، باید رابط کاربری را به فارسی ترجمه کنیم و آن را با جهتگیری راستبهچپ (RTL) و فونتهای زیبای پارسی هماهنگ کنیم.
۳.۱.۱ افزودن ترجمههای پارسی: صدای پروژه شما¶
ترجمهها به Nextcloud اجازه میدهند که به زبان فارسی با کاربران صحبت کند. ما از سیستم l10n استفاده میکنیم تا رشتههای متنی را جایگزین کنیم.
- ایجاد فایل ترجمه:
فایل:
apps/myapp/l10n/fa.json
{
"translations": {
"Files": "فایلها",
"Settings": "تنظیمات",
"Calendar": "تقویم",
"Save": "ذخیره",
"Share": "اشتراکگذاری"
},
"pluralForm": "nplurals=2; plural=(n != 1);"
}
- ثبت ترجمه در اپلیکیشن:
فایل:
apps/myapp/appinfo/app.php
<?php
namespace OCA\MyApp;
use OCP\AppFramework\App;
class MyApp extends App {
public function __construct(array $urlParams = []) {
parent::__construct('myapp', $urlParams);
\OC::$server->getL10N('myapp')->load();
}
}
- استفاده در رابط کاربری (Vue):
فایل:
apps/myapp/src/components/MyComponent.vue
<template>
<div>{{ t('Files') }}</div>
</template>
<script>
import { getTranslator } from '@nextcloud/l10n';
export default {
methods: {
t(key) {
return getTranslator('myapp').t(key);
}
}
}
</script>
تست:
console.log(getTranslator('myapp').t('Files')); // فایلها
۳.۱.۲ پشتیبانی از RTL: طراحی برای خوانندگان پارسی¶
جهت راستبهچپ و فونتهای پارسی، تجربه کاربری را برای ایرانیان بهینه میکند.
- ایجاد استایل RTL:
فایل:
apps/myapp/css/rtl.css
[dir="rtl"] {
direction: rtl;
text-align: right;
unicode-bidi: embed;
}
.myapp-container {
margin-inline-start: 1rem;
padding: 1rem;
}
@font-face {
font-family: 'Vazir';
src: url('https://cdn.fontcdn.ir/Font/Persian/Vazir/Vazir.woff2') format('woff2');
font-display: swap;
}
body {
font-family: 'Vazir', sans-serif;
}
- فعالسازی RTL:
فایل:
apps/myapp/appinfo/app.php
\OCP\Util::addStyle('myapp', 'rtl');
\OCP\Util::addHeader('html', ['dir' => 'rtl', 'lang' => 'fa']);
- اعمال فونت در سرور:
فایل:
themes/persian-theme/core/css/server.css
body {
font-family: 'Vazir', sans-serif;
}
تست: به http://localhost:8080 بروید و مطمئن شوید متنها راستچین و با فونت Vazir هستند.
۳.۲ ادغام تقویم جلالی: قلب پارسی پروژه¶
تقویم جلالی، که بر اساس چرخه خورشیدی کار میکند، برای کاربران ایرانی ضروری است.
۳.۲.۱ نصب کتابخانههای جلالی¶
npm install date-fns-jalali
composer require morilog/jalali
۳.۲.۲ کلاس تبدیل جلالی¶
فایل: apps/myapp/lib/Calendar/JalaliConverter.php
<?php
namespace OCA\MyApp\Calendar;
use Morilog\Jalali\Jalalian;
class JalaliConverter {
public static function toJalali(\DateTime $date): array {
$jalali = Jalalian::fromDateTime($date);
return [
'year' => $jalali->getYear(),
'month' => $jalali->getMonth(),
'day' => $jalali->getDay()
];
}
public static function toGregorian(int $year, int $month, int $day): \DateTime {
return Jalalian::fromFormat('Y/m/d', sprintf('%d/%d/%d', $year, $month, $day))
->toCarbon()->toDateTime();
}
public static function formatJalali(\DateTime $date, string $format): string {
return Jalalian::fromDateTime($date)->format($format);
}
}
۳.۲.۳ ادغام در هسته¶
فایل: apps/myapp/appinfo/app.php
$container->getServer()->get(IEventDispatcher::class)->addListener(
'OCP\Template::render',
function ($event) {
$params = $event->getParameters();
if (isset($params['date']) && $params['date'] instanceof \DateTime) {
$params['date'] = \OCA\MyApp\Calendar\JalaliConverter::formatJalali(
$params['date'], 'Y/m/d'
);
$event->setParameters($params);
}
}
);
۳.۲.۴ جلالی در JavaScript¶
فایل: apps/myapp/js/jalali.js
import { format } from 'date-fns-jalali';
if (!OC.Util) OC.Util = {};
OC.Util.formatJalaliDate = (date, pattern = 'yyyy/MM/dd') => {
try {
return format(new Date(date), pattern, { calendar: 'jalali' });
} catch (e) {
console.error('خطا در فرمت تاریخ جلالی:', e);
return date.toLocaleDateString('fa-IR');
}
};
بارگذاری:
\OCP\Util::addScript('myapp', 'jalali');
۳.۲.۵ ادغام با Datepicker¶
نصب:
npm install flatpickr flatpickr-jalali
فایل: apps/myapp/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',
mounted() {
Flatpickr(this.$refs.picker, {
calendar: 'jalali',
locale: 'fa',
dateFormat: 'Y/m/d',
onChange: (selectedDates) => {
this.$emit('input', OC.Util.formatJalaliDate(selectedDates[0]));
}
});
}
}
</script>
<style>
.jalali-picker {
font-family: 'Vazir', sans-serif;
direction: rtl;
}
</style>
۳.۳ تست: اطمینان از جادوی پارسی¶
- فعالسازی اپلیکیشن:
php occ app:enable myapp
- تست API:
فایل:
apps/myapp/lib/Controller/TestController.php
<?php
namespace OCA\MyApp\Controller;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IRequest;
use OCA\MyApp\Calendar\JalaliConverter;
class TestController extends Controller {
public function __construct($appName, IRequest $request) {
parent::__construct($appName, $request);
}
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function index() {
$date = new \DateTime('2025-03-21');
return new JSONResponse([
'jalali' => JalaliConverter::formatJalali($date, 'Y/m/d')
]);
}
}
مسیر: apps/myapp/appinfo/routes.php
['name' => 'test#index', 'url' => '/api/index', 'verb' => 'GET']
تست:
curl http://localhost:8080/index.php/apps/myapp/api/index
- تست JavaScript:
OC.Util.formatJalaliDate(new Date('2025-03-21')) // 1404/01/01
- تست UI:
- به
http://localhost:8080بروید. - تاریخها و متنها را بررسی کنید.
نکات حرفهای¶
- کشینگ: از Redis برای ذخیره تبدیلها استفاده کنید.
- دسترسیپذیری: با WAVE تست کنید.
- مستندات: در
README.fa.mdبنویسید.