cli icon indicating copy to clipboard operation
cli copied to clipboard

Clean content command removes field values from fields defined in plugins

Open morja opened this issue 2 months ago • 10 comments

I have a plugin that defines a tab with fields in its own blueprint. The tab is added to my page blueprint.

When I run the kirby clean:content command, it removes the values from those fields from the plugin.

Also, interestingly in one case it changed a page field's value from true to false.

And it creates translation version of all pages, which is not really wanted.

It would be great to have an option to make it omit fields that have a value and/or provide a list of fields to skip.

Image

morja avatar Oct 26 '25 12:10 morja

The clean:content command is made to clean all fields that are not defined in the blueprint. So it is intended that fields that are not detected from the blueprint are removed. However I see three potential bugs:

  1. Somehow Kirby did not detect your field that was defined in the plugin tab.
  2. Somehow the value of the Inmenu field was changed.
  3. Somehow the Metakitseo field was cleared, but not removed (I would have expected the field to be removed entirely if Kirby cleans it because of bug 1).

@morja Could you please share your blueprints and a simple reduced test case of your plugin so we can reproduce this behavior? @afbora Could you please debug this with the additional info?

lukasbestle avatar Oct 26 '25 17:10 lukasbestle

Sure, I created a stripped down version of the plugin and tested it with the kirby plainkit. It reproduces issue 1/3. Just use the attached default blueprint and go to the homepage and add some metadata and safe it. Then run cleanup.

meta-kit.zip default.yml

Issue 2) may have another reason. I found out, that the content file in this case has a name of a none existent template. But it uses the default template as a fallback and works fine in the panel and everywhere. Only in this file the Inmenu was changed from true to false.

morja avatar Oct 26 '25 18:10 morja

Thanks @morja, I can reproduce the issue with your kit.

afbora avatar Oct 26 '25 20:10 afbora

@morja I couldn't see the Inmenu field in your default blueprint. Could you also share with us that field props please?

afbora avatar Oct 26 '25 20:10 afbora

I think I've found the issue: content field names are lowercase and blueprint field names are camelCase. Maybe @distantnative have an idea about that as author of the command.

I'll more digging after @morja share other field props.

afbora avatar Oct 26 '25 20:10 afbora

I added the Inmenu field:

default.yml

Going to the homepage, turning it to on and then running cleanup will turn it to false in home.txt.

My suspicion with the template name turns out wrong. It actually always turns this toggle field from true to false.

morja avatar Oct 26 '25 21:10 morja

Just for my understanding, content->getFields() should already return lowercase as all keys are lowercased in \Kirby\Content\Content::get.

As far as I can see, lowercasing the blueprint fields is the actual fix. But the the whole logic with lowercaseToOriginal doesn't really do anything. I tested it without that part and it still works the same for me.

And I found another issue with this change. For some reason when The site content has no changes ($fieldsToBeDeleted is empty) the script now deletes the first page it finds and stops with Storage for the page is immutable and cannot be updated. Make sure to use the last alteration of the object.

If I remove the check and always execute update it works:

	$data = [];
	foreach ($fieldsToBeDeleted as $lowercaseField) {
		$data[$lowercaseField] = null;
	}
	$item->update($data, $lang);

morja avatar Nov 02 '25 11:11 morja

@afbora ping

distantnative avatar Nov 02 '25 11:11 distantnative

@morja Yes, you're right about content fields being lowercase. I've already mentioned in previous comment that content fields are lowercase and blueprint fields are camelcase. I applied to lowercase both just to be sure :) We can only apply this to blueprint fields.

Regarding the immutable error, I couldn't reproduce the issue. Could you list the steps I need to take to reproduce this error?

afbora avatar Nov 03 '25 06:11 afbora

@afbora great. And sure. So my setup is the following:

I have a site.en.txt (multi language site). And a 1_home/default.en.txt. If both have obsolete fields, it works fine, it removes them and saves both. But if site.en.txt doesn't have any obsolete fields (no changes to be saved) and home has, then I get the immutable error and it will delete 1_home/default.en.txt.

morja avatar Nov 03 '25 10:11 morja

@afbora could you have another look at it?

bastianallgeier avatar Nov 17 '25 11:11 bastianallgeier

@bastianallgeier I'm on it.

afbora avatar Nov 17 '25 16:11 afbora