Best way to customize entry meta fields & data? #9797
-
We dont allow postDate to be set manually and force it to be set once and once only at the initial publication time. We also dont support allowing content to expire, so we force it to always be null. In support of these policies, we had customized the Entry UI to remove the post and expiry date fields from the meta fields section and add "Published at" to the meta data section. We did this by adding some jquery to the template to make these changes. Craft::$app->view->hook('cp.entries.edit', function() use ($entry) {
$selectorsToRemove = [];
// Remove the "Create a draft" button if there is already a draft;
// this only allows one draft at a time in most cases
$hasDraft =
// make sure this is the current version
!ElementHelper::isDraftOrRevision($entry)
// and that it has a draft already
&& Entry::find()->site($entry->site)->draftOf($entry)->exists();
if ($hasDraft) {
$selectorsToRemove[] = '#save-draft-btn-container';
}
// remove fields managed by the publication system
$selectorsToRemove[] = '#postDate-field';
$selectorsToRemove[] = '#expiryDate-field';
$selectorsToRemove[] = '#enabled-field';
return Craft::$app->view->renderTemplate(
'ltk-publication/_edit',
compact('entry', 'selectorsToRemove')
);
}); {% js on ready %}
{# remove certain elements that we do not want to display #}
$("{{ selectorsToRemove|join(',') }}").remove();
{# update the date area to display extra details #}
{% if entry.postDate %}
dateUpdated = $("#date-updated-value").parent();
datePosted = dateUpdated.clone().insertAfter(dateUpdated);
datePosted.find(".heading").text("{{ "Published at"|t('app') }}");
datePosted.find(".value").attr('id', 'post-date-value').text("{{ entry.postDate|datetime('short') }}");
{% endif %}
{% endjs %} This all worked fine until 3.7 which introduced the sidebar into the popup/slideout. Is there a better way to customize universally what is displayed in the meta area? I'm sure I can get something similar going for the slideout sidebar, but I'm wondering if there is a way to do this that is less hacky and a little more future-proof. Like if Element had an event for meta fields and meta data with them individually in an array of fields/data passed to the event and then that array could be modified. I tried using Yii dependency injection to replace the Entry class with an inherited class to override a couple methods, but that produced a bunch of runtime errors, like missing section id. 'container' => [
'definitions' => [
\craft\elements\Entry::class => modules\Entry::class
],
], |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
This is a little hacky, and can’t promise that it’s future-proof, but you can remove the Post Date and Expiry Date fields using the use craft\base\Element;
use craft\elements\Entry;
use craft\events\DefineHtmlEvent;
use craft\helpers\Html;
use yii\base\Event;
Event::on(
Entry::class,
Element::EVENT_DEFINE_SIDEBAR_HTML,
function(DefineHtmlEvent $event) {
$remove = ['postDate', 'expiryDate'];
foreach ($remove as $id) {
// Find the beginning of the field container
$id = preg_quote($id, '/');
if (preg_match("/<div\b[^\>]*id=\"$id-field\"/", $event->html, $matches, PREG_OFFSET_CAPTURE)) {
// Remove the entire div
$tag = Html::parseTag($event->html, $matches[0][1]);
$event->html = substr($event->html, 0, $tag['start']) . substr($event->html, $tag['end']);
}
}
}
); Adding a custom “Published at” metadata field can be done with use craft\base\Element;
use craft\elements\Entry;
use craft\events\DefineMetadataEvent;
use yii\base\Event;
use yii\i18n\Formatter;
Event::on(
Entry::class,
Element::EVENT_DEFINE_METADATA,
function(DefineMetadataEvent $event) {
/** @var Entry $entry */
$entry = $event->sender;
$event->metadata['Published at'] = function() use ($entry) {
return $entry->postDate
? Craft::$app->getFormatter()->asDatetime($entry->postDate, Formatter::FORMAT_WIDTH_SHORT)
: false;
};
}
); Unfortunately both of these will only affect entry editor slideouts for now, so you will need to keep your current code for modifying Edit Entry pages. Down the road the plan is to make them more unified. |
Beta Was this translation helpful? Give feedback.
This is a little hacky, and can’t promise that it’s future-proof, but you can remove the Post Date and Expiry Date fields using the
craft\base\Element::EVENT_DEFINE_SIDEBAR_HTML
event: