No announcement yet.

Copying a custom extensoíon does not display layout

  • Filter
  • Time
  • Show
Clear All
new posts

  • Copying a custom extensoíon does not display layout

    In my app I achieve a modular concept with different custom entities by packing each entity as an installable extension, what worked and still works in 7.2.

    The only thing I do not get to work is the layout. Though all files are in place and complete, in the layout manager there is only one field (name) displayed, as well as in list view as in detail view. All fields are present in the right column.

    Did I miss anything regarding this approach for version 7.2? Or has anybody an idea, what could be the cause of this behaviour?

  • #2
    Hello shalmaxb

    The Entity Manager and the Layout Manager create or modify json scripts in the Custom namespace only.

    Once an extension is installed, if you want to modify an entity or layout, using the GUI Entity Manager or Layout Manager, you will need to read the new json scripts created in the Custom namespace and copy the changes to your json scripts in your extension's namespace.

    Not sure if this is the issue in your case.


    • #3
      Hi telecastg,
      you are right. By following the proceeding to make an entity installable, everything is installed in Custom/Modules and this way espoCRM does not "see" the layout. I copied all layouts to the Custom folder and it works. That means, by installing entity as an extension, there should be a way to point the installer script to the layout folder in Custom.

      Another possibility would be to make espoCRM read the file from the Modules folder (which actually would be the best for consistency), instead from Custom.

      Is there any workaround to achieve one of these proposals?


      • #4
        Hi shalmaxb,
        To use the layouts from your extension folder instead of the custom one you have to set the "Module" value in your scopes json to the extension module name instead of using "Custom" value.


        • #5
          Hello Kharg, yeah, that worked. Of course you have to rebuild and clear cache (also browser cache).
          Thanks to that answer, I can really use a modular concept for my app. That is great!

          telecastg, you see, your direction was right as well.

          and an additional remark: by default it is this way in scopes.json

          "module": "Custom"

          Instead of "Custom" you will have to put the name of your extension there (not only "Modules").
          Last edited by shalmaxb; 11-09-2022, 12:50 PM.


          • #6
            If you use your entities this way, you may not longer be able to edit the layout in the admin area (GUI), because the frontend does not point there anymore. An entity edited in this case would create a folder in Custom, but this layout will not be displayed.
            So in case you install an extension this way and after that you have changes, you will have to install the extension/entity again or you create new fileds etc. directly in the layout file in the Modules folder.


            • Kharg
              Kharg commented
              Editing a comment
              If you set the namespace to the module name and built your extension correctly future Layout changes will be saved and used from custom folder if I remember correctly.

            • shalmaxb
              shalmaxb commented
              Editing a comment
              I tested very rapidly. Later I will test more and see, how it works. But already as it is now, is great for me.

          • #7
            The GUI Entity Manager and the Layout Manager are designed to work only with files in the Custom namespace, this assures that any customization will take precedent over the standard equivalent file.

            For example, if you add a new field to the "Contact" entity, the system creates or edits a Contact.json file in the Custom namespace but the original entityDefs file is left intact, so regardless of your customizations the original Contact entityDefs will remain unaffected in case you change your mind and decide for example to "delete" the additional field.

            When the application rebuilds, the system reads all json metadata fields, organizes possible conflicting data and aggregates by "order" of importance (Custom is always the highest order) to create a single metadata.php file that contains the system actual "metadata specifications".


            • #8
              Worked the last few days on this concept, to make my app modular. In general it works as elaborated in the previous posts.

              But it does not work, if your entities have relationships, making one entity (module) dependent from another. As example:

              - You have entity 1 with own fileds etc.
              - Then you have entity 2 with relation to entity 1. This creates e.g. a field in entity 1, where the both entities are linked.
              - if you now install entity 1 as a module and do not want, that the user uses entity 2, the entity 1 still will work, but will have the now abandoned field for the relationship to entity 2. This causes, besides of the confusion an user will feel, a warning about a missing field.

              Because of this, in my opinion, it is not possible to make an espoCRM app modular. I guess it would not be possible with any database, that works with relationships (what is an essential feature of relational databases).

              I guess, the only way to avoid an user to use a certain entity, is to configure that by ACL. In that case you could hide the still existing fields conditional, depending on the user role.

              Nevertheless, even this approach is not too comfortable. I created an app, that has one entity as the main functional part and meanwhile extended the app by more than 20 custom entities, all with relationships. I imagined to make this modular to deliver the app, depending on the user`s needs, as kind of "light" version up to "full featured" version.
              Making the entities modular and install only what the user needs is not possible. Tweaking every use case by ACL would also be very tedious.

              If anybody has another idea, I appreciated to know about it.


              • espcrm
                espcrm commented
                Editing a comment
                You trying to create an Extension that we can install like the official Real Estate app right? But what are you making?

                As our industry probably won't cross, I volunteer to beta test and complain if you do plan to release it.

              • shalmaxb
                shalmaxb commented
                Editing a comment
                no it will not be comparable to the Real Estate App. It is an app for a catalogue raisonée for artists, that consists of several entities. All entities are connected in some way, so the app works only as one app together.
                I have clients, who do not need all features and for that my idea was to make it modular. But that does not work because of how the whole app is constructed. I guess, it will not even give any way to realize something like that, because relationships are always necessary to connect the data of the different entities.

            • #9
              hello shalmaxb

              I think that it is possible to accomplish your goal of "modularity" but you would probably need to restructure your whole application using these principles:

              1) Build a "parent" module that is common to all your other modules and which will be installed in all configurations.

              For an example of this, you can look at Espo's structure and notice that it has a "Crm" module, which contain the basic functionality to work as a Crm (Accounts, Contacts, etc) and it is always installed, so any extensions like Advanced, Sales, etc will need Crm to work, but you can have the Advanced pack and not the Sales pack and everything works.

              The key here is that the Advanced pack does not need anything from the Sales pack to work and vice-versa (this is known as encapsulation) but BOTH modules need the Crm module

              2) Design your other modules (children modules) following the encapsulation principle, by making sure that a child module does not require any entity or relationship defined in another child module, but it doesn't prevent you from having different links on each child mode to an entity defined in the "parent" module.

              For example, suppose that you have entity A defined in the "parent" module, and that entity is to be linked to "child" module1 B entity as a Many-to-One relationship (a B entity can have one or more A entities), and then you have a C entity, defined in child module2 and linked to the A entity as a Many-to-Many relationship (a C entity can contain one or more A entities and an A entity can have one or more C entities).

              a) Create all three entities without any links between them using the entity manager and move each entity files to its own namespace ("parent", "module1", "module2")

              b) Using the entity manager, create the Many-to-One relationship between A and B. The application will generate entityDefs for entity A and for B.

              c) Move the entityDefs file for entity A to module1 namespace, and copy the content of the entityDefs for B in the Custom namespace and merge with the entitydefs for B in the module1 namespace, deleting the Custom namespace entityDefs for both A and B

              d) Using the entity manager again, create a Many-to-many relationship between A and C.

              e) Move the entityDefs file for entity A to module2 namespace and copy the content of the entityDefs for C in the Custo namespace and merge with the entityDefs for C in the module2 namespace, deleting the Custom namespace entityDefs for both A and C.

              d) Clear cache and rebuild

              e) The database will have tables "a", "b", "c" and "a-c" with the necessary fields for all links to work, but since the system only "reads" the metadata content for the installed modules, it will not matter for example if nothing points out to table "a-c" when only modules "parent" and "module1" are installed.

              To better understand why the above works, keep in mind that the Espo application is a single page javascript application (basically a super-complex javascript file) which connects to a back-end (php) application and database (MySql) through Ajax calls to the back-end defined APIs

              The actual single page file is not static, it is actually created by the system based on the existing javascript files and the definitions contained in the metadata scripts.

              In other words, the system uses the metadata definitions as the recipe to build the single page script, and when necessary to make changes to the database structure like adding tables or fields but the single page script is not really "hard-wired" to the database, so it is possible to have fields that are not used in a table or unused tables without affecting the system, as long as the metadata is properly defined.

              Hope the above makes sense


              • #10
                telecastg, thank you very, very much for this explanation. So much work. You are really a friendly person!
                I had been thinking of the concept to separate all the entities from one another, without having a clue, how to get the necessary linking between them. I now understand, where to begin, although I do not yet know in detail, how to actually do that. But I will try. I already feared, that I would have to construct my app in another way. I do not see that necessarily a disadvantage, because I will learn even more and get to my aim of modularity.

                I will start to rebuild the app trying to follow the mentioned principles. Let`s see if I get it forward.

                Again, thank you so much!


                • telecastg
                  telecastg commented
                  Editing a comment
                  You are very welcome shalmaxb I appreciate how you are actively helping others.

                  It is refreshing to see that, instead of like a lot of other users whom are eager to post their specific questions to solve their own projects but almost never ready to help someone else.
                  Last edited by telecastg; 11-11-2022, 04:37 AM.