Coding Tutorial: How to package a custom implementation as an installable extension.

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • telecastg
    Active Community Member
    • Jun 2018
    • 907

    Coding Tutorial: How to package a custom implementation as an installable extension.

    This tutorial describes how to create a simple extension based on a custom implementation and shows how to use 'Modules' to segregate customizations instead of having everything in the 'Custom' namespaces, making it much easier to manage changes and troubleshooting for your custom code.

    The custom implementation described here is a button in an entity's detail display, that when clicked recalculates all formulas that apply to the subject entity.

    Please follow this link to see the original scripts which I will use to describe what changes were made to turn it into an installable extension.
    https://forum.espocrm.com/forum/gene...7904#post67904

    The namespace that we will use for this example is "FormulaRefresh" for back-end code and "formula-refresh" for front-end code

    Step 1:
    Change the namespace reference in the original front-end script
    client/custom/src/unrestricted-recalculate-formula-handler,js

    from:
    Code:
    define('custom:unrestricted-recalculate-formula-handler', ['action-handler'], function (Dep) {
    ...
    to:
    Code:
    define('[B]formula-refresh[/B]:unrestricted-recalculate-formula-handler', ['action-handler'], function (Dep) {
    ...
    Save the modified script (in your local machine) as:
    files/client/modules/recalculate-formula/src/unrestricted-recalculate-formula-handler.js

    Step 2:
    Change the namespace reference in the back-end script:
    custom/Espo/Custom/Controllers/RecalculateFormula.php

    from:

    Code:
    namespace Espo\Custom\Controllers;
    ...
    to:
    Code:
    namespace Espo\[B]Modules\FormulaRefresh[/B]\Controllers;
    Save the modified script (in your local machine) as:
    files/application/Espo/Modules/FormulaRefresh/Controllers/RecalculateFormula.php

    Step 3:
    Change the namespace reference in the back-end script:
    custom/Espo/Custom/Services/RecalculateFormula.php

    from:
    Code:
    namespace Espo\Custom\Services;
    to:
    Code:
    namespace Espo\[B]Modules\FormulaRefresh[/B]\Services;
    ...
    Save the modified script (in your local machine) as:
    files/application/Espo/Modules/FormulaRefresh/Services/RecalculateFormula.php

    Step 4:
    Save the file custom/Espo/Custom/Resources/routes.json as files/application/Espo/Modules/FormulaRefresh/Resources/routes.json

    Step 5:
    Create file (in your local machine) files/application/Espo/Modules/FormulaRefresh/Resources/metadata/module.json where you will establish a hierarchy (the higher the number the higher hierarchy) in case of conflict with other namespaces. The official extension Real Estate for example has an "order" value of 15. The namespace "Custom" is always the highest hierarchy.
    Code:
    {
        "order": 20
    }
    Step 6:
    Create file (in your local machine) manifest.json where Espo will read the extension basic parameters to install properly
    Code:
    {
        "name": "Formula Refresh",
        "version": "1.0.0",
        "acceptableVersions": [
            ">=6.1.1"
        ],
        "releaseDate": "2021-02-21",
        "author": "Omar A Gonsenheim",
        "description": "Gives any User with 'edit' privileges the ability to recalculate formulas by clicking a button on an entity's 'detail' display"
    }
    Step 7:
    Compress the folder "files" and the file "manifest.json" as zip file "formula-refresh-for-espocrm-1.0.0.zip"

    Congratulations !, you just created an installable extension which you can upload and install at Admin > Extensions
    Last edited by telecastg; 02-24-2021, 05:40 AM.
  • item
    Active Community Member
    • Mar 2017
    • 1476

    #2
    Thanks friend.. you are the legend ( emillod now you know the real legend )
    Next step, with custom library (vendor.. autoload field how make with composer in new extension/module )

    question :
    - why we need route.json ?
    - can i extension use out-of-box Util ? certainly.. but for be sure.
    If you could give the project a star on GitHub. EspoCrm believe our work truly deserves more recognition. Thanks.​

    Comment

    • telecastg
      Active Community Member
      • Jun 2018
      • 907

      #3
      You're very welcome item , don't know about legend though, there are a lot of very good coders / developers here aside from the more active that we all know, they just might be a little shy (or maybe selfish) to post code examples that benefit everyone

      Regarding your first question: We used a custom route for this example because the controller and service classes are not part of an entity and by using a custom route you can direct Espo to the correct controller and action instead of following the general API call to Controller(same name as entity)/action.

      You don't need to create custom routes if all your back end controllers are derived from a record, as it is most common.

      Regarding the second question I am afraid that I am a complete new comer to composer so I don't know the answer...
      Last edited by telecastg; 02-23-2021, 01:25 AM.

      Comment

      • item
        Active Community Member
        • Mar 2017
        • 1476

        #4
        Hello friend,
        i have voip extension.. and there are a vendor library.. (same path as you write..like espocrm out-of-box vendor but for module )
        but with one file : autoload.php .. with content :

        PHP Code:
        <?php
        // autoload.php @generated by Composer
        require_once __DIR__ . '/composer/autoload_real.php';
        return ComposerAutoloaderInitBBBBBBBSSSDDDD::getLoader();
        I don't know how is "generate".. and how it's "_append" .. you understand me because i don't understand

        I think i have no post anything "confidential" .. and replace some char with "BBBBSSSDD"

        Regards
        If you could give the project a star on GitHub. EspoCrm believe our work truly deserves more recognition. Thanks.​

        Comment

        • telecastg
          Active Community Member
          • Jun 2018
          • 907

          #5
          Hello friend,

          As I mentioned I don't know much about composer so I don't know how to incorporate it in a custom extension.

          My only experience thus far with external libraries in a custom extension, is what I did with the esignature documents extension https://github.com/telecastg/esignat...ts-for-espocrm (please download the zip file and open it locally to better understand what I mean).

          In that case I used the "jsignature" library to create and manage the signature panel, so I used a folder files/client/modules/esignature/lib/jsignature/ to store all the jsignature library files and folders, and then created the file files/application/Espo/Modules/Esignature/Resources/metadata/app/client.json to call all scripts under the lib folder.

          However, in my case I was incorporating a front-end library and in your case you would need to incorporate a back-end library and I don't know which metadata script you would use for that.

          Perhaps emillod or eymen-elkum or yuri or Maximus can help.
          Last edited by telecastg; 02-24-2021, 01:32 AM.

          Comment

          • emillod
            Active Community Member
            • Apr 2017
            • 1405

            #6
            Hello guys!
            I've try to manage extensions for many months, but it's hard to do so without template. I've tried to build extensions, but it take a lot of time
            So i think that if you want to create extension, you should use ext-template repo from EspoCRM: https://github.com/espocrm/ext-template
            It's pretty simple. You have to prepare environment on your computer or server, but it's simple.

            item in regard to your question about composer package.
            1. Prepare propper structure for your extension. That's mean you have to prepare module for your ext in app folder. For example \files\application\Espo\Modules\OvhIntegration\
            2. In module folder(\files\application\Espo\Modules\OvhIntegrat ion\) Create composer.json for example: https://pastebin.com/NELatsmD
            3. In module Resource directory, create file autoload.json with path to autoload.php: https://pastebin.com/ar0X7Udy
            4. Open CLI in module folder and run composer install to make sure that your extension will have propper packages attached
            5. Enjoy

            After that you don't have to attach vendor in any file, just use package.
            If you want i can attach package with composer as an example.
            Of course also please let me know if you'll have any questions

            Comment

            • telecastg
              Active Community Member
              • Jun 2018
              • 907

              #7
              Originally posted by emillod
              Hello guys!
              I've try to manage extensions for many months, but it's hard to do so without template. I've tried to build extensions, but it take a lot of time
              So i think that if you want to create extension, you should use ext-template repo from EspoCRM: https://github.com/espocrm/ext-template
              It's pretty simple. You have to prepare environment on your computer or server, but it's simple.
              Hello emillod !

              I must confess that not being a professional developer, I felt totally ignorant trying to follow the documentation instructions.

              If you have time could you post an example of an actual use of this template ? So far I have been building our modules purely by hand and it works fine, but if using the template can simplify the process it would be great.

              Thanks in advance !

              Comment


              • item
                item commented
                Editing a comment
                Hello Emillod, +1 like telecastg ..

              • esforim
                esforim commented
                Editing a comment
                "I felt totally ignorant trying to follow the documentation instructions"

                Hello fellow friend

              • telecastg
                telecastg commented
                Editing a comment
                esforim lol !
            • emillod
              Active Community Member
              • Apr 2017
              • 1405

              #8
              telecastg sure, of course.
              I'm using for that wsl on my computer. I'm using windows 10 with WSL, so it's not rocket science

              I believe you should have packages like php, git, node.
              If you have everything, just:
              1. Open CLI (i love Microsoft terminal )
              2. Fetch espo template: git clone https://github.com/espocrm/ext-template.git (ss: https://i.imgur.com/orZpSWj.png)
              3. Move to the directory (ss: https://i.imgur.com/0PQsN4i.png)
              4. Initiate php script: php init.php (ss: https://i.imgur.com/ITSA0UU.png) and provide basic information
              5. Run npm install command

              That's all. Now you can remove .git directory and init.php file because everything is ready.
              This init.php script will prepare all folders which you need to work on your extension.

              After that you can open your edit, for me it's visual studio code, so i have to enter "code -n ." to open vscode in that directory.

              I've also tried to use everything manually, but it's simpler. I can upgrade version with one command, i can build a package also with one command.
              I can prepare temporary instance with one command thanks to which i have EspoCRM instance for specific extension.

              There is also one command to move all changes from Custom to Extension. Unfortunatelly it can't merge changes, so after you move everything from Custom, and you'll change something from GUI(for example you'll create new field) it can't merge changes from custom with already existing module.

              And of course if you're git-guy, working with github in vscode is a blessing

              Comment


              • telecastg
                telecastg commented
                Editing a comment
                Thanks so much emillod !

                I am a total beginner using git but I will educate myself more and will try.

              • emillod
                emillod commented
                Editing a comment
                I'm using git not that long, but now it's big part of my job as a developer.
                I store everything important on github, i have to enter "git clone XYZ" to prepare a dev workflow

                And that history of changes is bless
            • shalmaxb
              Senior Member
              • Mar 2015
              • 1602

              #9
              Hi, I have been using the customization itself (in the custom`s folder) quite a while now and it works as desired.
              Today I tried to built this as an extension as described here. Unfortunately I did not have success. The button does not appear, no error in the log file or in the app itself.

              I see, that in the files, when implemeted in folder custom, there you will have to append this code:


              Code:
              { ... "menu":
              { "detail":
              { "buttons":
              [ "__APPEND__",
              {
              "label": "Recalculate Formula",
              "name": "recalculateFormula",
              "action": "recalculate",
              "style": "default",
              "acl": "read",
              "aclScope":
              "Basic",
              "data": { "handler": "custom:basic-recalculate-formula-handler" },
              "initFunction": "initRecalculate" } ] } }, ... }
              in every entity, where you want the button to appear. Is this not necessary, when packing as extension, because in the description above, there is nothing about that?

              Comment

              • telecastg
                Active Community Member
                • Jun 2018
                • 907

                #10
                Hello,

                Yes, that code is still necessary to be added to the clientDefs of each entity where you want to display the "Recalculate" button. The only change is the reference to the custom handler

                from:
                Code:
                "data": { "handler": "custom:basic-recalculate-formula-handler" },
                to:
                Code:
                "data": { "handler": "formula-refresh:unrestricted-recalculate-formula-handler" },
                The extension allows you to add the button but you still need to let Espo know which entities should have the custom button.

                Comment


                • shalmaxb
                  shalmaxb commented
                  Editing a comment
                  Unfortunately, it does not work. When I insert the handler-code into the clientDef of an entity, the record of that entity won`t open. There appears for one second "load" on top and after that nothing.
                  No error in log-file.
              • emillod
                Active Community Member
                • Apr 2017
                • 1405

                #11
                There are some changes 6.2. We'll have to keep ext in custom directory
                Supporting modules in the custom directories for both back-end and front-end: custom/Espo/Modules/{ModuleName} client/custom/modules/{module-name} The system will automatically recognize when the m...


                Comment


                • telecastg
                  telecastg commented
                  Editing a comment
                  Thanks for the heads up.
              • shalmaxb
                Senior Member
                • Mar 2015
                • 1602

                #12
                I get this error in Browser console:

                Code:
                loader.js:421 Uncaught Error: Could not load file 'client/modules/formula-refresh/src/unrestricted-recalculate-formula-handler.js?r=1627310483'
                at Object.error (loader.js:421)
                at j (jquery-2.1.4.min.js:2)
                at Object.fireWith [as rejectWith] (jquery-2.1.4.min.js:2)
                at x (jquery-2.1.4.min.js:4)
                at XMLHttpRequest.<anonymous> (jquery-2.1.4.min.js:4)
                error @ loader.js:421

                Comment

                • shalmaxb
                  Senior Member
                  • Mar 2015
                  • 1602

                  #13
                  Meanwhile I found the error. It is caused by a wrong path for the js-file. In a former post the file should be here:

                  files/client/modules/recalculate-formula/src/unrestricted-recalculate-formula-handler.js

                  but it works only, if the path looks like this:

                  files/client/modules/formula-refresh/src/unrestricted-recalculate-formula-handler.js

                  Here is the extension ready to use: formula-refresh-for-espocrm-1.0.0.zip
                  Be aware, that this is not my extension, it was made by the tutorial and files from telecastg in this thread.
                  Attached Files
                  Last edited by shalmaxb; 07-26-2021, 05:09 PM.

                  Comment

                  • shalmaxb
                    Senior Member
                    • Mar 2015
                    • 1602

                    #14
                    Hi, telecastg , seems, that the process to create custom modules changed with 7.0.x.
                    Any hints, how I can create modules from my custom entities? I succeeded with that in 6.x but the file structure changed.

                    Comment

                    • telecastg
                      Active Community Member
                      • Jun 2018
                      • 907

                      #15
                      Hi shalmaxb ,

                      Actually you can use your old (pre Espo 7) or the new (Espo 7) module structure and the system will recognize it.

                      You can have the pre Espo 7 structure like this:
                      application/Espo/Modules/{MyModule}/(back end folders like Controllers, Services,Resources, etc)
                      client/modules/{my-module}/(front end folders like libs, res. src, etc)
                      For an example of this structure you can check the Chats extension (which I believe you have) folder structure https://payhip.com/b/tq62X

                      Or you can have the Espo 7 way like this:
                      custom/Espo/Modules/{MyModule}/(back end folders)
                      client/custom/modules/{my-module}/(front end folders)
                      For an example of this structure you can check the List Plus extension (that I believe that you also have) folder structure https://payhip.com/b/ZGQMH

                      yuri stated that the "old" way would continue working maybe indefinitely so perhaps it is not necessary to alter the old structure but for new extensions I would recommend using the new way just in case there is another major code refactoring and the "old" way is no longer available

                      Comment


                      • shalmaxb
                        shalmaxb commented
                        Editing a comment
                        Thanks, I will try that tomorrow.

                      • telecastg
                        telecastg commented
                        Editing a comment
                        You're welcome
                    Working...