An open-source Sulu bundle providing a custom image crop content type with an integrated React component for intuitive image cropping.
This bundle allows you to seamlessly select, crop, and manage images within the Sulu Admin. It augments the default Sulu Media handling by introducing a specialized image_crop
field type, powered by a custom React component.
Requirement | Version |
---|---|
PHP | ^8.2 |
Sulu | ^2.6 |
Node | ^20 |
composer require smartlabsat/sulu-image-crop-content-type
mkdir -p assets/admin
bin/console sulu:admin:download-build
cd assets/admin
npm install
npm install file:../../vendor/smartlabsat/sulu-image-crop-content-type/Resources/js
// /assets/admin/app.js
// Add project specific javascript code and import of additional bundles here:
import 'sulu-smartlabsat-image-crop-bundle';
Build your admin assets
npm run build
Once everything is installed, you can use the image_crop type in your Sulu templates or pages:
<property name="composite" type="image_crop">
<params>
<param name="previewCrop" value="300x"/>
</params>
</property>
Note: The previewCrop parameter controls the thumbnail size that appears in the admin interface (e.g., 300x). Example Template Configuration
config/templates/pages/imagecroppage.xml
<?xml version="1.0"?>
<template xmlns="http://schemas.sulu.io/template/template"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://schemas.sulu.io/template/template http://schemas.sulu.io/template/template-1.0.xsd">
<key>image_crop_page</key>
<view>pages/image_crop_page</view>
<controller>Sulu\Bundle\WebsiteBundle\Controller\DefaultController::indexAction</controller>
<meta>
<title lang="en">Image Crop Page</title>
</meta>
<properties>
<property name="title" type="text_line" colspan="12">
<meta>
<title lang="en">Title</title>
</meta>
</property>
<property name="url" type="resource_locator" colspan="12">
<tag name="sulu.rlp"/>
<meta>
<title lang="en">URL</title>
</meta>
</property>
<property name="composite" type="image_crop">
<params>
<param name="previewCrop" value="300x"/>
</params>
</property>
</properties>
</template>
templates/pages/image_crop_page.html.twig
{% block content %}
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Image Cropper Demo</title>
<!-- Bulma CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
<!-- Font Awesome for Icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
integrity="sha512-p0p+65dAxpkrv+7c6Wbb5e9s6RO7XlOQhvfA4CTp6GAGcJZUT1kn2SZig0wYxumCAtdIsP+S3f+q1D1r5u0xig=="
crossorigin="anonymous" referrerpolicy="no-referrer"/>
<style>
.image-container {
display: flex;
justify-content: center;
}
.component-title {
display: flex;
align-items: center;
gap: 0.5rem;
}
.image-container img {
max-width: 100%;
height: auto;
}
</style>
</head>
<body>
<section class="section">
<div class="container">
<div class="level">
<div class="level-left">
<div class="level-item">
<h1 class="title component-title">
<span class="icon is-large">
<i class="fas fa-crop fa-2x"></i>
</span>
<span>{{ content.title }}</span>
</h1>
</div>
</div>
</div>
{% set composite = content.composite|default({}) %}
{% set media = composite.media|default(null) %}
{% if media %}
<div class="box">
<figure class="image image-container">
{% set cropKey = '300x' %}
<img src="{{ media.thumbnails[cropKey]|default('') }}" alt="Image Cropper Demo"/>
</figure>
</div>
{% endif %}
</div>
</section>
<script src="https://cdn.jsdelivr.net/npm/@material-ui/styles@4.11.5/index.min.js"></script>
</body>
</html>
{% endblock %}
If you haven’t defined any image crops in your project yet, please refer to Sulu Docs on Image Formats.
Below is a simplified overview of the React component that powers the cropping interface: • ImageCropContentType class • Utilizes Sulu’s SingleSelectionStore to manage the selected media • Integrates Sulu’s CropOverlay for the cropping functionality • Offers convenient Select, Crop, Edit, Refresh, and Remove actions • Automatically handles reloading the image to ensure the newest cropped version is displayed
Error: There is no field with key “image_crop” registered… If you see this error in the Sulu Admin, it usually means your Admin frontend build wasn’t run correctly. Please re-check the steps:
- Execute npm install (and the npm install file:../../vendor/...) in the assets/admin folder.
- Make sure you import 'sulu-smartlabsat-image-crop-bundle' in your app.js.
- Finally, run npm run build.
Licensed under the MIT license. Feel free to use, modify, and distribute this software according to the terms of the license.
If you have any questions, feel free to open an issue or pull request!