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

Editorjs Bundle Laravel Package

darylseven/editorjs-bundle

Symfony bundle integrating Editor.js with Symfony Forms and Twig. Adds an EditorjsType form field, configurable editor setups, and a Twig helper to render/init the editor. Includes example config and JS init (Encore/webpack).

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the Bundle

    composer require tbmatuka/editorjs-bundle
    

    Ensure Tbmatuka\EditorjsBundle\TbmatukaEditorjsBundle::class is registered in config/bundles.php.

  2. Configure the Bundle Copy examples/editorjs.yaml to config/packages/editorjs.yaml and adjust settings (e.g., default tools, CDN paths). Example:

    tbmatuka_editorjs:
        default_config:
            tools:
                header: null
                paragraph: { class: Header }
    
  3. Set Up Twig Form Theme Add the form theme to your config/packages/twig.yaml:

    twig:
        form_themes:
            - '@TbmatukaEditorjs/Form/editorjs_widget.html.twig'
    
  4. Basic Form Integration Use EditorjsType in a Symfony form:

    use Tbmatuka\EditorjsBundle\Form\Type\EditorjsType;
    
    $builder->add('content', EditorjsType::class, [
        'config' => ['tools' => ['header', 'paragraph']],
    ]);
    
  5. Initialize JavaScript (Encore) Copy examples/editorjs-init.js to assets/js/editor-init.js and import it in your Encore entry file:

    import EditorJS from '@editorjs/editorjs';
    import Header from '@editorjs/header';
    import Paragraph from '@editorjs/paragraph';
    
    // Configure and initialize Editor.js
    const initEditor = (editorId) => {
        const editor = new EditorJS({
            tools: { header: Header, paragraph: Paragraph },
            holder: `editorjs-${editorId}`,
        });
        return editor;
    };
    
  6. Render the Form Use the form in a Twig template:

    {{ form_start(form) }}
        {{ form_row(form.content) }}
        {{ form_end(form) }}
    

Implementation Patterns

Usage Patterns

1. Form-Centric Workflows

  • Dynamic Tool Configuration: Pass tool configurations directly in the form type:
    $builder->add('article', EditorjsType::class, [
        'config' => [
            'tools' => [
                'header' => ['class' => Header, 'config' => ['defaultLevel' => 2]],
                'list' => ['class' => ListTool],
            ],
            'data' => $initialContent, // Preload JSON data
        ],
    ]);
    
  • Validation: Validate JSON output in the form’s validation logic:
    $builder->add('content', EditorjsType::class)
        ->addModelTransformer(new EditorjsTransformer())
        ->addConstraint(new ValidEditorjsContent());
    

2. Twig Customization

  • Override the default Twig widget for Symfony 8’s Twig 3+:
    {# templates/TbmatukaEditorjs/Form/editorjs_widget.html.twig #}
    <div id="{{ id }}" class="editorjs-container">
        {{ form_widget(form) }}
    </div>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            initEditor('{{ id }}');
        });
    </script>
    
  • Use the editorjs() Twig function for inline configs:
    {{ editorjs(form.content.vars.config) }}
    

3. Encore Integration

  • Lazy-Load Plugins: Dynamically import plugins in your Encore entry file:
    const loadPlugin = async (pluginName) => {
        const module = await import(`@editorjs/${pluginName}`);
        return module.default || module;
    };
    
  • Editor Initialization: Attach to form submission events:
    document.querySelectorAll('.editorjs-form').forEach(form => {
        form.addEventListener('submit', (e) => {
            const editor = initEditor(form.dataset.editorId);
            const output = await editor.save();
            form.querySelector('[name="content"]').value = JSON.stringify(output);
        });
    });
    

4. Data Handling

  • Symfony 8 + Doctrine: Store JSON in a json column and use accessors:
    #[ORM\Column(type: 'json')]
    private $content;
    
    public function getContentAsArray(): array
    {
        return json_decode($this->content, true) ?: [];
    }
    
  • API Responses: Serialize Editor.js data for APIs:
    $data = $entity->getContentAsArray();
    return $this->json(['content' => $data]);
    

