Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Sharp Laravel Package

code16/sharp

Code-driven CMS framework for Laravel (PHP 8.3+/Laravel 11+). Build admin/CMS sections with a clean UI and strong DX: CRUD with validation, search/sort/filter, bulk or custom commands, and authorization—no front-end code required, data-agnostic.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require code16/sharp
    php artisan vendor:publish --tag=sharp-assets --force
    php artisan migrate
    
  2. Configure Provider: Create a service provider extending SharpAppServiceProvider:

    // app/Providers/SharpServiceProvider.php
    use Code16\Sharp\SharpAppServiceProvider;
    
    class SharpServiceProvider extends SharpAppServiceProvider
    {
        protected function configureSharp(SharpConfigBuilder $config): void
        {
            $config
                ->setName('My CMS')
                ->declareEntity(\App\Sharp\Entities\PostEntity::class);
        }
    }
    
  3. Define an Entity:

    // app/Sharp/Entities/PostEntity.php
    use Code16\Sharp\Entities\Entity;
    
    class PostEntity extends Entity
    {
        public static function fields(): array
        {
            return [
                'title' => 'string',
                'content' => 'markdown',
                'published_at' => 'datetime',
            ];
        }
    }
    
  4. Route Access: Add to routes/web.php:

    use Code16\Sharp\SharpRoutes;
    
    SharpRoutes::register();
    

First Use Case

Create a CRUD interface for PostEntity with zero frontend code:

php artisan sharp:make:entity Post

This generates a fully functional admin panel at /sharp/posts.


Implementation Patterns

Core Workflows

1. Entity Management

  • Field Types: Use built-in types (string, markdown, datetime, relationship, autocomplete, etc.) or extend with custom fields.

    public static function fields(): array
    {
        return [
            'author' => 'relationship:users',
            'tags' => 'autocomplete:tags',
        ];
    }
    
  • Validation: Define rules in rules() method:

    public static function rules(): array
    {
        return [
            'title' => 'required|max:255',
            'content' => 'required',
        ];
    }
    
  • Actions: Add custom actions to lists/forms:

    public static function listActions(): array
    {
        return [
            'publish' => 'Publish',
            'archive' => 'Archive',
        ];
    }
    

2. Search & Filtering

  • Global Search: Enable in configureSharp:
    $config->enableGlobalSearch(\App\Sharp\AppSearchEngine::class, 'Search...');
    
  • Entity-Specific Filters:
    public static function filters(): array
    {
        return [
            'published' => 'boolean',
            'author' => 'relationship:users',
        ];
    }
    

3. Authorization

  • Role-Based Access: Use Laravel’s built-in gates/policies or Sharp’s authorize():
    public static function authorize(): array
    {
        return [
            'create' => 'can:create-posts',
            'update' => 'can:edit-posts',
        ];
    }
    

4. Custom Commands

  • Bulk Actions: Extend EntityCommand:
    class PublishPostsCommand extends EntityCommand
    {
        use Code16\Sharp\Commands\Traits\PublishPostsCommandTrait;
    }
    
  • Wizards: For multi-step workflows:
    class ImportPostsWizard extends WizardCommand
    {
        use Code16\Sharp\Commands\Traits\ImportPostsWizardTrait;
    }
    

5. Integration with Existing Data

  • Eloquent Models: Sharp is data-agnostic but works seamlessly with Eloquent:
    protected static function model(): string
    {
        return \App\Models\Post::class;
    }
    
  • Custom Queries: Override query() in entities:
    public static function query(): Builder
    {
        return parent::query()->where('status', 'active');
    }
    

Advanced Patterns

1. Dynamic UI

  • Conditional Fields: Use visible()/hidden():

    public static function fields(): array
    {
        return [
            'excerpt' => 'string|visible:isPreview',
        ];
    }
    
  • Dynamic Forms: Extend FormBuilder:

    public function buildForm(FormBuilder $builder): void
    {
        if ($builder->isEditing()) {
            $builder->addField('previous_version', 'relationship:posts');
        }
    }
    

2. API-First Approach

  • Expose Sharp as API: Use Sharp’s built-in API routes:
    SharpRoutes::register(['api' => true]);
    
  • Custom API Responses: Extend ApiResource:
    class PostApiResource extends ApiResource
    {
        public function toArray($request, Post $post): array
        {
            return [
                'title' => $post->title,
                'slug' => Str::slug($post->title),
            ];
        }
    }
    

3. Theming & Assets

  • Custom CSS/JS: Publish assets:
    php artisan vendor:publish --tag=sharp-assets --force
    
  • Override Views: Copy from vendor/code16/sharp/resources/views to resources/views/vendor/sharp.

4. Multi-Tenancy

  • Scoped Entities: Use middleware to filter by tenant:
    $config->setMiddleware([
        'common' => [
            \App\Http\Middleware\SetTenant::class,
        ],
    ]);
    

Gotchas and Tips

Common Pitfalls

  1. Middleware Order:

    • Place SubstituteBindings after HandleGlobalFilters in common middleware.
    • Remove SetSharpLocale from api middleware group (Sharp 9+ uses Inertia).
  2. Icon Migration:

    • Sharp 9+ uses blade-icons. Update icons from fas fa-user to fas-user.
    • Install owenvoke/blade-fontawesome if you need legacy FontAwesome support.
  3. Asset Caching:

    • Always run php artisan view:clear and php artisan vendor:publish --tag=sharp-assets --force after updates.
  4. Entity Declaration:

    • Ensure entities are declared before they’re used in menus or relationships:
    $config->declareEntity(PostEntity::class)
           ->declareEntity(AuthorEntity::class);
    
  5. 2FA Quirks:

    • For enable2faByTotp(), ensure two_factor_secret is stored as a base32-encoded string.
    • Recovery codes must be comma-separated in the two_factor_recovery_codes field.
  6. Inertia Integration:

    • Sharp 9+ uses Inertia.js. Ensure your app/Http/Middleware/HandleInertiaRequests is configured:
    public function rootView(): string
    {
        return config('sharp.inertia_root_view', 'app');
    }
    

Debugging Tips

  1. Log Sharp Events: Enable Sharp’s debug mode in configureSharp:

    $config->setDebug(true);
    

    Or use Laravel’s logging:

    \Log::debug('Sharp event:', ['event' => $event]);
    
  2. Check Entity Resolution:

    • Use php artisan sharp:list to verify registered entities.
    • For missing entities, ensure the class is autoloaded and declared in configureSharp.
  3. Validation Errors:

    • Sharp uses Laravel’s validation. Check storage/logs/laravel.log for validation messages.
    • Override rules() or use validate() in custom commands:
    public function handle(): void
    {
        $this->validate([
            'title' => 'required|unique:posts',
        ]);
    }
    
  4. Permission Denied:

    • Verify gates/policies are registered:
    php artisan gate:list
    
    • Check Sharp’s authorize() methods in entities.
  5. Asset Loading Issues:

    • Clear caches:
    php artisan cache:clear
    php artisan view:clear
    php artisan config:clear
    
    • Ensure sharp-assets are published to public/vendor/sharp.

Extension Points

  1. Custom Field Types:

    • Extend Code16\Sharp\Fields\Field:
    class RichTextField extends Field
    {
        public function render(FieldRenderer $renderer): string
        {
            return $renderer->renderTrixEditor($this);
        }
    }
    
  2. Custom Search Engines:

    • Implement Code16\Sharp\Search\SearchEngineInterface:
    class AlgoliaSearchEngine implements SearchEngineInterface
    {
        public function search(string $query, array $filters): array
        {
            return Algolia::search($
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope