We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
  • Thanks for that, I almost have it 100% as I want it.

    The only issue now is that since I have html5mode active, refreshing the page breaks the site. If you start at index.html all is fine:

    http://designfromwithin.com

    I also need to find out a good way to have Google index my site, I know about HTML snapshots but have not found a easy way to do this...

    My script:
    <script src="assets/templates/gulp_h5bp/js/vendor/angular.js"></script>
      <script src="assets/templates/gulp_h5bp/js/vendor/angular-route.js"></script>
      <script>
        // create the module and name it DESIGNfromWITHIN
    	var DESIGNfromWITHIN = angular.module('DESIGNfromWITHIN', ['ngRoute']);
    
    	DESIGNfromWITHIN.config(function($sceProvider) {
    		$sceProvider.enabled(false);
    	});
    
    	DESIGNfromWITHIN.config(function($locationProvider) {
    		$locationProvider.html5Mode(true);
    		$locationProvider.hashPrefix('!');
    	});
    
    	// configure our routes
    	DESIGNfromWITHIN.config(function($routeProvider) {
    		$routeProvider
    		// route for the home page
    		.when('/', {
    			templateUrl : 'assets/templates/gulp_h5bp/pages/home.html',
    			controller  : 'mainController'
    		})
    		// route for the test page
    		.when('/contact.html', {
    			templateUrl : 'assets/templates/gulp_h5bp/pages/contact.html',
    			controller  : 'contactController'
    		})
    		// route for the post page
    		.when('/blog.html', {
    			templateUrl : 'assets/templates/gulp_h5bp/pages/post_overview.html',
    			controller  : 'blogController'
    		})
    		// route for the post page
    		.when('/blog/:postName.html', {
    			templateUrl : 'assets/templates/gulp_h5bp/pages/post.html',
    			controller  : 'postController'
    		})
    		.otherwise({ 
    			redirectTo: '/'
    		});
    	});
    
    	// create the controller and inject Angular's $scope
    	DESIGNfromWITHIN.controller('mainController', function($scope, $http) {
    	$http.get('[[~1]]')
    		.then(function(res){
    			$scope.message = res.data;              
    		});
    	});
    
    	// create the controller and inject Angular's $scope
    	DESIGNfromWITHIN.controller('blogController', function($scope, $http) {
    	$http.get('[[~20]]')
    		.then(function(res){
    	 		$scope.message = res.data;              
    		});
    	});
    
    	DESIGNfromWITHIN.controller('postController', function($scope, $http, $routeParams) {
    		$http.get('[[~20]]' + $routeParams.postName + '.html')
    		.then(function(res){
    			$scope.message = res.data;             
    		});
    	});
    
    
    	DESIGNfromWITHIN.controller('contactController', function($scope, $http) {
    		$http.get('http://designfromwithin.com/assets/templates/gulp_h5bp/package.json')
    		.then(function(res){
    			$scope.message = res.data;            
    		});
    	});
    	</script>
    
      MODX Ambassador (NL) | Responsive web design specialist, developer & speaker
      DESIGNfromWITHIN, MPThemes and Any Screen Size
      Follow me on Twitter | Read my blog | My code on GitHub
      • 33657
      • 128 Posts
      go into your content types and change .html into " "

      so a HTML file has no extension.

      then you access your subpages without .html

      like ... mysite.com/contact

      mysite.com/whatever

      rather than mysite.com/contact.html (this wont work)

      and then you need to do escaped fragments for google SEO (which I have not done yet but plan on making that a directory in modx and just using some sort of getresources to recreate those pages for SEO purposes).

      and then when you get a blog post... you would have to do a lookup to resolve it...

      
      .factory('utils', function () {
      
          return {
      
            // Util for finding an object by its 'id' property among an array
            findById: function findById(a, id) {
              for (var i = 0; i < a.length; i++) {
                if (a[i].id == id) return a[i];
              }
              return null;
            },
      
            findByAlias: function findByAlias(a, id) {
              for (var i = 0; i < a.length; i++) {
                if (a[i].alias == id) return a[i];
              }
              return null;
            }
          };
      
        });
      
      


      and on my blog page, i use it to get the item i want on the "detail" page..

      
      .state('blog.detail', {
      			url: "/:alias",
      			views: {
      				'mainBlog': {
      					templateUrl: 'pages/blog.detail.html',
      					controller: ['$scope', '$stateParams', 'utils',
      					function (  $scope,   $stateParams,   utils) {
      						$scope.item = utils.findByAlias($scope.blogposts, $stateParams.alias);
      					}]
      				},
      			},
      		})
      
      


      and these are code fragments so you have to just use the "theory" behind it, not plug and play.. you would need angular-ui-router if you wanted to use my state's but you get the idea for the lookup in the controller.. $scope.item = utils.findByAlias and then i look for my alias..

      you can see a working example at

      http://ecocooltech.com/blog

      for example..

      and

      http://ecocooltech.com/blog/there-once-was-a-story

      would resolve to the blog page, lookup the alias and pull that detail up on the fly. [ed. note: zurie last edited this post 9 years, 8 months ago.]
      • thanks, but changing the file extension does not change the issue....

        I think I need to redirect all url's to the index.html somehow....

        Any chance that i see your code and how you do it? [ed. note: ThaClown last edited this post 9 years, 8 months ago.]
          MODX Ambassador (NL) | Responsive web design specialist, developer & speaker
          DESIGNfromWITHIN, MPThemes and Any Screen Size
          Follow me on Twitter | Read my blog | My code on GitHub
          • 40045
          • 534 Posts
          Ever thought about using the extra instantAPI? http://modx.com/extras/package/instantapi

          Maybe this way you could have a "normal" site (for indexing) and another (the live one) via AngularJS?
            • 33657
            • 128 Posts
            Quote from: ThaClown at Aug 05, 2014, 09:50 PM
            thanks, but changing the file extension does not change the issue....

            I think I need to redirect all url's to the index.html somehow....

            Any chance that i see your code and how you do it?

            make sure you have a .htaccess file in the same spot your index.php file is. (if you are using apache).


            .htaccess file contents
            # html5 pushstate (history) support:
            <ifModule mod_rewrite.c>
            RewriteEngine on
            
            
            # Rewrite "domain.com/foo/ -> domain.com/foo"
              RewriteRule ^(.*)/$ /$1 [R=301,L]
            
            # The Friendly URLs part
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
            </ifModule>
            
            



            if you wanna see the full .htaccess file I use https://gist.github.com/zurie/5da3bc6c965b088b831b
            [ed. note: zurie last edited this post 9 years, 8 months ago.]
              • 34244
              • 51 Posts
              I've created Angular apps in Modx. Typically I found it worked better if I injected the JSON as a chunk on the pages themselves, otherwise I would run into caching issues of the dynamically created JSON (usually from some getResources calls).

              Usually to successfully present HTML stored inside JSON, I'd have to present it like this:

              <span ng-bind-html="trustHTML(tool.toolDocs)"></span>


              And my controller would look something like this (note the inclusion of the $sce service and ngSanitize):

              <script>
              'use strict'; 
              var toolApp = angular.module('toolApp', ['ngSanitize', 'ngDialog']);
              
              toolApp.controller('ToolController', function($scope, $sce, $window, ngDialog) {
                  
                  $scope.toolList = [[$toolsJSONListTpl]]; //JSON List
              
                  $scope.trustHTML = function(input) {
                     return $sce.trustAsHtml(input);
                  };
              
              });
              </script>
              
                


              I also encoded my JSON when including large blocks of HTML (note the jsonEncode snippet):
              {
                "pageTitle":"[[+pagetitle]]",
                "toolId":"[[+id]]",
                "toolType":"[[+tv.tool-type]]",
                "toolImg":"[[+tv.tool-img]]",
                "toolMsg":"[[!jsonEncode? &jsonInput=`[[+tv.tool-msg]]`]]",
                "toolStages":"[[!jsonEncode? &jsonInput=`[[+tv.tool-stages]]`]]",
                "toolNotes":"[[!jsonEncode? &jsonInput=`[[+tv.tool-notes]]`]]",
                "toolInventory":"[[+tv.tool-inventory]]",
                "toolDocs":"[[!jsonEncode? &jsonInput=`[[!getResources? &parents=`[[+id]]` &tpl=`toolDocTpl` &limit=`4` &includeTVs=`1`]]`]]",
                "toolZoom":"[[+tv.tool-zoom]]"
              },
              
              [ed. note: aesop1 last edited this post 9 years, 8 months ago.]
                • 33657
                • 128 Posts
                Quote from: aesop1 at Aug 06, 2014, 07:38 PM
                Usually to successfully present HTML stored inside JSON, I'd have to present it like this:
                <span ng-bind-html="trustHTML(tool.toolDocs)"></span>


                Cool, you could also make a global filter for the $sce.trustAsHtml and pass a directive recompiler in at the same time.

                
                angular.module('myApp').directive('compileTemplate', function ($compile, $parse) {
                	return {
                		link: function (scope, element, attr) {
                			var parsed = $parse(attr.ngBindHtml);
                
                			function getStringValue() {
                				return (parsed(scope) || '').toString();
                			}
                
                			//Recompile if the template changes
                			scope.$watch(getStringValue, function () {
                				$compile(element, null, -9999)(scope);  //The -9999 makes it skip directives so that we do not recompile ourselves
                			});
                		}
                	}
                });
                
                angular.module('myApp').filter('unsafe', function ($sce) {
                	return function (val) {
                		return $sce.trustAsHtml(val);
                	};
                });
                
                


                and to apply it to an element you would do it like this:

                <p ng-bind-html="items.content | unsafe" compile-template> </p>
                


                Compile template is so if you had a directive "inside" your HTML it would compile and reapply it as a directive, rather than treat it like unescaped html content.
                  • 34244
                  • 51 Posts
                  Zuriel, nice! I like it.