5. Plugin Management

  • Custom Tools: Create a custom tool and register it in the config:
    tbmatuka_editorjs:
        tools:
            custom_tool:
                class: App\Editorjs\CustomTool
                config: { /* tool-specific config */ }
    
  • Tool Configuration: Pass tool-specific configs in the form:
    $builder->add('content', EditorjsType::class, [
        'config' => [
            'tools' => [
                'custom_tool' => ['config' => ['option1' => true]],
            ],
        ],
    ]);
    

Integration Tips

  1. Symfony 8 Form Compatibility:

    • Test with Symfony 8’s new form components (e.g., FormBuilder::add() changes).
    • Use FormBuilder::createNamedBuilder() for nested forms with Editor.js.
  2. Frontend Asset Management:

    • For Encore, ensure @editorjs/editorjs and plugins are installed via npm.
    • For CDN/inline, manually initialize Editor.js in the Twig template:
      <script src="https://cdn.jsdelivr.net/npm/@editorjs/editorjs@latest"></script>
      <script>
          const EditorJS = window.EditorJS;
          new EditorJS({ /* config */ });
      </script>
      
  3. Performance Optimization:

    • Lazy-load plugins to reduce initial bundle size.
    • Cache Editor.js in production (e.g., via Symfony’s asset cache).
  4. Debugging:

    • Use Symfony’s profiler to inspect form data and Editor.js output.
    • Log JSON data before submission to verify structure:
      $form->handleRequest($request);
      if ($form->isSubmitted() && $form->isValid()) {
          $data = $form->getData();
          error_log('Editor.js data: ' . print_r($data, true));
      }
      
  5. Testing:

    • Test with Symfony’s form validation and Doctrine constraints.
    • Mock Editor.js in PHPUnit for unit tests:
      $this->getContainer()->get('twig')->addFunction(
          new \Twig\TwigFunction('editorjs', [$this, 'mockEditorjs'])
      );
      

Gotchas and Tips

Pitfalls

  1. Symfony 8-Specific Issues:

    • Twig Form Themes: Symfony 8 may require adjustments to the form theme path (e.g., form_div_layout.html.twig changes).
    • Form Builder Changes: Ensure compatibility with Symfony 8’s FormBuilder methods (e.g., add() vs. create()).
  2. Frontend Dependencies:

    • Encore Required: The bundle assumes Encore for JS asset management. CDN/inline setups are undocumented and may require custom workarounds.
    • Plugin Loading: Plugins must be installed via npm. No dynamic loading is supported out of the box, which can bloat your bundle.
  3. Data Handling:

    • JSON Validation: The bundle does not validate Editor.js output. Manual validation is required to prevent malformed JSON submissions.
    • Doctrine Integration: JSON data must be manually serialized/deserialized. No built-in Doctrine types are provided.
  4. Configuration Quirks:

    • Default Config Overrides: Configs passed in the form type override bundle defaults. Use array_merge to preserve defaults:
      $config = array_merge(
          $this->container->getParameter('tbmatuka_editorjs.default_config'),
          ['tools' => ['header']]
      );
      $builder->add('content', EditorjsType::class, ['config' => $config]);
      
    • Tool Class Names: Tools must match the npm package name (e.g., Header for @editorjs/header). Case-sensitive.
  5. Browser Compatibility:

    • Modern Browsers Only: Editor.js is not fully compatible with IE11. Test in your target browsers.
    • Polyfills: May require Promise or fetch polyfills for older browsers.

Debugging Tips

  1. Editor.js Not Initializing:
    • Check if the editorjs-init.js script is loaded and executed after the DOM is ready.
    • Verify the holder ID matches the Twig template’s output (e.g., `editor
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui