Skip to content

Commit c562aef

Browse files
committed
Craft 4 compatibility, refactoring, add twig template rendering, sortable
1 parent 3eeb12b commit c562aef

13 files changed

+217
-96
lines changed

CHANGELOG.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,27 @@
11
# Read-only Field Changelog
22

3-
## Unreleased
3+
## 2.0.0 - 2022-04-29
4+
5+
### Added
6+
7+
- Craft CMS 4 compatibility
8+
- php 8.1 compatibility
9+
- Support for Craft CMS 4 condition builder
10+
- Twig formatting of value in CP
11+
- The field is now sortable
12+
413
### Changed
5-
- Fixed background color of icon
14+
15+
- Requires Craft CMS >= 4.0 and php >= 8.0
616

717
## 1.0.1 - 2019-09-14
18+
819
### Added
20+
-
921
- Support for Feed-Me plugin
1022

1123
## 1.0.0 - 2019-04-06
24+
1225
### Added
26+
-
1327
- Initial release

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Read-only Field for Craft CMS 3.x
1+
# Read-only Field for Craft CMS
22

33
![Icon](resources/readonly.png)
44

@@ -10,7 +10,7 @@ Sometimes you add content to Craft entries (for example via an API) that should
1010

1111
## Requirements
1212

13-
* Craft CMS >= 3.0.0
13+
* Craft CMS >= 4.0.0
1414

1515
## Installation
1616

composer.json

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "codemonauts/craft-readonly-field",
33
"description": "Craft CMS plugin to add a simple, read-only plaintext field.",
4-
"version": "1.0.1",
4+
"version": "2.0.0",
55
"type": "craft-plugin",
66
"keywords": [
77
"craft",
@@ -24,7 +24,8 @@
2424
"issues": "https://github.com/codemonauts/craft-readonly-field/issues"
2525
},
2626
"require": {
27-
"craftcms/cms": "^3.0.0"
27+
"craftcms/cms": "^4.0.0-alpha",
28+
"php": "^8.0"
2829
},
2930
"autoload": {
3031
"psr-4": {
@@ -33,10 +34,7 @@
3334
},
3435
"extra": {
3536
"handle": "readonly",
36-
"class": "codemonauts\\readonly\\Readonly",
37-
"name": "Read-only Field",
38-
"description": "Simple, read-only plaintext field.",
39-
"hasCpSection": false,
40-
"hasSettings": false
37+
"class": "codemonauts\\readonly\\ReadonlyPlugin",
38+
"name": "Read-only Field"
4139
}
4240
}

resources/readonly.png

345 Bytes
Loading

src/Readonly.php renamed to src/ReadonlyPlugin.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@
22

33
namespace codemonauts\readonly;
44

5+
use Craft;
56
use craft\base\Plugin;
67
use craft\events\RegisterComponentTypesEvent;
78
use craft\services\Fields;
89
use yii\base\Event;
9-
use codemonauts\readonly\fields\Readonly as ReadonlyField;
10-
use codemonauts\readonly\feedme\Readonly as ReadonlyFeedme;
10+
use codemonauts\readonly\fields\ReadonlyField;
11+
use codemonauts\readonly\feedme\ReadonlyField as ReadonlyFeedme;
1112
use craft\feedme\events\RegisterFeedMeFieldsEvent;
1213
use craft\feedme\services\Fields as FeedMeFields;
1314

14-
class Readonly extends Plugin
15+
class ReadonlyPlugin extends Plugin
1516
{
17+
public string $schemaVersion = '1.0.1';
18+
1619
public function init()
1720
{
1821
parent::init();
@@ -22,7 +25,7 @@ public function init()
2225
});
2326

