Requirements check first. Open the package's composer.json (or run composer show dpsoft/nova-persian-date) and note the laravel/nova and php constraints before installing. Last release was July 2023, so confirm it fits your Nova major version (Nova 4 vs. Nova 5) and PHP version before committing.
Install:
composer require dpsoft/nova-persian-date
php artisan nova:publish # only if the README asks for asset publishing
The field registers itself through Nova's field mechanism; no NovaServiceProvider edits are normally needed. If the frontend component fails to load, run php artisan optimize:clear and verify the compiled JS asset exists under the package's dist/ folder.
Look here first to understand capabilities before coding against it:
vendor/dpsoft/nova-persian-date/src/ — the PHP field class; every chainable method you can use is defined here.vendor/dpsoft/nova-persian-date/resources/js/ — the Vue component; tells you what the input emits (Jalali string vs. Gregorian ISO) and which picker options are supported.README.md — usually the only documentation; expect it to be thin.First use case — swap a plain DateTime field for a Shamsi picker on a resource while keeping Gregorian values in the database:
use Dpsoft\NovaPersianDate\PersianDate; // confirm namespace in vendor/src
public function fields(NovaRequest $request)
{
return [
PersianDate::make('published_at')
->rules('required', 'date')
->sortable(),
];
}
Keep the model cast as Gregorian so ordering, whereDate, and API output stay sane:
protected $casts = [
'published_at' => 'datetime',
];
Database is Gregorian, UI is Jalali. Treat the field purely as an input widget. Never let a Persian-formatted string reach the database column; otherwise orderBy, range filters, and Carbon casts will break inconsistently.
Consistent display in index/detail views. If the package's built-in formatting is limited, override it without touching stored data:
PersianDate::make('published_at')
->displayUsing(fn ($value) => $value
? verta($value)->format('%Y/%m/%d')
: null) // hekmatinasser/verta
->onlyOnIndex();
Pair with a hidden/read-only Gregorian view for debugging and support:
DateTime::make('published_at', 'Stored (Gregorian)')
->onlyOnDetail()
->readonly(),
Filters and lenses. Nova filter payloads typically arrive as strings; convert once at the boundary and use whereDate so time components don't cause off-by-one results:
public function apply(Request $request, $query, $value)
{
$date = verta($value)->toCarbon(); // or Carbon::parse($value)
return $query->whereDate('published_at', $date);
}
Searchable / sortable columns. Only add ->sortable() when the underlying column is a real date/datetime. Sorting a varchar column containing mixed calendars is a common source of "wrong order" bug reports.
Forms with time. If the field supports a time picker, keep the same Gregorian storage contract and validate the merged value with standard Laravel rules (date, after:now). Confirm what the component submits by watching the network payload once — do not assume the format.
API and exports. Cast to datetime in the model and convert at the serialization layer (JsonResource, exporter). This keeps one conversion point and avoids scattering verta() calls through controllers.
Incoming imports/seeders. Accept Persian input from spreadsheets by parsing to Gregorian before save():
$model->published_at = verta($row['published_at'])->toCarbon();
packages/ if a Nova upgrade breaks it. Read the Vue component before relying on any undocumented option.app.timezone, Nova's userTimezone, and the picker's own display timezone can each shift the value. Test by saving a value, reloading the form, and inspecting the raw DB column — all three must agree.whereBetween, and date filters, and they make data migration expensive later. Normalize on write. (This pattern is not unique to this package — it's the most common failure mode for Persian date field integrations.)date rule may reject or misinterpret it. Verify with a deliberately invalid submission, and use fillUsing()/prepareRules() to convert before validation if necessary.Nova::script(...) in the package service provider) and run php artisan nova:publish. In local dev, a stale public/vendor directory is a frequent culprit.displayUsing, resolveUsing, fillUsing, and overriding the Vue component (fork + custom npm run prod). Budget for this rather than waiting on upstream fixes.Date field plus verta conversion in resolve/fill gives you a smaller long-term dependency footprint.How can I help you explore Laravel packages today?