code16/sharp
Sharp is a Laravel package for building a CMS/admin back office with a clean UI and strong DX. Manage structured data, search/filter/sort, run custom commands, and handle auth/validation—fully driven by PHP code, no frontend, data-agnostic.
Installation:
composer require code16/sharp
php artisan vendor:publish --tag=sharp-assets --force
php artisan migrate
Configure via Service Provider:
Create a custom provider extending SharpAppServiceProvider and implement configureSharp():
use Code16\Sharp\SharpAppServiceProvider;
class SharpServiceProvider extends SharpAppServiceProvider
{
protected function configureSharp(SharpConfigBuilder $config): void
{
$config
->setName('My CMS')
->declareEntity(\App\Sharp\Entities\PostEntity::class);
}
}
First Use Case:
Define a simple entity (e.g., PostEntity) and access it via /sharp/posts (or your custom URL segment).
Entity Management:
declareEntity() in the config builder.Sharp\Entities\Entity traits for CRUD operations (e.g., SingleInstanceTrait, ListTrait).class PostEntity extends Entity
{
use SingleInstanceTrait, ListTrait;
// ...
}
Forms and Validation:
Sharp\Form\Fields for form fields (e.g., TextField, RichTextField).Sharp\Validation\Rules or Laravel’s built-in rules.protected function buildForm(): array
{
return [
TextField::make('title')->required(),
RichTextField::make('content'),
];
}
Search and Filtering:
Sharp\Search\SearchEngine for custom search logic.GlobalFilter to apply filters across entities.class PostSearchEngine implements SearchEngine
{
public function search(string $query): Collection
{
return Post::where('title', 'like', "%{$query}%")->get();
}
}
Authorization:
Sharp\Authorization\Authorizer for custom rules.can() in entities to enforce permissions.class PostEntity extends Entity
{
public function canCreate(): bool
{
return auth()->user()->isAdmin();
}
}
Commands and Actions:
SingleInstanceCommand, EntityCommand).class PublishPostCommand extends SingleInstanceCommand
{
public function handle(): void
{
$this->instance->update(['status' => 'published']);
}
}
resources/js/Pages/Sharp.Sharp\Http\Controllers\ApiController.Middleware Conflicts:
HandleGlobalFilters and SubstituteBindings are in the correct order (Sharp docs specify SubstituteBindings must come after HandleGlobalFilters).SetSharpLocale from the api middleware group if using the new config builder.Icon Migration:
blade-icons. Update icon names from FontAwesome (e.g., fas fa-user → fas-user).owenvoke/blade-fontawesome and configure default attributes.Deprecated Methods:
buildListFields() and buildListLayout() were replaced with buildList().delete() method in forms was moved to Show or EntityList.2FA Setup:
users table has two_factor_secret, two_factor_recovery_codes, and two_factor_confirmed_at columns.pragmarx/google2fa-laravel and bacon/bacon-qr-code for TOTP support.Global Filters:
addGlobalFilter(). Use the authorize() method of the filter instead.php artisan view:clear
php artisan cache:clear
$config->enableDebug();
dd($this->props) in Inertia pages to inspect passed data.Custom Handlers:
Sharp2faNotificationHandler or Sharp2faTotpHandler for 2FA customization.isEnabledFor() to restrict 2FA to specific users.Search Engines:
Sharp\Search\SearchEngine for full-text search or external APIs (e.g., Algolia).Menu Customization:
Sharp\Menu\SharpMenu to dynamically build menus.addEntityLink() with logo for icons (e.g., logo: 'fas-user').Form Fields:
Sharp\Form\Field.ColorPickerField for hex color inputs.Commands:
SingleInstanceWizardCommand for multi-step workflows (e.g., 2FA setup).EntityCommand for bulk actions (e.g., export/import).How can I help you explore Laravel packages today?