diff --git a/CHANGELOG.md b/CHANGELOG.md
index 202cafa..25a9b20 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,13 +1,27 @@
# Read-only Field Changelog
-## Unreleased
+## 2.0.0 - 2022-04-29
+
+### Added
+
+- Craft CMS 4 compatibility
+- php 8.1 compatibility
+- Support for Craft CMS 4 condition builder
+- Twig formatting of value in CP
+- The field is now sortable
+
### Changed
-- Fixed background color of icon
+
+- Requires Craft CMS >= 4.0 and php >= 8.0
## 1.0.1 - 2019-09-14
+
### Added
+-
- Support for Feed-Me plugin
## 1.0.0 - 2019-04-06
+
### Added
+-
- Initial release
diff --git a/README.md b/README.md
index b5464c0..bcfbe05 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Read-only Field for Craft CMS 3.x
+# Read-only Field for Craft CMS
![Icon](resources/readonly.png)
@@ -10,7 +10,7 @@ Sometimes you add content to Craft entries (for example via an API) that should
## Requirements
- * Craft CMS >= 3.0.0
+ * Craft CMS >= 4.0.0
## Installation
diff --git a/composer.json b/composer.json
index 2436610..06b46cc 100644
--- a/composer.json
+++ b/composer.json
@@ -1,7 +1,7 @@
{
"name": "codemonauts/craft-readonly-field",
"description": "Craft CMS plugin to add a simple, read-only plaintext field.",
- "version": "1.0.1",
+ "version": "2.0.0",
"type": "craft-plugin",
"keywords": [
"craft",
@@ -24,7 +24,8 @@
"issues": "https://github.com/codemonauts/craft-readonly-field/issues"
},
"require": {
- "craftcms/cms": "^3.0.0"
+ "craftcms/cms": "^4.0.0-alpha",
+ "php": "^8.0"
},
"autoload": {
"psr-4": {
@@ -33,10 +34,7 @@
},
"extra": {
"handle": "readonly",
- "class": "codemonauts\\readonly\\Readonly",
- "name": "Read-only Field",
- "description": "Simple, read-only plaintext field.",
- "hasCpSection": false,
- "hasSettings": false
+ "class": "codemonauts\\readonly\\ReadonlyPlugin",
+ "name": "Read-only Field"
}
}
diff --git a/resources/readonly.png b/resources/readonly.png
index 2164cef..ac51d1d 100644
Binary files a/resources/readonly.png and b/resources/readonly.png differ
diff --git a/src/Readonly.php b/src/ReadonlyPlugin.php
similarity index 74%
rename from src/Readonly.php
rename to src/ReadonlyPlugin.php
index c3b1619..6f32040 100644
--- a/src/Readonly.php
+++ b/src/ReadonlyPlugin.php
@@ -2,17 +2,20 @@
namespace codemonauts\readonly;
+use Craft;
use craft\base\Plugin;
use craft\events\RegisterComponentTypesEvent;
use craft\services\Fields;
use yii\base\Event;
-use codemonauts\readonly\fields\Readonly as ReadonlyField;
-use codemonauts\readonly\feedme\Readonly as ReadonlyFeedme;
+use codemonauts\readonly\fields\ReadonlyField;
+use codemonauts\readonly\feedme\ReadonlyField as ReadonlyFeedme;
use craft\feedme\events\RegisterFeedMeFieldsEvent;
use craft\feedme\services\Fields as FeedMeFields;
-class Readonly extends Plugin
+class ReadonlyPlugin extends Plugin
{
+ public string $schemaVersion = '1.0.1';
+
public function init()
{
parent::init();
@@ -22,7 +25,7 @@ public function init()
});
// Register field for feed-me plugin if installed
- if (\Craft::$app->plugins->isPluginEnabled('feed-me')) {
+ if (Craft::$app->plugins->isPluginEnabled('feed-me')) {
Event::on(FeedMeFields::class, FeedMeFields::EVENT_REGISTER_FEED_ME_FIELDS, function(RegisterFeedMeFieldsEvent $e) {
$e->fields[] = ReadonlyFeedme::class;
}
diff --git a/src/feedme/Readonly.php b/src/feedme/ReadonlyField.php
similarity index 86%
rename from src/feedme/Readonly.php
rename to src/feedme/ReadonlyField.php
index 348389d..5771907 100644
--- a/src/feedme/Readonly.php
+++ b/src/feedme/ReadonlyField.php
@@ -5,10 +5,10 @@
use craft\feedme\base\Field;
use craft\feedme\base\FieldInterface;
-class Readonly extends Field implements FieldInterface
+class ReadonlyField extends Field implements FieldInterface
{
public static $name = 'Read-only Field';
- public static $class = 'codemonauts\readonly\fields\Readonly';
+ public static $class = 'codemonauts\readonly\fields\ReadonlyField';
public function getMappingTemplate(): string
{
diff --git a/src/fields/Readonly.php b/src/fields/Readonly.php
deleted file mode 100644
index ea45b4a..0000000
--- a/src/fields/Readonly.php
+++ /dev/null
@@ -1,78 +0,0 @@
-columnType;
- }
-
- /**
- * @inheritdoc
- */
- public function getInputHtml($value, ElementInterface $element = null): string
- {
- return Craft::$app->getView()->renderTemplate('readonly/input',
- [
- 'name' => $this->handle,
- 'value' => $value,
- 'field' => $this,
- ]);
- }
-
- /**
- * @inheritdoc
- */
- public function serializeValue($value, ElementInterface $element = null)
- {
- if ($value !== null) {
- $value = LitEmoji::unicodeToShortcode($value);
- }
-
- return $value;
- }
-
- /**
- * @inheritdoc
- */
- public function getSearchKeywords($value, ElementInterface $element): string
- {
- $value = (string)$value;
- $value = LitEmoji::unicodeToShortcode($value);
-
- return $value;
- }
-}
diff --git a/src/fields/ReadonlyField.php b/src/fields/ReadonlyField.php
new file mode 100644
index 0000000..ca6fb19
--- /dev/null
+++ b/src/fields/ReadonlyField.php
@@ -0,0 +1,128 @@
+columnType;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function getInputHtml($value, ElementInterface $element = null): string
+ {
+ return Craft::$app->getView()->renderTemplate('readonly/input', [
+ 'name' => $this->handle,
+ 'value' => $value,
+ 'renderedValue' => $this->renderValue($value, $element),
+ 'field' => $this,
+ ]);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function serializeValue($value, ElementInterface $element = null): mixed
+ {
+ if ($value !== null) {
+ $value = LitEmoji::unicodeToShortcode($value);
+ }
+
+ return $value;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function getSearchKeywords($value, ElementInterface $element): string
+ {
+ $value = (string)$value;
+ return LitEmoji::unicodeToShortcode($value);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function getElementConditionRuleType(): ?string
+ {
+ return TextFieldConditionRule::class;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function getSettingsHtml(): ?string
+ {
+ return Craft::$app->getView()->renderTemplate('readonly/settings', [
+ 'field' => $this,
+ ]);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function getTableAttributeHtml(mixed $value, ElementInterface $element): string
+ {
+ return Html::encode(StringHelper::stripHtml($this->renderValue((string)$value, $element)));
+ }
+
+ /**
+ * @param string $value
+ * @param \craft\base\ElementInterface $element
+ *
+ * @return string
+ * @throws \Twig\Error\LoaderError
+ * @throws \Twig\Error\SyntaxError
+ */
+ private function renderValue(?string $value, ElementInterface $element): string
+ {
+ if ($this->template !== null) {
+ try {
+ $value = Craft::$app->getView()->renderString($this->template, [
+ 'value' => $value,
+ 'element' => $element,
+ ]);
+ } catch (Error) {
+ Craft::error('Error rendering template of read-only field with handle "' . $this->handle . '".', 'readonly');
+ }
+ }
+
+ return $value;
+ }
+}
diff --git a/src/icon-mask.svg b/src/icon-mask.svg
new file mode 100644
index 0000000..ae43d72
--- /dev/null
+++ b/src/icon-mask.svg
@@ -0,0 +1,10 @@
+
diff --git a/src/migrations/m220429_104217_change_class_name.php b/src/migrations/m220429_104217_change_class_name.php
new file mode 100644
index 0000000..e1d0adb
--- /dev/null
+++ b/src/migrations/m220429_104217_change_class_name.php
@@ -0,0 +1,34 @@
+getDb()->createCommand()
+ ->update(Table::FIELDS, ['type' => 'codemonauts\readonly\fields\ReadonlyField'], ['type' => 'codemonauts\readonly\fields\Readonly'])
+ ->execute();
+
+ return true;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function safeDown(): bool
+ {
+ echo "m220429_104217_change_class_name cannot be reverted.\n";
+ return false;
+ }
+}
diff --git a/src/templates/input.twig b/src/templates/input.twig
index b6968c0..b977676 100644
--- a/src/templates/input.twig
+++ b/src/templates/input.twig
@@ -1,2 +1,2 @@
-{{ value }}
+{{ renderedValue }}
diff --git a/src/templates/settings.twig b/src/templates/settings.twig
new file mode 100644
index 0000000..9aed44e
--- /dev/null
+++ b/src/templates/settings.twig
@@ -0,0 +1,10 @@
+{% import "_includes/forms" as forms %}
+
+{{ forms.textField({
+ label: "Template String"|t('readonly'),
+ instructions: "Twig template string for displaying the value in CP. If not set, the value is printed. You can use {{ value }} and {{ element }}."|t('readonly'),
+ id: 'template',
+ name: 'template',
+ value: field.template,
+ errors: field.getErrors('template')
+}) }}
\ No newline at end of file
diff --git a/src/translations/de/readonly.php b/src/translations/de/readonly.php
index ec66f66..9a46a43 100644
--- a/src/translations/de/readonly.php
+++ b/src/translations/de/readonly.php
@@ -2,4 +2,6 @@
return [
'Read-only Field' => 'Schreibgeschütztes Feld',
+ 'Template String' => 'Template String',
+ 'Twig template string for displaying the value in CP. If not set, the value is printed. You can use {{ value }} and {{ element }}.' => 'Twig Template für die Ausgabe im CP. Wenn nicht gesetzt wird der Wert ausgegeben. Es stehen {{ value }} und {{ element }} zur Verfügung.',
];