We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 33657
    • 128 Posts
    Is there a awesome way to use Modx with a SPA? Angularjs for example?

    For me, I am unable to use both simultaneously because my index.html page wants to use a angular router. my angular router is looking for custom routes and pages from inside my angular javascript. none of these things connect to modx and use modx's engine to redirect index.php

    my solution is to use angular on the ROOT website and use MODX as a manager / json creator on a sub directory. ie http://mysite.com/cms/whatever.json

    and I am making pages like "whatever" and setting them to json as a format and using getResources and MigXTV as a glorified JSON creator. like

    { "image" : "[[+image]]", "etc": "[[+etc_variable]]" }


    the problem is that there is no way to create new pages "dynamically" with new controllers and new directives in angular and that be managed from Modx (at least not in my system). (this is important for clients who don't know how to write html and pages, etc)

    So is there a way to connect the two or what is the plan for this stuff in the future, etc. Does modx have a place in the future for Single Page Javascript Frameworks. Right now using json files I am able to create a global-resources.json and include things like meta data, keywords, page titles, and stuff like that.. but using something like Wayfinder might be impossible unless I am only setting up "dynamic" routes in angular with no controllers or javascript for those pages...

    Another thing is.. is there a way to dump the entired modx website. every page. every variable. every tree into a JSON list? sorta like a global RSS feed but just something built in that dumps the whole database as json?

    thanks!

    Here is a example of my testimonial page. As you can see. there is so much stuff happening in javascript that dynamically creating "testimonial" and linking it into javascript, and then adding in a controller, and etc. is a pain in the butt.

    'use strict';
    angular.module('myapp.testimonials', [])
    .config(
            ['$stateProvider',
            function ($stateProvider) {
    
    
            	$stateProvider.state("testimonials", {
            		abstract: false,
            		url: "/testimonials",
            		views: {
            			'@': {
            				template: ''
            			},
                            'subcontent@': {
                            	templateUrl: 'pages/testimonials.html',
                                controller: 'testimonialsCtrl',
                            },
                            'navTitle@': {
                            	template : '<ul><li><h1> {{mytitle}} </h1></li></ul>',
                                controller: 'navTitle',
                            },
                            'bkg@': {
                            	template: '<div class="static-bkg"></div>'
                            },
                        },
                        onExit: ['appLoading',
                        function (appLoading) {
                        	appLoading.loading();
    
                        }],
                        onEnter: ['appLoading', 'triangles', 'drawer',
                        function ( appLoading, triangles, drawer) {
    		appLoading.ready();
    		triangles.close();
    		drawer.close();
            
                        }],
                    })
    }]
    ).controller('testimonialsCtrl', ['$scope','$http', function($scope, $http) {
        $scope.currentPage = 0;
        $scope.pageSize = 8;
        $scope.items = [];
    
        $http.get('http://ecocooltech.com/cms/Testimonials.json')
        .success(function(data) {
            $scope.items = data.entries;
            $scope.numberOfPages=function(){
                    return Math.ceil($scope.items.length/$scope.pageSize);                
            }
        });
    
        
    }]);
      • 33657
      • 128 Posts
      Noone has any input on this question? Is there no elegant way to deal with SinglePage applications that have their own router? Is there no way to dump the entire modx tree as a json automatically? Is there a way to bypass modx's router or is there an API that may help?
      • I think you can use getResources to get all the resources and TVs from your MODX site you might have to create a tpl to output it in the format you need.

        I'm not 100% sure if this will get you what you need but take a look at it.
          Benjamin Marte
          Interactive Media Developer
          Follow Me on Twitter | Visit my site | Learn MODX
          • 33657
          • 128 Posts
          yes.. i can use get resources. don't know if i can get ALL the tvs and values... doubtful...

          yes... i can create a custom template, and manually, 1 by 1 create a json file

          "pagetitle": "[[+pagetitle]]",

          and just do EVERYTHING...


          but i'm already at and beyond that step. I was looking for a straight DUMP of the whole modx tree with EVERYTHING thats available.. hence not having to individually do that.

          but what I really care about is the integration.. or lack there of. of a Single Page app that has its own brain. and modx, which also has its own brain. and trying to access a page that doesn't actually exist... since its derived from the index.php page with an clever query and mod_rewrite. so mysite.com/mycoolpage.html is really just index.php with a query.

          which makes pulling mycoolpage.html really hard unless I am hitting index.php and then that goes and pulls it and pretends its a real page.

          which then steps me back to my original problem, which is.. modx does not play well with another system thats basically trying to do the same thing. so i work around it. but what I really want, is someone who is smarter than I am, who has a more intimate knowledge of Modx, to objectively look at the "issues" and say.. oh, well here is a elegant solution.

          because unlike jquery.. angular.js wants to be the boss. where jquery can enchance another website, angular wants to control that same website.

          and i like angular... but creating a content management system that plugs into a client side dynamic javascript MVC framework seems like it has its own inherit issues that either need to be resolved, or worked around. I have done a fairly good job of "working around" things, but controlling the structure of the site, which was easy in modx to create and manage new pages, becomes impossible in a system that requires javascript updating of a few main javascript files to even get a new page loaded. Router, controllers, Views, Models. (Is it possible to create dynamic javascript files that are updated from modx? Can I have a content type of .js and pull it from another site (enabling cross refrences).

          Angular.js has absolutely exploded in the past year. and if you aren't using it, and you aren't getting your hands dirty with it, well you are leaveing yourself behind. you are going to be the guy who 5 years ago was like "jquery? who cares" and now its in 90% of all websites. why? because it makes building and using websites better. so I have a feeling that more and more people are going to use angular to build sites. and I am looking for a positive way to integrate modx into angular as a CMS, but because of some of the behind the scenes things happening, I am not sure I am doing it in the most optimal way.

          [ed. note: zurie last edited this post 10 years, 2 months ago.]
          • Yeah, totally understand I just started using angular for a few projects but not SPA and not using MODX so I really can't say what would be the best way to handle this.

            Another thing you could probably do is have you angularjs file be a modx resource so you can get access to all the TVs and placeholders MODX provides, again not sure if this would be beneficial for you just throwing out some ideas of things you could probably try.

            Good luck and please let us know if you figure out a way to do this.
              Benjamin Marte
              Interactive Media Developer
              Follow Me on Twitter | Visit my site | Learn MODX
              • 36996
              • 211 Posts
              Do you know this? - http://modx.com/extras/package/simplxrpc

              and this - http://modx.com/extras/package/simplxcontroller [ed. note: nir-z last edited this post 10 years, 2 months ago.]
                • 4172
                • 5,888 Posts
                do you really need to create a controller for each page? I think not.

                Basically something like this in a template seems to play nice:

                I have all resources in this scenario checked as container.
                This is everything inside modx:
                http://www.revo222.webcmsolutions.de/75/angular-spa/book/gatsby

                <!doctype html>
                <html xmlns:ng="http://angularjs.org" ng-app="ngRouteExample">
                <head>
                <base href="[[++site_url]]"
                </head>
                <body >
                
                    <div ng-controller="MainCntl">
                    Choose:
                    [[pdoMenu? &startId=`182`]]
                     
                    <div ng-view></div>
                    <hr />
                     
                    <pre>$location.path() = {{$location.path()}}</pre>
                    <pre>$route.current.templateUrl = {{$route.current.templateUrl}}</pre>
                    <pre>$route.current.params = {{$route.current.params}}</pre>
                    <pre>$route.current.scope.name = {{$route.current.scope.name}}</pre>
                    <pre>$routeParams = {{$routeParams}}</pre>
                    </div>
                
                
                 
                <script src="http://code.angularjs.org/1.2.11/angular.min.js"></script>
                <script src="http://code.angularjs.org/1.2.11/angular-route.js"></script>
                <script type="text/javascript" >
                
                
                    angular.module('ngRouteExample', ['ngRoute'])
                     
                    .config(function($routeProvider, $locationProvider) {
                    $routeProvider.when('/75/angular-spa/book/:bookId', {
                    templateUrl: '[[~180? &template=`book`]]',
                    controller: ContentCntl
                    });
                    $routeProvider.when('/75/angular-spa/book/:bookId/:chapterId', {
                    templateUrl: '[[~180? &template=`chapter`]]',
                    controller: ContentCntl
                    });
                     
                    // configure html5 to get links working on jsfiddle
                    $locationProvider.html5Mode(true);
                    });
                     
                    function MainCntl($scope, $route, $routeParams, $location) {
                    $scope.$route = $route;
                    $scope.$location = $location;
                    $scope.$routeParams = $routeParams;
                    }
                     
                    function ContentCntl($scope, $routeParams, $http, $location) {
                            $http({method: 'GET', url: '[[~181]]?root=' + $location.path() + '&params=' + angular.toJson($routeParams)}).
                              success(function(data, status, headers, config) {
                                  if(data){
                                      $scope.title = data.pagetitle || '';
                                      $scope.items = data.items || [];      
                                  }
                            }).
                              error(function(data, status, headers, config) {
                              // called asynchronously if an error occurs
                              // or server returns response with an error status.
                            });   
                    }
                
                </script>      
                 
                </body>
                </html>
                


                get the template on resource 180 (blank template):

                [[$contentTpl_[[!getReqParam? &name=`template`]]]]
                


                get the json-contents on resource 181 (also a blank template):

                [[!getResourceToJson]]
                


                getResourceToJson is a very simple Testsnippet:

                $classname = $modx->getOption('classname', $scriptProperties, 'modResource');
                $fields = $modx->getOption('fields', $scriptProperties, 'id,pagetitle');
                $limit = $modx->getOption('limit', $scriptProperties, 10);
                $offset = $modx->getOption('offset', $scriptProperties, 0);
                $offset = $modx->getOption('offset', $_REQUEST, $offset);
                $uri = trim($modx->getOption('root', $_REQUEST, ''),'/');
                $output = array();
                
                if ($docid = $modx->findResource($uri)){
                    
                } elseif ($docid = $modx->findResource($uri.'/')){
                
                } elseif (empty($url)){
                    $docid =  $modx->getOption('site_start');   
                }
                
                if ($docid) {
                    if ($resource = $modx->getObject('modResource', $docid)) {
                        $output = $resource->toArray();
                    }
                 
                    $items = array();
                    $c = $modx->newQuery($classname);
                    $c->select($modx->getSelectColumns($classname, $classname, '', explode(',', $fields)));
                    $c->where(array('parent' => $docid));
                 
                    $count = $modx->getCount($classname, $c);
                 
                    $c->limit($limit, $offset);
                    //$c->prepare();echo $c->toSql();
                    if ($collection = $modx->getCollection($classname, $c)) {
                        foreach ($collection as $object) {
                            $items[] = $object->toArray('', false, true);
                        }
                    }
                 
                    $output['items'] = $items;
                }
                 
                 
                return $modx->toJson($output);
                



                [ed. note: Bruno17 last edited this post 10 years ago.]
                  -------------------------------

                  you can buy me a beer, if you like MIGX

                  http://webcmsolutions.de/migx.html

                  Thanks!
                  • 33657
                  • 128 Posts
                  I will have to take a look at this more bruno, this might be what I need.

                  so are you creating your javascript inside modx, so that you have access to your template variables? or are you forced to do it, inline. so you have access to template variables.

                  I was sorta doing a similar thing outside of modx, with dynamic pages and just saying when its /dynamic/:myid goto a templateUrl with a path of /pages/:myid so it goes to /pages/whatever.html for example. This might be something i'd need to see a good working example of "inside" modx using getresources or wayfinder or some way to make the pages in modx and it just link up.

                  not a HUGE fan of inline scripting but it is what it is...


                  so there is no way to harness this power unless we drop the scripts inline. Does modx have a way to create a .js file dynamic any other way.

                  what if i kept my modx folder seperate, and created .js files just like I am currently creating .json files. using modx to make js files and pages via the modx brain, but then have a engine that pulls the data cross site scripting style.
                    • 4172
                    • 5,888 Posts
                    this would also work with the javascript-part in a file, but wouldn't process MODX-tags like
                    [[~180? &template=`chapter`]]

                    this could be a system-setting or something, too:
                    [[~[[++angular_template_ID]]? &template=`chapter`]]


                    Its more flexible and you can inject code more dynamic by MODX this way.

                    It should, of course also work, to have them as a modx-resource, which you would include by its url.
                    But you wouldn't have the current-resource-object to work with.

                    That said, the most flexible way seems to be, to have the javascript-code inline.
                      -------------------------------

                      you can buy me a beer, if you like MIGX

                      http://webcmsolutions.de/migx.html

                      Thanks!
                      • 33657
                      • 128 Posts
                      Bruno this is the first time i've had a chance to put what you've written to the test and already I see that your example page is gone sad

                      Regardless, this is what i've done.

                      I've copied your HTML template into a blank template.

                      setup 2 resources. both (empty) templates. 1 calls [[!getResourceToJson]] and 1 calls [[$contentTpl_[[!getReqParam? &name=`template`]]]] I copied in your snippet for getResourceToJson

                      edit: so you are calling 2 snippets? $contentTpl_book and $contentTpl_chapters

                      i've changed the #'s in your controller from 180 and 181 etc to match my id's which are 4 and 5 now.

                      you can see my current setup at

                      http://za.hostwarp.com/about/bruno

                      http://za.hostwarp.com/about/whatever_i_want_to_put_here

                      http://za.hostwarp.com/test

                      I had to change the extensions of .html pages to be blank for my routing to work correctly and all error pages need to route to index as well.

                      The getResourceToJson call isn't working for me, because I don't see anything coming back. Do you know if your code above is correct or did the forum add extra markup to it? i see a paragraph mark or some weird gremlin in that call in your main template? can you tell me if thats intended or if its off? I would like to be able to pull pagetitle, content, all the parameters and If i remember correctly your demo was doing that.


                      Thanks! [ed. note: zurie last edited this post 10 years ago.]