We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 4385
    • 372 Posts
    I decided to get my feet wet with Revolution. Nice job everyone. Im try to think in terms of revo and want to convert some of my beloved PHx format scripts into Output Filters.

    This one formats numbers (1 to 1st, 22 to 22nd, 303 to 303rd)
    <?php
    if (!function_exists('ordinal'))
     {
     function ordinal($cardinal){
     $test_c = abs($cardinal) % 10;
     $ext = ((abs($cardinal) %100 < 21 && abs($cardinal) %100 > 4) ? 'th'
     : (($test_c < 4) ? ($test_c < 3) ? ($test_c < 2) ? ($test_c < 1)
     ? 'th' : 'st' : 'nd' : 'rd' : 'th'));
     return $cardinal.$ext;
     }
     }
     return ordinal($input);
    ?>
    



    So far so good. Everything seems to work. So how do I create a package so I can share with others and they can just click to install?

    The directions provided were beyond me. I would like to see all the PHx scripts that are on the old wiki converted to a group of "Filters" packages.
      DropboxUploader -- Upload files to a Dropbox account.
      DIG -- Dynamic Image Generator
      gus -- Google URL Shortener
      makeQR -- Uses google chart api to make QR codes.
      MODxTweeter -- Update your twitter status on publish.
      • 3749
      • 24,544 Posts
      There’s a transport package template here, although I’m not sure it’s up-to-date:

      http://svn.modxcms.com/svn/modx-components/component-template

      (You’ll need an SVN client to get it).

      splittingred has a tutorial here: http://svn.modxcms.com/docs/display/revolution/Creating+a+3rd+Party+Component+Build+Script

      If they are just snippets, the build script would be fairly simple (relatively speaking wink ) and you could add them in a loop. You might look at the SPForm build script (which is up-to-date). It’s also in the components repository. It’s a lot more complicated than you need, but you can see the loop that creates the snippets and chunks.
        Did I help you? Buy me a beer
        Get my Book: MODX:The Official Guide
        MODX info for everyone: http://bobsguides.com/modx.html
        My MODX Extras
        Bob's Guides is now hosted at A2 MODX Hosting
        • 4385
        • 372 Posts
        Thanks BobRay.

        That was the tutorial that I got lost on. wink

        I was hoping for a simple example since the build script looks like it is more than the finished snippet.

        What is the best practice for something like this? Many of my snippets are short and quick items that I find useful. I usually copy and paste them from one site to the next. It would be nice to be able to get them from the same source every time.
          DropboxUploader -- Upload files to a Dropbox account.
          DIG -- Dynamic Image Generator
          gus -- Google URL Shortener
          makeQR -- Uses google chart api to make QR codes.
          MODxTweeter -- Update your twitter status on publish.
          • 3749
          • 24,544 Posts
          There used to be a tool in the Manager for creating packages, but it caused some problems. It may come back some time.

          I’ve got to eat dinner, but I’ll try to put up a simple example here later.


            Did I help you? Buy me a beer
            Get my Book: MODX:The Official Guide
            MODX info for everyone: http://bobsguides.com/modx.html
            My MODX Extras
            Bob's Guides is now hosted at A2 MODX Hosting
            • 3749
            • 24,544 Posts
            Here is a fairly simple package. I tried to boil it down as much as I could for you. It’s untested and I had to move some things around to make it simpler, so consider it an alpha version, but it should get you started. I assumed that you wanted to put all your snippets in a category. It’s generally a good idea.

            <?php
            /**
             * Minimal Build Script
             * 
             */
            global $modx;
            
            /* set this to the directory above your _build directory */
            $root = dirname(dirname(__FILE__)).'/';
            
            /* Set File Locations
             *  -- source_assets is for files you want to transfer that need to be accessible via URL
             *    or have no security issues
             *
             *  -- source_core is for files you want to protect and that don't need to be accessible
             *    via URL (e.g. .php files)
             *
             *  -- data is for sources files used in the build that won't be transfered (which could be all of your files)
             *
             *  Assumes a directory structure like this:
             * 
             *     yourcomponent
             *         _build
             *             build.transport.php -- this file
             *             build.config.php -- file with the modx config settings (not used here)
             *             data -- files used in build that won't be transferred in the package
             *                 yoursnippet1.props.php  -- properties file
             *                 yoursnippet2.props.php
             *                 transport.snippets.php -- code to create the snippet array (not used here)
             *                 transport.chunks.php -- code to create the chunk array (not used here)
             *                 transport.resources.php -- code to create the resources array (not used here)
             *                 etc. for other elements (plugins, system settings, users, etc.
             *         assets -- files to transfer below the assets dir -- whole dir is transferred
             *             components
             *                 yourcomponent
             *                      css
             *                          yourcomponent.css
             *                      js
             *                          yourcomponent.js
             *         core -- files to transfer below the core dir -- whole dir is transferred
             *             components
             *                 yourcomponent
             *                      classes  -- class files (if any -- not used here)
             *                           yourcomponent.class.php
             *                      docs
             *                             readme.txt
             *                             license.txt
             *                             changelog.txt
             *                      lexicon
             *                         en
             *                             default.inc.php   -- language file
             *                      templates (if any)
             *                         yourcomponent.tpl -- Tpl chunk
             *                         yourcomponenttpl2.tpl -- Tpl chunk
             *                      yoursnippet1.inc.php -- source code of snippet1
             *                      yoursnippet2.inc.php -- source code of snippet2
             *
             *
             *
            */
            
            $sources= array (
                'root' => $root,
                'build' => $root . '_build/',
                'data' => $root . '_build/data/',
                'lexicon' => $root . 'core/components/yourcomponentname/lexicon/',
                'docs' => $root . 'core/components/yourcomponentname/docs/',
                'source_assets' => $root . 'assets/components/yourcomponentname',
                'source_core' => $root . 'core/components/yourcomponentname',
            );
            unset($root);
            
            
            $packageNamespace = 'yourcomponentname';
            
            
            /* This example assumes that you are creating 2 snippets with one namespace,
             * a lexicon, and 2 file resolvers (core files, assets files).
             *
             * The elements will all go in a single category.
             * Note: this code won't work without a category.
             *
             * You'll need to modify it if your situation
             * is different.
             *
             * A snippet with no files to be transferred doesn't need a file
             * resolver so you can comment out that part of the code.
             *
             * If you have no lexicon, you can comment out that part of
             * the code.
            */
            
            /* The name of the package as it will appear in Package Management
             * will be a combination of the name, version, and release
             */
            define('PKG_NAME','YourComponentName');
            define('PKG_NAME_LOWER','yourcomponentname');
            define('PKG_VERSION','1.0.0');
            define('PKG_RELEASE','beta1');
            
            /* set the name of the category the elements will go in */
            define('PKG_CATEGORY','yourcategory');
            
            /* set modx constants (edit the first) */
            define('MODX_CORE_PATH', '/path/to/modx/core/');
            define('MODX_CONFIG_KEY', 'config');
            
            /* let this script run outside of MODx */
            require_once MODX_CORE_PATH . 'model/modx/modx.class.php';
            $modx= new modX();
            $modx->initialize('mgr');
            
            echo '<pre>'; /* used for nice formatting for log messages  */
            $modx->setLogLevel(modX::LOG_LEVEL_INFO);
            $modx->setLogTarget('ECHO');
                /* $modx->setDebug(true); */
            
            $modx->log(modX::LOG_LEVEL_INFO,'Building ' . PKG_NAME . '<br />');
            $modx->log(modX::LOG_LEVEL_INFO,'Initializing Package Builder<br />');
            
            /* Initialize the Package Builder - don't change anything here */
            $modx->loadClass('transport.modPackageBuilder','',false, true);
            $builder = new modPackageBuilder($modx);
            $builder->createPackage(PKG_NAME_LOWER,PKG_VERSION,PKG_RELEASE);
            $builder->registerNamespace(PKG_NAME_LOWER,false,true,'{core_path}components/'.PKG_NAME_LOWER.'/');
            
            /* create category  -- skip if you don't want to put your stuff in a category */
            
            $modx->log(modX::LOG_LEVEL_INFO,'Creating Category<br />');
            $attr = array(
                xPDOTransport::UNIQUE_KEY => 'category',
                xPDOTransport::PRESERVE_KEYS => false,
                xPDOTransport::UPDATE_OBJECT => true,
                xPDOTransport::RELATED_OBJECTS => true,
                xPDOTransport::RELATED_OBJECT_ATTRIBUTES => array (
                    'Snippets' => array (
                        xPDOTransport::PRESERVE_KEYS => false,
                        xPDOTransport::UPDATE_OBJECT => true,
                        xPDOTransport::UNIQUE_KEY => 'name',
                    ),
                    'Chunks' => array (
                        xPDOTransport::PRESERVE_KEYS => false,
                        xPDOTransport::UPDATE_OBJECT => true,
                        xPDOTransport::UNIQUE_KEY => 'name',
                    ),
                )
            );
            $categoryObject= $modx->newObject('modCategory');
            $categoryObject->set('id',1);
            $categoryObject->set('category',PKG_CATEGORY);
            
            /* create snippet objects */
            $modx->log(modX::LOG_LEVEL_INFO,'Creating Snippets<br />');
            
            $snippets = array();
            
            /* first snippet */
            $modx->log(modX::LOG_LEVEL_INFO,'Creating Snippet1<br />');
            $snippets[1]= $modx->newObject('modSnippet');
            $snippets[1]->fromArray(array(
                'id' => 1,
                'name' => 'YourSnippet1',
                'description' => 'YourSnippet1 '.PKG_VERSION.'-'.PKG_RELEASE
                        .' -  Description goes here',
            ),'',true,true);
            $snippets[1]->setContent(file_get_contents($sources['source_core'] . '/yoursnippet1.inc.php'));
            
            /* code to add snippet properties to snippet1 */
            /* $properties = include $sources['data'].'properties.yoursnippet1.php';
            $snippets[1]->setProperties($properties);
            unset($properties); */
            
            /* second snippet */
            $modx->log(modX::LOG_LEVEL_INFO,'Creating Snippet2<br />');
            $snippets[2]= $modx->newObject('modSnippet');
            $snippets[2]->fromArray(array(
                'id' => 2,
                'name' => 'yoursnippet2',
                'description' => 'YourSnippet2 '.PKG_VERSION.'-'.PKG_RELEASE
                        . 'Description of snippet 2',
            ),'',true,true);
            $snippets[2]->setContent(file_get_contents($sources['source_core'] . '/yoursnippet2.inc.php'));
            
            /* code to add snippet properties to snippet2 */
            
            /* $properties = include $sources['data'].'properties.yoursnippet2.php';
            $snippets[2]->setProperties($properties);
            unset($properties); */
            
            /* repeat above sections for more snippets */
            
            /* chunks work just like snippets, but with 'modChunk'.
               Put them in a $chunks array  */
            
            /* add snippets to category (if there is one) */
            
            $categoryObject->addMany($snippets,'Snippets');
            
            
            /* add chunks to category
             $categoryObject->addMany($chunks,'Chunks');
            */
            
            /* build category */
            $modx->log(modX::LOG_LEVEL_INFO,'Creating Vehicle<br />');
            $vehicle = $builder->createVehicle($categoryObject,$attr);
            
            $modx->log(modX::LOG_LEVEL_INFO,'Adding Resolver to transfer assets files<br />');
            $vehicle->resolve('file',array(
                'source' => $sources['source_assets'],
                'target' => "return MODX_ASSETS_PATH . 'components/';",
            ));
            $modx->log(modX::LOG_LEVEL_INFO,'Adding Resolver to transfer core files<br />');
            $vehicle->resolve('file',array(
                'source' => $sources['source_core'],
                'target' => "return MODX_CORE_PATH . 'components/';",
            ));
            
            $modx->log(modX::LOG_LEVEL_INFO,'Adding File Resolvers to package<br />');
            $builder->putVehicle($vehicle);
            
            /* done building package */
            /* now pack in the license file and readme */
            
            $modx->log(modX::LOG_LEVEL_INFO,'Adding readme.txt and licence to package<br />');
            $builder->setPackageAttributes(array(
                'readme' => file_get_contents($sources['docs'] . 'readme.txt'),
                'license' => file_get_contents($sources['docs'] . 'license.txt'),
            ));
            
            $modx->log(modX::LOG_LEVEL_INFO,'Adding Lexicon strings<br />');
            /* load lexicon strings */
            $builder->buildLexicon($sources['lexicon']);
            
            $modx->log(modX::LOG_LEVEL_INFO,'Creating package ZIP<br />');
            
            /* zip up the package  */
            $builder->pack();
            
            $modx->log(modX::LOG_LEVEL_INFO,'Package completed.<br />');
            
            exit();
              Did I help you? Buy me a beer
              Get my Book: MODX:The Official Guide
              MODX info for everyone: http://bobsguides.com/modx.html
              My MODX Extras
              Bob's Guides is now hosted at A2 MODX Hosting
              • 4385
              • 372 Posts
              That helped. I don’t really understand it, but I just changed things where I thought they should be changed. It took me a while to figure what to do with the script and where to put it.

              I got it to make a zip file! There was an error on installation. Other than not putting in the php code, it worked great.

              /*
               * MODx Console Output
               *
               * @date 2010-03-29 00:58:29
               */
              Attempting to install package with signature: makeordinal-1.0.0-RC1
              
              Package found...now preparing to install.
              
              Grabbing package workspace...
              
              Workspace environment initiated, now installing package...
              
              No modVehicle resolver found for type .
              
              No modVehicle resolver found for type .
              
              Could not resolve vehicle: Array
              (
                  [readme] => # description: Ordinal numbers.
              # usage: [[*publishedon:strtotime:date=`%e`:makeOrdinal]]
              # notes: Adds 'st' to 21 to make it the 21st or 'nd' to 132 for 132nd. 
                  [license] => Free as in Freedom.
                  [action] => install
                  [signature] => 26e7294ac9a438e850ff4107f94fceaa
                  [register] => mgr
                  [topic] => /workspace/package/install/makeordinal-1.0.0-RC1/
                  [package_action] => 0
                  [vehicle_package] => transport
                  [vehicle_class] => xPDOObjectVehicle
                  [class] => modCategory
                  [guid] => 93a84ca0adc994cd54cbae65117220ad
                  [native_key] => 1
                  [filename] => modCategory/26e7294ac9a438e850ff4107f94fceaa.vehicle
                  [namespace] => makeordinal
                  [unique_key] => category
                  [preserve_keys] => 
                  [update_object] => 1
                  [related_objects] => Array
                      (
                          [Snippets] => Array
                              (
                                  [bd2b627082aeaec9c406a18e7b5b93ef] => Array
                                      (
                                          [preserve_keys] => 
                                          [update_object] => 1
                                          [unique_key] => name
                                          [class] => modSnippet
                                          [object] => {"id":1,"name":"makeOrdinal","description":"makeOrdinal 1.0.0-RC1 -  Output filter to make ordinal numbers.","editor_type":0,"category":0,"cache_type":0,"snippet":"","locked":0,"properties":null,"moduleguid":""}
                                          [guid] => 82e2b075b5015e8c1357489efea28a50
                                          [native_key] => 1
                                          [signature] => 85ebb148ff160b07ae97516c590d7585
                                      )
              
                              )
              
                      )
              
                  [related_object_attributes] => Array
                      (
                          [Snippets] => Array
                              (
                                  [preserve_keys] => 
                                  [update_object] => 1
                                  [unique_key] => name
                              )
              
                          [Chunks] => Array
                              (
                                  [preserve_keys] => 
                                  [update_object] => 1
                                  [unique_key] => name
                              )
              
                      )
              
                  [resolve] => Array
                      (
                          [0] => 
                          [1] => 
                      )
              
                  [validate] => 
                  [package] => modx
                  [object] => {"id":1,"parent":0,"category":"filters"}
              )
              
              
              Successfully installed package makeordinal-1.0.0-RC1
              
              
              /* EOF */
              
              
                DropboxUploader -- Upload files to a Dropbox account.
                DIG -- Dynamic Image Generator
                gus -- Google URL Shortener
                makeQR -- Uses google chart api to make QR codes.
                MODxTweeter -- Update your twitter status on publish.
                • 3749
                • 24,544 Posts
                It sounds like you’re pretty close. Without the category it would be *much* simpler, but it’s nice to have the snippets categorized.

                Did it install all the snippets in their category?

                I assume it didn’t transfer the files and directories.

                $sources[’source_core’] has to point to your /core directory (not the MODx core) and $sources[’source_assets’] has to point to your assets dir. They have to exist and may have to have contents. If you don’t have any files you want to transfer, you can just comment out the whole file resolver section.
                  Did I help you? Buy me a beer
                  Get my Book: MODX:The Official Guide
                  MODX info for everyone: http://bobsguides.com/modx.html
                  My MODX Extras
                  Bob's Guides is now hosted at A2 MODX Hosting
                  • 4385
                  • 372 Posts
                  Success! Thanks BobRay! Now get some sleep.

                  I left source assets as spform. I thought it was a "setup form" for setup options.



                    DropboxUploader -- Upload files to a Dropbox account.
                    DIG -- Dynamic Image Generator
                    gus -- Google URL Shortener
                    makeQR -- Uses google chart api to make QR codes.
                    MODxTweeter -- Update your twitter status on publish.
                    • 3749
                    • 24,544 Posts
                    Quote from: bwente at Mar 29, 2010, 12:54 AM

                    Success! Thanks BobRay! Now get some sleep.

                    I left source assets as spform. I thought it was a "setup form" for setup options.

                    Sorry about that. I copied the build file from my SPForm snippet. I fixed it in the post above.

                    Glad you got it working. smiley
                      Did I help you? Buy me a beer
                      Get my Book: MODX:The Official Guide
                      MODX info for everyone: http://bobsguides.com/modx.html
                      My MODX Extras
                      Bob's Guides is now hosted at A2 MODX Hosting