2427
// Register field for feed-me plugin if installed
25-
if (\Craft::$app->plugins->isPluginEnabled('feed-me')) {
28+
if (Craft::$app->plugins->isPluginEnabled('feed-me')) {
2629
Event::on(FeedMeFields::class, FeedMeFields::EVENT_REGISTER_FEED_ME_FIELDS, function(RegisterFeedMeFieldsEvent $e) {
2730
$e->fields[] = ReadonlyFeedme::class;
2831
}

src/feedme/Readonly.php renamed to src/feedme/ReadonlyField.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
use craft\feedme\base\Field;
66
use craft\feedme\base\FieldInterface;
77

8-
class Readonly extends Field implements FieldInterface
8+
class ReadonlyField extends Field implements FieldInterface
99
{
1010
public static $name = 'Read-only Field';
11-
public static $class = 'codemonauts\readonly\fields\Readonly';
11+
public static $class = 'codemonauts\readonly\fields\ReadonlyField';
1212

1313
public function getMappingTemplate(): string
1414
{

src/fields/Readonly.php

Lines changed: 0 additions & 78 deletions
This file was deleted.

src/fields/ReadonlyField.php

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
<?php
2+
3+
namespace codemonauts\readonly\fields;
4+
5+
use Craft;
6+
use craft\base\ElementInterface;
7+
use craft\base\Field;
8+
use craft\base\PreviewableFieldInterface;
9+
use craft\base\SortableFieldInterface;
10+
use craft\fields\conditions\TextFieldConditionRule;
11+
use craft\helpers\Html;
12+
use craft\helpers\StringHelper;
13+
use LitEmoji\LitEmoji;
14+
use Twig\Error\Error;
15+
use yii\db\Schema;
16+
17+
class ReadonlyField extends Field implements PreviewableFieldInterface, SortableFieldInterface
18+
{
19+
/**
20+
* @var string The type of database column the field should have in the content table
21+
*/
22+
public string $columnType = Schema::TYPE_STRING;
23+
24+
/**
25+
* @var string|null The template to render the value
26+
*/
27+
public ?string $template = null;
28+
29+
/**
30+
* @inheritdoc
31+
*/
32+
public static function displayName(): string
33+
{
34+
return Craft::t('readonly', 'Read-only Field');
35+
}
36+
37+
/**
38+
* @inheritdoc
39+
*/
40+
public function getContentColumnType(): string
41+
{
42+
return $this->columnType;
43+
}
44+
45+
/**
46+
* @inheritdoc
47+
*/
48+
public function getInputHtml($value, ElementInterface $element = null): string
49+
{
50+
return Craft::$app->getView()->renderTemplate('readonly/input', [
51+
'name' => $this->handle,
52+
'value' => $value,
53+
'renderedValue' => $this->renderValue($value, $element),
54+
'field' => $this,
55+
]);
56+
}
57+
58+
/**
59+
* @inheritdoc
60+
*/
61+
public function serializeValue($value, ElementInterface $element = null): mixed
62+
{
63+
if ($value !== null) {
64+
$value = LitEmoji::unicodeToShortcode($value);
65+
}
66+
67+
return $value;
68+
}
69+
70+
/**
71+
* @inheritdoc
72+
*/
73+
public function getSearchKeywords($value, ElementInterface $element): string
74+
{
75+
$value = (string)$value;
76+
return LitEmoji::unicodeToShortcode($value);
77+
}
78+
79+
/**
80+
* @inheritdoc
81+
*/
82+
public function getElementConditionRuleType(): ?string
83+
{
84+
return TextFieldConditionRule::class;
85+
}
86+
87+
/**
88+
* @inheritdoc
89+
*/
90+
public function getSettingsHtml(): ?string
91+
{
92+
return Craft::$app->getView()->renderTemplate('readonly/settings', [
93+
'field' => $this,
94+
]);
95+
}
96+
97+
/**
98+
* @inheritdoc
99+
*/
100+
public function getTableAttributeHtml(mixed $value, ElementInterface $element): string
101+
{
102+
return Html::encode(StringHelper::stripHtml($this->renderValue((string)$value, $element)));
103+
}
104+
105+
/**
106+
* @param string $value
107+
* @param \craft\base\ElementInterface $element
108+
*
109+
* @return string
110+
* @throws \Twig\Error\LoaderError
111+
* @throws \Twig\Error\SyntaxError
112+
*/
113+
private function renderValue(?string $value, ElementInterface $element): string
114+
{
115+
if ($this->template !== null) {
116+
try {
117+
$value = Craft::$app->getView()->renderString($this->template, [
118+
'value' => $value,
119+
'element' => $element,
120+
]);
121+
} catch (Error) {
122+
Craft::error('Error rendering template of read-only field with handle "' . $this->handle . '".', 'readonly');
123+
}
124+
}
125+
126+
return $value;
127+
}
128+
}

src/icon-mask.svg

Lines changed: 10 additions & 0 deletions
Loading
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
namespace codemonauts\readonly\migrations;
4+
5+
use Craft;
6+
use craft\db\Migration;
7+
use craft\db\Table;
8+
9+
/**
10+
* m220429_104217_change_class_name migration.
11+
*/
12+
class m220429_104217_change_class_name extends Migration
13+
{
14+
/**
15+
* @inheritdoc
16+
*/
17+
public function safeUp(): bool
18+
{
19+
$this->getDb()->createCommand()
20+
->update(Table::FIELDS, ['type' => 'codemonauts\readonly\fields\ReadonlyField'], ['type' => 'codemonauts\readonly\fields\Readonly'])
21+
->execute();
22+
23+
return true;
24+
}
25+
26+
/**
27+
* @inheritdoc
28+
*/
29+
public function safeDown(): bool
30+
{
31+
echo "m220429_104217_change_class_name cannot be reverted.\n";
32+
return false;
33+
}
34+
}

src/templates/input.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
<strong>{{ value }}</strong>
1+
<strong>{{ renderedValue }}</strong>
22
<input name="{{ name }}" type="hidden" value="{{ value }}" />

src/templates/settings.twig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{% import "_includes/forms" as forms %}
2+
3+
{{ forms.textField({
4+
label: "Template String"|t('readonly'),
5+
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'),
6+
id: 'template',
7+
name: 'template',
8+
value: field.template,
9+
errors: field.getErrors('template')
10+
}) }}

src/translations/de/readonly.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22

33
return [
44
'Read-only Field' => 'Schreibgeschütztes Feld',
5+
'Template String' => 'Template String',
6+
'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.',
57
];

0 commit comments

Comments
 (0)