Correct way to render an custom entity and its custom field? In my module, I have a custom entity LocationEntity and it uses a custom field type CoordinateItem which has 2 sub fields X, Y.

So what is the correct way of Drupal 8 to:

1) Render this LocationEntity in a twig template?


What I'm doing is just send the entity to twig template '#loc1' and manually render its each field value using getter method {{ loc1.getName() }}. It works but I'm sure this is not the correct way to do.


2) If question 1 has another correct way then how to have more than one templates for rendering the entity?


For example, one simple layout with less fields and one detail layout with all fields.


3) In the entity, I defined to use the custom field CoordinateItem. But now what to do with its getter and setter, because it's not a single sub field inside?


Getter if $this-&gt;get('coord') -> a FieldItemList object.
Getter if $this-&gt;get('coord')-&gt;value -> null.
Setter? What type is the parameter?


4) I wrote a formatter for CoordinateItem to show its sub fields. But again I don't know how to use this formatter to render this custom field in the main (entity) template?


Maybe this is related to question 1 and 2?
View Builder



Set the view_builder in ContentEntityType annotation to EntityViewBuilder to inherit some default behavior (or write your own).


Set your canonical router to something like what content_entity_example does in the examples module.


Berdir suggests using DefaultHtmlRouteProvider though that class is marked as @internal so it may not be stable to use long term.




content_entity_example.routing.yml

entity.content_entity_example_contact.canonical:
  path: '/content_entity_example_contact/{content_entity_example_contact}'
  defaults:
    _entity_view: 'content_entity_example_contact'
    _title: 'Contact Content'
  requirements:
    _entity_access: 'content_entity_example_contact.view'




Change your entity theme to something like what node module does, and have it display as a render element. 


Use your entity or bundle's field display page to change what field formatters a given field will use.


Then you can print out {{ elements }} in the template for it to go through the entire render array for a given view mode. Again, you can follow something similar to node module.