Problem/Motivation

Port of Paragraphs to Drupal 8 is now available on Drupal.org.

Proposed resolution

It needs some more fixing.

Remaining tasks

- Test coverage
- Fix revision support in core
- Probably something I forgot.

User interface changes

API changes

Original report

There was the intention to port this module within GSoC 2014. This didn't happen though.
Did anyone start with a Drupal 8 port?

Comments

jeroen.b’s picture

One of my colleagues started working on a port, I'll ask him to post the status here.

miro_dietiker’s picture

Thank you for the update. Great to hear this!
A link to some early repo for testing, typically on github would be best.

lennard westerveld’s picture

Hello miro_dietiker,

I has created a entity + view mode options for Drupal 8.
Thing is i'm now creating the paragraphs field that takes a bit more time.

When its testable i will push it to github.

lennard westerveld’s picture

Status update:
I started again for scratch and now i have the paragraphs_type working.
Now its starting to make the Paragraphs_item entity working with entity reference field.
After that we can make a formatter for the reference field so there can be inline editing etc.

At the moment i have pushed things to github and cloned from drupal.org so we can merge it later back.

Github url: https://github.com/LennardWesterveld/paragraphs-d8

duaelfr’s picture

Hi ! I'll try to continue your work during the BADCamp (6th to 9th of november). Prepare for a big pull request ;)

lennard westerveld’s picture

Thanks, we will prepare for it!

duaelfr’s picture

Pull request sent.
https://github.com/LennardWesterveld/paragraphs-d8/pull/1

I wish I had time to do more but that's a good start I think.

lennard westerveld’s picture

Thank you DuaelFr. We will look into the merge request this weekend or next week.

sachbearbeiter’s picture

hello,

thanks for working on this ...
make it sense to install and test?

regards sb

duaelfr’s picture

I don't think it's ready to test yet.

jeroen.b’s picture

I made quite some progress this weekend:
I'm currrently working to give it the same functionality as the Drupal 7 module.

What we got working now:
- Paragraph types can be made
- You can add a Entity Reference field with Reference type "Paragraphs"
- You can define the same settings as in D7 (edit mode / add mode / titles / bundles)
- You can create/edit/delete/sort items when you use the widget "Paragraphs"
- You can use edit modes, you can start with open/closed/preview items. Preview will render the paragraphs item in the preview view mode
- Items display properly when using the "Rendered entity" formatter

What needs to be done:
- Add mode (list or button) is not supported yet, both will end up in a list
- Sortable table for the paragraph types
- Proper entity access implementation
- Some theme suggestions for easy theming
- Probably more stuff thats not working correctly yet

matglas86’s picture

Issue summary: View changes
sachbearbeiter’s picture

i will test ;)

thanks sb

sachbearbeiter’s picture

sweet - as first feedback - had no errors so far ...

jeroen.b’s picture

I got some major work done today:
- Add mode (list or button) works properly now
- You can now sort the bundle order in the field settings
- I moved most of the settings (except the bundle selection) to the widget settings.
- I implemented entity access
- I did some theme implementations for easier theming (default template and template suggestions).
- I recreated the Paragraphs Bundle Permissions (it now uses hook_paragraphs_item_access and hook_paragraphs_create_access which are triggered by core).
- Fixed #limit_validation_errors (for example: you couldn't press Remove Paragraph item when you had empty fields that are required).
- You can now select a Form display mode in the widget settings.

