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

Fieldtype Richtext Laravel Package

ibexa/fieldtype-richtext

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require ibexa/fieldtype-richtext
    

    Requires Ibexa DXP as a dependency.

  2. Field Type Registration: Register the ibexa_richtext field type in your ContentType definition (e.g., config/content_types/my_content_type.yaml):

    fieldDefinitions:
        my_richtext_field:
            type: ibexa_richtext
            config:
                toolbar: ["bold", "italic", "link", "image"]
    
  3. First Use Case:

    • Create a content type with the ibexa_richtext field.
    • Use the field in a form or admin interface to input formatted text (e.g., CKEditor UI).
    • Retrieve the stored XML data via:
      $content = $contentService->loadContent($contentId);
      $value = $content->getFieldValue('my_richtext_field');
      $xmlData = $value->xml; // Raw XML content
      

Implementation Patterns

Core Workflows

  1. Field Configuration:

    • Define toolbars, allowed HTML tags, and custom plugins in config:
      config:
          toolbar: ["bold", "italic", "link", "image", "table"]
          allowedTags: ["p", "h1", "h2", "a", "img", "table"]
          customTags: ["alert", "highlight"]
      
    • Extend the RNG schema for custom validation:
      // config/ibexa/fieldtypes/richtext/ezpublish.rng
      <define name="my_custom_tag">
          <element name="alert">
              <attribute name="type">
                  <choice>info</choice>
                  <choice>warning</choice>
              </attribute>
              <text/>
          </element>
      </define>
      
  2. Data Handling:

    • Storing: Use the field type’s API to save formatted content:
      $fieldValue = new FieldValue();
      $fieldValue->value = $xmlContent;
      $content->setFieldValue('my_richtext_field', $fieldValue);
      $contentService->saveContent($content);
      
    • Rendering: Convert XML to HTML for display:
      use Ibexa\Contracts\FieldType\RichText\Value;
      $value = $content->getFieldValue('my_richtext_field');
      $html = (new Value())->html($value->value); // Renders HTML
      
  3. Custom Plugins:

    • Extend the editor with custom buttons/plugins (e.g., for embeds or custom tags):
      // resources/js/richtext-plugins.js
      CKEDITOR.plugins.add('myPlugin', {
          init: function(editor) {
              editor.addCommand('myCommand', {
                  exec: function() {
                      editor.insertHtml('<div class="my-custom-class">Custom Content</div>');
                  }
              });
              editor.ui.addButton('MyButton', {
                  label: 'My Plugin',
                  command: 'myCommand'
              });
          }
      });
      
    • Register the plugin in config/ibexa/fieldtypes/richtext/config.yml:
      plugins:
          myPlugin:
              path: /bundles/yourbundle/js/richtext-plugins.js
      
  4. Validation:

    • Validate custom tags/styles against the RNG schema:
      $validator = new \Ibexa\RichText\Validator\CustomTagsValidator();
      $isValid = $validator->validate($xmlContent);
      
  5. SiteAccess-Specific Config:

    • Override toolbar/config per SiteAccess:
      # config/siteaccess/my_siteaccess/fieldtypes/richtext.yml
      toolbar: ["bold", "italic"] # Overrides global config
      

Gotchas and Tips

Pitfalls

  1. XML Storage:

    • The field stores content as XML, not raw HTML. Use Value::html() to render it safely.
    • Avoid direct HTML injection; sanitize inputs via the field type’s API.
  2. Editor Initialization:

    • Ensure CKEditor assets (JS/CSS) are properly enqueued. Use Ibexa’s Encore for asset management:
      // webpack.config.js
      Encore
          .enableSingleRuntimeChunk()
          .addEntry('richtext', './resources/js/richtext.js')
          .copyFiles({
              from: './resources/public/ckeditor',
              to: 'build/ckeditor/[name].[ext]'
          });
      
    • Clear cache after adding custom plugins:
      php bin/console cache:clear
      
  3. Custom Tag Quirks:

    • Custom tags (e.g., <alert>) must be defined in the RNG schema and registered in the editor config.
    • Empty inline custom tags (e.g., <highlight></highlight>) may render incorrectly; ensure non-empty content or use minOccurs="0" in the schema.
  4. Link Handling:

    • Links to internal content require SiteAccess selection. Use the Link plugin with:
      config:
          link:
              siteAccesses: [site1, site2] # Restrict to specific SiteAccesses
      
  5. Performance:

    • Large XML payloads (e.g., deeply nested tables) may slow down the editor. Optimize by:
      • Limiting allowed tags.
      • Using lazy-loading for images/media.
  6. Debugging:

    • Editor Issues: Check browser console for CKEditor errors. Verify plugin paths in config.yml.
    • XML Validation: Use libxml_use_internal_errors(true) to debug RNG schema errors:
      $doc = new DOMDocument();
      $doc->loadXML($xmlContent);
      libxml_use_internal_errors(true);
      $doc->schemaValidate('path/to/ezpublish.rng');
      $errors = libxml_get_errors();
      

Tips

  1. Reusable Configs:

    • Share toolbar configs across content types via extends in YAML:
      fieldDefinitions:
          body:
              type: ibexa_richtext
              config:
                  extends: "@ibexa/fieldtypes/richtext/config/base.yml"
                  toolbar: ["bold", "italic", "link"]
      
  2. Custom CSS:

    • Add custom stylesheets to the editor:
      config:
          stylesheets:
              - { uri: "/bundles/yourbundle/css/richtext-styles.css" }
      
  3. Fallback Config:

    • Provide fallback configs for missing SiteAccesses:
      config:
          fallback: "@ibexa/fieldtypes/richtext/config/default.yml"
      
  4. Testing:

    • Test custom tags/plugins in isolation using Ibexa’s FieldTypeTest base class:
      public function testCustomTagRendering() {
          $value = new FieldValue();
          $value->value = '<alert type="warning">Test</alert>';
          $html = (new Value())->html($value->value);
          $this->assertStringContainsString('class="alert warning"', $html);
      }
      
  5. Migration Notes:

    • Upgrading from v4 to v5? Check for breaking changes in release notes. Key changes:
      • Symfony 7.4 LTS support (v5.0.7+).
      • Updated CKEditor version (may require plugin updates).
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity