No announcement yet.

Pack an entity to make it installable

  • Filter
  • Time
  • Show
Clear All
new posts

  • Pack an entity to make it installable

    I did not find an answer for this especially. Is there a possibility to pack a whole entity with layout, relationships and custom fields as extension so that deployment could be done easily?

  • #2
    No such tool from UI yet.

    If you don't mind to work from CLI you can utilize the template repository. See


    • #3
      Yes, Yuri is right. You can use their template, but if you don't have skills to do so, you can create propper structure of fail, create manifest file and just prepare a package. I started from that, because it is the easiest way.


      • #4
        Hello, I created an entity and after that, following the blog article about creating PM entity as installable extension, I succeeded in packing the files correctly and installation worked. But in the end there appeared the error 500, telling that one class would not exist in repositories. As far as I see, the class is there, but I don`t get it to work.

        Anybody any idea?

        emillod , thank you for the hint, I did it in that direction.


        • espcrm
          espcrm commented
          Editing a comment
          I'm pretty useless here, but what the class? Is it one of your custom Class name or a file that should be default in Espo?

      • #5
        Hello shalmaxb don't know if you have seen this posting, maybe it can help you


        • shalmaxb
          shalmaxb commented
          Editing a comment
          Great, that really helped. I used the git clone, what made the folder structure easier to create. Thank you!

      • #6
        shalmaxb you have to remember about changing all namespaces in your extension. Also you have to change in scope module from Custom to name of your extension.

        Before namespaces was generated by EspoCRM, so they're "Custom", and you have to change them in Repositories, Controllers, Services folders to propper for your extension


        • shalmaxb
          shalmaxb commented
          Editing a comment
          Hi, great help. I used the template from github and copied all my files to the folders, changed the namespace (that is missing in the help files for extensions) and now it worked.

      • #7
        Hi, after I succeeded in creating the extension for the entity, I still asking me one thing:

        Let`s say I have two custom entities A and B, that have some relationships. I create two extensions A and B. So far so good.
        But what happens to the relationships, if I only install extension A for instance? Would the existence of these relationships, that in this case would not have the counterpart, cause problems?


        • shalmaxb
          shalmaxb commented
          Editing a comment
          I think meanwhile I can answer it by myself:
          Even if your custom entity A has relationships, they won`t be copied before entity B (with which A has relationships) is installed.
          So installing A first, no custom relationships, installing B second, the relationships between A and B are added, installing C, these relationships to A (and or B) are installed.
          That is perfect!

      • #8
        It's supposed that one package contains all needed entities and their relationships.


        • shalmaxb
          shalmaxb commented
          Editing a comment
          Yes, that is, what I did. And it worked great. I only was afraid, that if I only install one of the related entities, it could create problems, what it not is. Works perfect and was not so difficult. Thanks to the great support here in this forum.

      • #9
        shalmaxb you should create full relationship in extension. If you create relation between custom entity and account entity, EspoCRM will also generate file in custom directory for account with new field. You should add this file to your extension. Thanks to that, if you add extension, you don't have to worry about relations. There is a problem if you try to relate with custom entity, which is not in your instance. But here you can create simple if in BeforeInstall script, which will check if entity exist.


        • #10
          I have all my custom entities packed as extension, so if I need to launch a new installation of my app, I can easily add the pre-configured entities.

          But here is a very important hint:

          Don`t try to create an extension from a default entity (even if you customized), like document, contacts and so on. If you install such extension, you will crack your app, because it seems to cause severe conflicts. Took me two days of exhausting work to make that experience.

          I think, it will be though possible to create a default entity as completely new custom entity, deactivate the default entity and then have the custom substitute for that entity as installable extension.
          I will test that, but perhaps anybody already has expeience in that?


          • #11
            shalmaxb i'm not sure what you want to achieve, but it's possible to override default entities, add some fields, override even the layout of these entities, sooo.. You probably doing something wrong Anyway, imho, if you want to add a lot of things to default entity, maybe it's a sign that you should create additional entity?


            • #12
              I am aware of being able to modify even default entities and even in complete different way, than original. I created an app, that has nothing to do with CRM, it is completely (ab)used for another purpose, but that works impressively well so far.
              For my purpose I would need to have all the customizations for more other installations. I know, that it is quite easy to put the custom folders into these new installations, but from pure curiosity I started to pack every custom entity as extension, so I could install any entity separately. Even another user could install these entities without touching any FTP or so.

              Besides m custom entities, I did so with the documents entity. I put together all files, that I found in my custum folder regarding the document entity and packed them into an extension. Without problems I succeeded in installing that extension and started to work with it. But at a certain stage suddenly it broke the app, I don`t know exactly what happened and there were no error logs anywhere, not in the espo log, not in Apache and as well not in the browser console. What became fact is, that the whole app was not working anymore, I could not open detail views and nearly all the image links (entity itself and relationships) were gone. Even deinstalling the extension did not get the app back to work again.

              So my conclusion is, that installing this extension entered in severe conflict with the default document extension, what caused the broken app.

              I read, that it is possible to clone default apps, what I will try next and then pack the cloned one as extension, deactivate the default and will see, if that works.


              • #13
                Hello shalmaxb ,

                If you did not write any custom code overriding front end (JS) classes/views or back end (PHP) classes I suspect that the issued is the "module" order value.

                Every time that you create a new module (extension) namespace you need to create a module.json file located at either:

                application/Espo/Modules/{{YourModule}}/Resources/metadata/module.json (Espo 6 way that still works) or at:

                custom/Espo/Modules/{{YourModule}}/Resources/metadata/module.json (Espo 7 way)

                "order": 25
                When you create or customize entities via the Admin Panel or manually, Espo creates metadata files which are the specifications for the entity, (like entityDefs, clientDefs, etc) and since Espo is a single page application, every time that it needs to rebuild the single page for display, Espo will use the metadata as a blue print to build the new page.

                In order to resolve possible conflicts when two metadata specs exist for the same entity,(like when you customize an entity), espo consolidates all existing metadata files to build a final metadata.php script.

                Conflicts between two metadata scripts for the same entity, are resolved based on the value of "order" in each module.

                Scripts in a higher "order" value module will override scripts in a lower "order" value and scripts in the Custom namespace will override everything else, that is why you are able to customize an standard entity without really affecting the application.

                Espo Crm module - the core module - has an "order" value of 10 so any module with and "order" value greater than 10 will override the standard Crm entities.

                If you have several modules that might conflict because they are using the same entities, you can do like emillod suggests which is create custom entities based on cloned versions of a core entity, or you will need to keep track of each module's order value and decide which module should have superiority over another one.
                Last edited by telecastg; 11-20-2021, 07:49 PM.


                • #14
                  This I had been missing, because I did not took it in consideration at all (forgot it). One question left: The order is only relevant for modules of the same name? That means, the order number of the module - in my case called documents - would not conflict regarding the order of other modules, right?

                  If I would give my module documents the order 25, it would not conflict with the default documents entity?


                  • #15
                    The order is only relevant for the same entity in different modules, because it affects how the metadata is built.

                    Remember that the metadata are the specifications (like a blue print) for the single page that is going to be rendered and the database that stores the data.

                    For example, suppose you want to modify the entity Document adding a varchar field ownership.

                    To do this, you go to Administration > Entity Manager and add the field there.

                    Espo will create a new entityDefs Document.json file under the namespace "Custom" that incorporates the parameters for the ownership field, but since you are encapsulating your modifications, you move that entityDefs file to a namespace Writings and assign the "order" value of 25 to the Writings module.

                    Then you realize that for Paitings you probably have to store provenance information, that might occupy a lot more space in the ownership field, so use the Entity Manager to modify the field type from varchar to text and save the newly created entityDefs from the Custom namespace to a Paintings, and assign the "order" value of 30 to the Paintings module.

                    Upon rebuild, Espo will read the 3 different entityDefs for Document:

                    1- application/Espo/Modules/Crm/Resources/metadata/entityDefs/Document.json - order value = 10

                    2) application/Espo/Modules/Writings/Resources/metadata/entityDefs/Document.json - order value = 25

                    3) application/Espo/Modules/Paitings/Resources/metadata/entityDefs/Document.json - order value = 30

                    Since only the field ownership is affected by the customization, Espo will use the original (Crm) module's entityDefs for all fields in Document

                    Since Paintings has the highest "order" value, espo will add a field type "text" for the ownership field

                    If you remove the module Paintings and rebuild the application, Espo will assign a field type "varchar" to the ownership field because the highest "order" is now Writings

                    This is why emillod suggestion to create custom Document entities, one at each different module, makes more sense. The work that you save by not creating custom entities is a good price to pay for not having to keep track of which modules override another one.

                    The idea behind using modules is to encapsulate functionalities in a way that they can be added or removed without affecting any other modules.
                    Last edited by telecastg; 11-22-2021, 05:34 PM.