New tasklist:
- Fix "The value can not be null" error. (might had to do with #limit_validation_errors)
- Publish on Drupal.org

I think D8 has the same functionality as D7 now, so, yay!

jeroen.b’s picture

Issue summary: View changes
sachbearbeiter’s picture

still no problems (but this is not a deep investigation yet ;)

but one small remark
paragraphs-item.html.twig
places

{%
set classes = [
'paragraphs-item',
'paragraphs-item--type--' ~ paragraphs_item.bundle|clean_class,
view_mode ? 'paragraphs-item--view-mode--' ~ view_mode|clean_class,
]
%}
<article{{ attributes.addClass(classes) }}>

    <div{{ content_attributes.addClass('paragraphs-item--content') }}>
        {{ content }}
    </div>

</article>

i could imagine, that the tag here confuses as the default the document outline of some frontend developers ...

duaelfr’s picture

I agree.
<article> should only be used by the host entity. As paragraphs are made to be parts of another entity, I suggest to simply use a <div> tag here.

jeroen.b’s picture

Yeah you are right. I copied the template from the node module.
I removed the element now, it's just the div now.

I also changed the UX a bit of the edit/delete buttons, let me know what you think.
I also added a new mode for the Add another Paragraph button: "Dropdown button".

I couldn't replicate the "The value can not be null" error anymore, so I think it's fixed already.

I just pushed 8.x-1.x to Drupal.org and created a release so 8.x-1.x-dev should pop up soon.
Also writing some documentation now.

berdir’s picture

Had a quick look at the code because of http://drupal.stackexchange.com/questions/144815/custom-node-field-type-...

(Please correct me there if I said anything that is not correct).

Noticed some minor things:
- You can use the isApplicable() method on the widget to make it available lust for paragraphs.
- I'm not sure what the vid() method on ParagraphsItem is supposed to, but I don't think it does what you meant it to. the default method for getting the revision ID is getRevisionId().
- I would also recommend to name the revision field revision_id or so, Node is a bad example there IMHO.
- The "If no owner has been set explicitly, make the current user the owner." in preSave() should not be necessary, you have the default value callback that should take care of that.

jeroen.b’s picture

- The widget should also work for other entities, so I rather not isApplicable implement it yet.
- You are right, vid() is wrong, I removed it now as I wasn't using it.
- Would it really matter to use vid or revision_id? Why does node use vid?
- I did not add the ['uid'] and ['revision_uid'] fields, so I will have to look into that later.

Also:

From looking at the code, the module does not define a field type. It just defines a widget for entity reference fields.

So, what you need to create instead is an entity reference field that points to paragraphs, and then select the Paragraps widget on "Manage form display".

But that should be exactly the same for nodes as well?

You are right in that post, I added some information to the project page and a quick how-to-start in Drupal 8.

berdir’s picture

No, technically, it doesn't matter. You can name your revision ID banana, as long as you specify it the entity keys in the annotation. I just think vid is a bad name, but we unfortunately never got to the point to unify/rename field names in core entities. It also clashes with the vocabulary id (vid).

The nice thing about the fact that D8 does not support an upgrade path, just a migration is that you can rename things and it will not make it any harder to migrate. Now is the best (and maybe last, for D8) time to give all your things good names.

jeroen.b’s picture

Yeah, you are right, I changed it to revision_id now.

Also, regarding http://drupal.stackexchange.com/questions/144815/custom-node-field-type-...
I just tested it with my instruction list "How to start in Drupal 8" on the block entity, it works the same way as node there and also works properly.

jeroen.b’s picture

Also, I just checked, the "If no owner has been set explicitly, make the current user the owner." is copied from the node module. I'm not sure why it's in there.
Node also has the DefaultValueCallback though.

duaelfr’s picture

I think that the initial port has been based on the node module. I've seen that when I worked on it at BADCamp.
I suppose that when the port started, there was not much documentation about how to write a module on D8.

jeroen.b’s picture

I'll just leave it in for now and check if anything changed regarding to that in the node module when a new version comes out.

sachbearbeiter’s picture

@jeroen.b @Berdir - thanks a lot for your help and development work (and to be persistent in the interaction with confused users ;)

miro_dietiker’s picture

This sounds awesome. Thank you for the great work!

Two questions:
- Can you provide a statement about status of test coverage?
- How about multilingual entities / translation UX?

I will also look into paragraphs soon and check all use cases we know of...
Preferrably i do so after migrating to d.o since i can then "SPAM the queue" with separated issues (issues, thoghts, UX review, ...) instead of huge review text blocks that are probably way out of scope of the (initial) port.

jeroen.b’s picture

- Test coverage is 0%, but it's definitely on the planning and I hope I get to it before D8 launches.
- I did not test multilingual yet, going to try that tonight.

There is also an issue with revisions (Entity Reference does not store the revision id in the field), I will probably create a core patch for that.
I hope my code will be of some help to modules like Inline Entity Form as the form handling is mostly the same.

jeroen.b’s picture

Issue summary: View changes
berdir’s picture

Revision support for entity reference was explicitly removed from core and will not be added back. If you need that, you need to subclass the entity reference field type and add that.

jeroen.b’s picture

Do you have the issue for that?
I don't really want to subclass entity reference as it makes more sense to let the widget define if it wants to save the revision id too.

berdir’s picture

Would have to search for it.

That's not something the widget can decide. The field type decides what can be stored, and the revision ID is not part of that.

jeroen.b’s picture

I know the field type decides what it can store.
The widget decides what it stores, so by default revision_id can be null, other widgets can fill the revision_id.
I honestly don't see why all these modules should define their own field_type while it can be easily fixed in core and thus only leaving one field type.

jeroen.b’s picture

I found the issue about the removal, https://www.drupal.org/node/2356609

It think it hasn't been given a good thought.
What we will get now is the same as in D7, 10 modules that implement their own field type just to get this revision support in, or there will be one contrib module that implements the field type "Entity Reference with revision support" and everyone has to rely on it, which doesn't really make sense.

I want to prevent that.

berdir’s picture

You will not, I can assure you that.

The default entity reference field type is also used to build the schema for base tables, adding a revision ID to the schema would mean that e.g the node_field_data.uid column would be expanded to node_field_data.uid_target_id and uid_revision_id.

The only thing that would be possible is a new field type that supports revisions in core, and that is an new feature and will not be added in 8.0.x.

jeroen.b’s picture

Well... "entity_reference_revision" incoming then...

miro_dietiker’s picture

Version: 7.x-1.x-dev » 8.x-1.x-dev

Moving.

jeroen.b’s picture

I renamed the entity from ParagraphsItem to just Paragraph, so your installation might be broken when you update.

miro_dietiker’s picture

I can't install, the installer fails:

(8.x-1.x) /var/www/d8.dev/www/modules/paragraphs$ drush en -y paragraphs
The following extensions will be enabled: paragraphs
Do you really want to continue? (y/n): y
exception 'Drupal\Core\Field\FieldException' with message 'Field storage definition for "" could not be found.' in                       [error]
/usr/local/var/www/d8.dev/www/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php:481
Stack trace:
#0 /usr/local/var/www/d8.dev/www/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php(207):
Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema->getEntitySchema(Object(Drupal\Core\Entity\ContentEntityType), true)

And the most recent commit is 28h ago: 618c6cf Change vid to revision_id
I guess you forgot to push?
Can you tell me the core hash you tested with, including a successful module reinstall?

jeroen.b’s picture

Yeah sorry, I pushed to the Github repo, I changed my origin url to drupal.org now.
I'm testing with beta4, not HEAD.

Can you test again, I just pushed to Drupal.org.
I just reinstalled Drupal D8 beta4 and enabled Paragraphs and it worked fine.

jeroen.b’s picture

Issue summary: View changes
miro_dietiker’s picture

Oh, you still do beta4... we always do dev against core latest (git checkout / pull).
There are still many things changing in core and we want to be as much up to date as possible.
I will test again with your recommended setup.

jeroen.b’s picture

Keeping up with D8 dev is way too much work, I rather patch it all up again with beta5 or rc1.

jeroen.b’s picture

Status: Active » Closed (fixed)

I guess this can be closed now, the D8 port is here.
Any issues with it should be created in separate issues.