Skip to content

WY Image Plugin for Redactor

Status: Production Ready
Version: 1.0.0
Last Updated: January 2025

The WY Image plugin enables rich image insertion in the Redactor editor with full ImageKit transformation support. Users can select images from the library, customize cropping/sizing/effects, and insert optimized images with proper srcset attributes for responsive delivery.

┌──────────────┐ Select ┌──────────────────┐ Configure ┌─────────────────┐
│ WY Image │─────────────►│ Image Picker │──────────────►│ Image Options │
│ Toolbar Btn │ │ Modal │ │ Editor Modal │
└──────────────┘ └──────────────────┘ └────────┬────────┘
┌──────────────────┐ │ Insert
│ oEmbed API │◄───────────────────────┘
│ /api/v1/oembed │
│ /image │
└────────┬─────────┘
┌────────▼─────────┐
│ ImageKit URL │
│ with transforms │
└──────────────────┘
  • Search modes: Keyword, AI semantic, Hybrid
  • Filters: Tags, source, colorspace, dimensions, product line
  • Tom Select: Searchable multi-select dropdowns
  • Infinite scroll: Loads more results on scroll
  • Filter badge: Shows count of active filters
TabOptions
BasicCaption, alt text, size presets, custom dimensions
CropVisual cropping with Cropper.js
AdvancedFormat, quality, blur, border, background color, lazy loading, srcset
  • Preview updates in real-time as options change
  • ImageKit URL displayed and copy-able
  • Lightbox for full-size preview

Images are inserted via an internal oEmbed endpoint that generates the full HTML:

<figure class="wy-image-embed" data-wy-image-id="12345" data-wy-image-options='{"width":800}'>
<img src="https://ik.warmlyyours.com/img/..."
srcset="..."
sizes="..."
alt="..."
class="img-fluid"
loading="lazy">
<figcaption class="figure-caption">Optional caption</figcaption>
</figure>
  1. Click WY Image button in toolbar
  2. Search/filter to find the image
  3. Click image thumbnail to select
  4. Configure options in the editor modal
  5. Click Insert Image
  1. Click on an embedded image in the editor
  2. Select WY Image from context menu
  3. Modify options in the editor modal
  4. Click Update Image
PresetDimensionsUse Case
Small400pxThumbnails, inline
Medium800pxStandard content
Large1200pxHero images
Full Width2000pxFull-bleed layouts
CustomUser-definedSpecific requirements

The visual cropper uses Cropper.js with coordinate scaling:

// Coordinates are scaled from displayed size to original dimensions
const scaleX = originalWidth / displayedWidth
const scaleY = originalHeight / displayedHeight
cropParams = {
x: Math.round(cropData.x * scaleX),
y: Math.round(cropData.y * scaleY),
w: Math.round(cropData.width * scaleX),
h: Math.round(cropData.height * scaleY)
}
OptionDescriptionValues
FormatOutput formatAuto, JPEG, PNG, WebP, AVIF
QualityCompression1-100 (default: 80)
BlurGaussian blur0-100
BorderBorder width0-20px
Border ColorBorder colorHex color
BackgroundPad colorHex color
Lazy LoadNative lazy loadingOn/Off
Include srcsetResponsive imagesOn/Off
GET /redactor/image_picker_modal
Parameters:
- callback: JavaScript callback function name
GET /redactor/image_options_modal
Parameters:
- image_id: Selected image ID
- callback: JavaScript callback function name
- caption: Pre-fill caption (for editing)
- alt: Pre-fill alt text (for editing)
GET /api/v1/oembed/image
Parameters:
- image_id: Image record ID
- caption: Figure caption
- alt: Alt text
- width: Max width
- height: Max height
- crop_x, crop_y, crop_w, crop_h: Crop region
- format: Output format
- quality: Compression quality
- blur: Blur amount
- border: Border width
- border_color: Border color
- background: Background color
- lazy: Enable lazy loading
- srcset: Include srcset attribute
FilePurpose
client/js/common/wyimage4.jsRedactor plugin
app/javascript/controllers/image_picker_controller.jsPicker modal logic
app/javascript/controllers/image_editor_controller.jsOptions editor logic
app/views/crm/redactor_image_picker/_modal.html.erbPicker modal view
app/views/crm/redactor_image_picker/_options_modal.html.erbOptions modal view
app/controllers/crm/redactor_image_picker_controller.rbModal endpoints
app/controllers/api/v1/oembed_controller.rboEmbed endpoint
app/services/oembed/image_provider.rbImage HTML generation

Targets:

  • searchInput, results, loading
  • modeButton, modeIcon, searchButton
  • filterBadge, tagsFilter, excludeTagsFilter
  • sourceFilter, colorspaceFilter, productLineFilter
  • minWidthFilter, minHeightFilter

Values:

  • callback: Callback function name
  • searchUrl: Image search endpoint
  • searchMode: keyword | ai | hybrid
  • placeholders: Mode-specific placeholder text
  • icons: Mode-specific icons

Targets:

  • preview, urlDisplay, urlCopied, copyBtn
  • caption, alt, sizePreset, customDimensions
  • width, height, lockAspect, link, linkTarget
  • cropperContainer, cropperImage, cropInfo
  • format, quality, qualityValue, blur, blurValue
  • border, borderColor, bgColor, lazyload, includeSrcset

Values:

  • imageId: Selected image ID
  • imageUrl: Full image URL
  • baseUrl: Raw ImageKit URL
  • imageWidth, imageHeight: Original dimensions
  • imageAlt: Default alt text
  • callback: Insert callback function name

Cause: oEmbed endpoint error
Fix: Check browser console for API errors, verify image_id is valid

Cause: Coordinate scaling mismatch
Fix: Ensure original dimensions are passed via data attributes

Cause: Debounce delay or missing target
Fix: Check updatePreview() is called and targets exist

Cause: DOM not ready when controller connects
Fix: Ensure Tom Select controller is on the select element