We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 28042 ☆ A M B ☆
    • 24,524 Posts
    I’ve seen it, and I’m still using Evo. But then I still use VI when in a terminal wink
      Studying MODX in the desert - http://sottwell.com
      Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
      Join the Slack Community - http://modx.org
      • 17499 ☆ A M B ☆
      • 872 Posts
      Yes sottwell, Quote from: sottwell at May 01, 2011, 10:22 AM

      I’ve seen it, and I’m still using Evo.

      That’s because you’ve developped an allergy to OOP in the web context.

      Which is very much understandable if you’re building standard company websites (home, products, blog, about, contact - Which is easier with WP in this particular case btw) that don’t need maintenance contract - most of the times, it’s not even part on the contract -, a lot less starting with average sized web applications that need more works, team sinergy ,a solid API and enough server horses behind (?) - That where the Revo API/OOP shines compared to Evo.

        • 30023
        • 172 Posts
        Quote from: cyclissmo at May 01, 2011, 09:57 AM

        Quote from: TimGS at May 01, 2011, 06:08 AM

        I’m still not seeing how learning xPDO is going to help the coding of my websites.
        -- Tim.
        Which may be precisely why you are arguing against it - because you have not worked with it as extensively as, say Bob or Mark for example. I abandoned Evo long ago after forcing myself to understand Revo, and realistically I see no comparison between the two models in terms of usability, functionality and overall cohesiveness.

        But it’s precisely how Morpheus describes the Matrix: Unfortunately, no one can be told what MODx Revolution is. You have to see it for yourself. cool

        You are labelling anyone who has objectively chosen to not use Revo, and therefore clearly will not have used it as much as Bob, Mark or yourself, as ill informed and/or lacking in understanding. Almost by definition then you are saying that the only people with valid comments are those who have chosen to use Revo.

        -- Tim.
          • 3749
          • 24,544 Posts
          @Tim -- I find this a really interesting conversation and you’ve made some very good points. I hope we can keep if from being a, "my CMS can kick your CSM’s butt" conversation, or worse yet, an argument about parsing the meaning of each other’s posts. I think we can all agree that Evo and Revo both have strengths and weaknesses.

          I believe Cyclissmo’s point is that to make a fair assessment, you’d have to spend a fair amount of time actually using each platform in real-world situations and that the opinions of people who have done that are more useful than those of others. That doesn’t imply that people who prefer Evo are wrong, and there are people with extensive Revolution experience who use Evo for specific situations.

          By way of changing the subject back to comparison of the two platforms (and especially xPDO), I thought I’d try another example. In retrospect, my last one wasn’t that great. Suppose that you want to show the names of the parent containers holding other docs created by the creator of the current resource. You’re obviously very good at the Evo DBAPI (much better than I am) and I’d be curious to see what this code would look like in Evo and how readable it would be. This is off the top of my head, so please forgive any errors:

          <?php
          $containers = array();
          $creator  = $modx->resource->getOne('CreatedBy');
          $docs = $creator->getMany('CreatedResources');
          
          foreach ($docs as $doc) {
             $parent = $doc->getOne('Parent');
             if ($parent) {  // ignore docs with no parent
                 $parentName = $parent->get('pagetitle');
                 if (! in_array($parentName, $containers) {
                     $containers[] = $parentName;
                 }
              }
          }
          return ('The author of this article has written articles in the following categories: ' . implode(', ', $containers);  
          


          As an aside, I can’t help pointing out that the Evo code for the earlier banlist example requires you to know that the table for chunks is called "htmlsnippets" and that the content field is, contrary to common sense, called "snippet". Using getObject(’modObject’) and setContent($string) is a lot simpler and more generic (though I admit that you occasionally have to know the few cases where the ’name’ field is not ’name’ -- e.g., ’username,’ ’pagetitle,’ ’templatename,’ and ’category’).
            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
            • 18373 ☆ A M B ☆
            • 3,141 Posts
            Quote from: TimGS at May 01, 2011, 08:54 AM

            Quote from: Mark at May 01, 2011, 07:56 AM

            Also - the underlying database structure can me modified to be more efficient / make more sense, while keeping a clean upgrade path if you use the recommended object approach.

            How would you want to modify the db structure? I’m not being rhetorical - though I admit to being skeptical as to any realistic practical advantage.

            I meant that the core developers can (and have in 2.1 I believe) modify the underlying structure, without breaking any snippets that properly use the objects.

            There’s quite some snippets (Didn’t check, but I guess most of them) for Evolution that directly access the database through SQL queries - modifying any database structure in there would break all those snippets.


            I’d just like to add that I like this in-depth discussion as well. 97% of my work at the moment involves developing for/in MODX Revolution, whereas the other 3% is taken by support from former clients who are on Evolution. So I definitely have a preference, and while I may not be able of fully describing what I like, and why that’s better than Evolution, I think that most people who are seriously developing outside of the box (and not just deliver the 5-page websites with two templates and a couple of TVs which I did for the past 2 years) would eventually agree that Revo has been seriously thought out and that provides those little extra touches that make it fun to work with. There’s always the right system for the right job, and it doesn’t always have to be Revolution, tho my work is built from it almost entirely.
              Mark Hamstra • Developer spending his days working on Premium Extras and a MODX Site Dashboard with the ability to remotely upgrade MODX and extras to make the MODX world a little better.

              Tweet me @mark_hamstra, check my infrequent blog at markhamstra.com, my slightly more frequent ramblings at MODX.today or see code at Github.
              • 30023
              • 172 Posts
              Quote from: BobRay at May 01, 2011, 04:40 PM

              @Tim -- I find this a really interesting conversation and you’ve made some very good points. I hope we can keep if from being a, "my CMS can kick your CSM’s butt" conversation, or worse yet, an argument about parsing the meaning of each other’s posts. I think we can all agree that Evo and Revo both have strengths and weaknesses.

              I also think you (and others) have made some very good points, not least because you have specific concrete examples instead of nebulous comments which seem to common. I may not agree them all the time (e.g. your example re: coding/OOP/xPDO) although sometimes I do (e.g. your point and Mark’s follow-up re: the package manager and updates which I have acknowledged).

              I certainly am not saying and have not said "my CMS can kick your CMS’s butt"; I have explicitly said that I do not think Revo is bad, and that in many ways I think it is just different and therefore for myself not worth the learning curve (although on balance I would say that I think Evo is better anyway for most small/medium websites. Edit: For big sites I’d probably use neither.)

              I have to say that I actually have felt for a long time that such as "my CMS can kick your CMS’s butt" is something said all too often by those who expect others to believe that Revo is better just because they so (I do not include you in this - like I said above, you can produce examples to back up your case - which are appreciated - instead of just expecting me to believe you). However it simply isn’t good enough for anyone to say that Revo (or any CMS) is better than another just because that person thinks it is - at best its unhelpful as it adds nothing to the debate and does not help anyone make a decision as to which CMS to use.

              Quote from: BobRay at May 01, 2011, 04:40 PM

              By way of changing the subject back to comparison of the two platforms (and especially xPDO), I thought I’d try another example. In retrospect, my last one wasn’t that great. Suppose that you want to show the names of the parent containers holding other docs created by the creator of the current resource. You’re obviously very good at the Evo DBAPI (much better than I am) and I’d be curious to see what this code would look like in Evo and how readable it would be. This is off the top of my head, so please forgive any errors:

              <?php
              $containers = array();
              $creator  = $modx->resource->getOne('CreatedBy');
              $docs = $creator->getMany('CreatedResources');
              
              foreach ($docs as $doc) {
                 $parent = $doc->getOne('Parent');
                 if ($parent) {  // ignore docs with no parent
                     $parentName = $parent->get('pagetitle');
                     if (! in_array($parentName, $containers) {
                         $containers[] = $parentName;
                     }
                  }
              }
              return ('The author of this article has written articles in the following categories: ' . implode(', ', $containers);  
              

              As before, untested, and with the usual disclaimer attached:

              $creator = $modx->documentObject['createdby'];
              $docs_result = $modx->db->select('parent', $modx->getFullTablename('site_content'), 'parent != 0 AND createdby='.$creator);
              
              $containers = array();
              while ($docs_row = $modx->getRow($docs_result))
              	{
              	$parent_doc = $modx->getDocument($docs_row['parent']);
              	$parent_name = $parent_doc['pagetitle'];
              	if (!in_array($parent_name, $containers)) $containers[] = $parent_doc['parent'];
              	}
              
              return ('The author of this article has written articles in the following categories: ' . implode(', ', $containers);
              


              ...although I have to admit I might well be tempted just to do...

              $modx_site_content = $modx->getFullTableName('site_content');
              $result = $modx->db->query('SELECT pagetitle FROM '.$modx_site_content.' WHERE id IN
              		(SELECT DISTINCT parent FROM '.$modx_site_content.' WHERE parent != 0 AND createdby = '.$modx->documentObject['createdby'].')');
              
              $containers = array();
              while($row = $modx->getRow($result) $containers[] = $row['pagetitle'];
              
              return ('The author of this article has written articles in the following categories: ' . implode(', ', $containers);
              


              ...but that is (arguably) an unfair comparison given its quite a different programming style. The two selects may also be quicker as a join, but I don’t know enough about MySQL to be sure.

              In both case I assume that the fields ’parent’, ’pagetitle’ and ’createdby’ will not be removed in future Evo versions, but I think this is reasonable. As far I can see though, the equivalent Revo code has similar assumptions (?), which again I think is reasonable.

              Quote from: Mark at May 01, 2011, 05:04 PM

              Quote from: TimGS at May 01, 2011, 08:54 AM

              Quote from: Mark at May 01, 2011, 07:56 AM

              Also - the underlying database structure can me modified to be more efficient / make more sense, while keeping a clean upgrade path if you use the recommended object approach.

              How would you want to modify the db structure? I’m not being rhetorical - though I admit to being skeptical as to any realistic practical advantage.

              I meant that the core developers can (and have in 2.1 I believe) modify the underlying structure, without breaking any snippets that properly use the objects.

              Understood. I agree its an advantage.

              Quote from: Mark at May 01, 2011, 05:04 PM

              There’s quite some snippets (Didn’t check, but I guess most of them) for Evolution that directly access the database through SQL queries - modifying any database structure in there would break all those snippets.

              True, and this would probably involve alot of work in the core also. There are cases where breaking the ’rules’ by bypassing the non-DB API is desirable e.g. for speed, albeit at the expense of having to potentially edit code in the future. Edit: I also think that the Evo API has alot of scope for more methods which would reduce programmers dependancy on the DBAPI.

              -- Tim.
                • 28215
                • 4,149 Posts
                For those who want to know the benefits of using xPDO...

                1. Simplicity of code:

                $resource = $modx->getObject('modResource',234);
                $resource->set('pagetitle','New Title');
                $resource->save();
                


                That will work in MySQL and MSSQL immediately in 2.1. And in future versions, *any* other DB driver we implement. You cannot say that about Evo.

                2. Automatic Sanitization
                Due to the fact that xPDO extends PDO, all of the data you put into it using the generated models and set()/save() is automatically sanitized.

                3. Extensibility

                You can easily override the save(), remove(), set(), or other methods in your model classes to provide custom functionality to happen in those methods. Examples:
                - firing events across an xpdo-based app whenever a certain DB table has a record saved (new or update).
                - adding custom validation (which can also be done via object validation
                - Backwards compatible code: say you change the name of a database field, but want to have backwards compatibility for users who might reference the old name. You can do this by overriding the set() method
                - Centralized code for accessing the objects; all of your queries to that table for the xpdoobject go through your classes, so you can more easily debug, fine-tune, and develop

                xPDO also allows for easy class generation, proper code scaling, and service provisioning through the getService method.

                4. Instant Relational Model

                No need to create complex, often buggy SQL queries using joins - after defining the relationships in your XML schema and henceforth maps, simply use one line:

                $wheels = $car->getMany('Wheels');
                /* OR */
                $car = $wheel->getOne('Car');



                I wont even go into the scaffolding abilities you can get in xPDO or by using say, modExtra as a base. Revolution is, from a programmers perspective, a far more superior product. Its code is fundamentally more sound and secure, is more extensible, and provides a much stronger foundation to eventually add more enterprise-level features (such as versioning, workflow, media management, etc) than Evo could ever boast.

                Does this mean that we expect everyone to use Revo? No. I understand why some people would prefer Evo for smaller projects, if they’re already familiar with it. But we (as a core team) are not building contexts, lexicons, package management, element properties, derivative Resource types, ACL-based security systems (or for the future, static-elements/versioning/workflow) into Evo. If you want those, it’s time to move to Revo. If you don’t - well, thats why we have Evo and still support it.
                  shaun mccormick | bigcommerce mgr of software engineering, former modx co-architect | github | splittingred.com
                  • 6228
                  • 249 Posts
                  Nobody could ever put it as succintly as splittingred, being one of the chief architects of Revolution.

                  It stands to reason that to prefer working with one version over the other is perfectly reasonable. Either system is suitable for a particular purpose. To say one would prefer working with Evo because its easier to understand, easier to work with, doesn’t have the huge learning curve of its younger sibling, or heck- even more stable, are perfectly valid reasons to dismiss Revolution.

                  Quote from: TimGS

                  You are in a different situation from me though. I already know Evo well, and see no benefit in switching. Despite the above, I don’t think Revo’s bad (but I don’t see it as being better.)
                  But to say that the flagship MODx product is on equal grounds (or inferior) to its older, aging sibling is a pretty ludicrous statement IMHO. shocked

                  The examples I’ve seen so far compare apples to apples, but Revo has other fruit from which is completely lacking in Evo’s tree wink

                  // Make your manager and extras multilingual:
                  
                  $translatedString = $modx->lexicon('namespace.tag');
                  
                  // Flexible, fine-tuned caching system (without polluting $_SESSION):
                  // Supports file-based caching or memcache. Can create a custom cache implementation by overriding the xPDOCache abstract class.
                  // Some easy ways of getting and setting cache data:
                  
                  $modx->cacheManager->add($key, $value, $ttl); // add an item to the cache for $ttl seconds
                  $modx->cacheManager->delete($key); // remove an item from the cache
                  
                  // xPDO - examples of Revo power out-of-the-box:
                  
                  $xPDO->addPackage; // instantly extends MODx core with your own package (classes and maps), making your custom database available to xPDO.
                  $xPDO->prepare, $xPDO->execute, etc. // prepared statement support
                  $xPDO->getOne, $xPDO->getMany, $xPDO->remove, etc. // Define your own database field relationships to create simple or complex associations with one another.
                  
                  // Contexts - discrete areas with isolated configuration parameters, useful for subdomains or multiple MODx instances with a single installation:
                  
                  $modx->switchContext('context'); // switches to a different context
                  
                  // Programmatic access to MODx or custom processors, with full error handling support
                  
                  $response = $modx->runProcessor();
                  
                  // Speaking of error handling...
                  
                  $modx->error // Object that supports field and group validation, error messages and return responses.
                  
                  // For more: check out api.modx.com
                  

                    lo9on.com

                    MODx Evolution/Revolution | Remote Desktop Training | Development
                    • 17499 ☆ A M B ☆
                    • 872 Posts
                    Quote from: TimGS at May 01, 2011, 06:56 PM

                    ...although I have to admit I might well be tempted just to do...

                    $modx_site_content = $modx->getFullTableName('site_content');
                    $result = $modx->db->query('SELECT pagetitle FROM '.$modx_site_content.' WHERE id IN
                    		(SELECT DISTINCT parent FROM '.$modx_site_content.' WHERE parent != 0 AND createdby = '.$modx->documentObject['createdby'].')');
                    
                    $containers = array();
                    while($row = $modx->getRow($result) $containers[] = $row['pagetitle'];
                    
                    return ('The author of this article has written articles in the following categories: ' . implode(', ', $containers);
                    


                    ...but that is (arguably) an unfair comparison given its quite a different programming style. The two selects may also be quicker as a join, but I don’t know enough about MySQL to be sure.

                    I want to try too, following your programming style:

                    <?php
                    $c = $modx->newQuery('modResource');
                    $c->select('modResource.*, Parent.pagetitle as category');
                    $c->where(array('Parent.parent != 0', 'CreatedResources.createdby ' => $modx->resource->get('createdby')));
                    $c->groupBy('Parent.pagetitle');
                    
                    $containers = array;
                    $rows = $modx->getCollectionGraph('modResource', '{"CreatedResources":{"Parent":{}}}', $c);
                    foreach($rows as $row){	$containers[] = $row->get('category'); }
                    
                    return ('The author of this article has written articles in the following categories: ' . implode(', ', $containers);
                    


                    arf, two more lines and i’m not even sure that it’s actually working! :p
                      • 6228
                      • 249 Posts
                      Do you need to include one more line:
                      $c->bindGraph('{"CreatedResources":{"Parent":{}}}');

                      smiley
                        lo9on.com

                        MODx Evolution/Revolution | Remote Desktop Training | Development