{"id":1099,"date":"2016-08-20T14:27:27","date_gmt":"2016-08-20T05:27:27","guid":{"rendered":"https:\/\/n8finch2024.local\/?p=1099"},"modified":"2019-06-30T07:02:20","modified_gmt":"2019-06-29T22:02:20","slug":"adding-angular-markup-genesis-child-theme","status":"publish","type":"post","link":"https:\/\/n8finch2024.local\/adding-angular-markup-genesis-child-theme\/","title":{"rendered":"Adding Angular Markup to a Genesis Child Theme (Part 1)"},"content":{"rendered":"
This is the second\u00a0post in a three part series on using Genesis and Angular. Part 2 can be read here<\/strong><\/a>, and Part 3 can be read here<\/strong><\/a>.\u00a0<\/em><\/p>\n This month is “Angular August<\/a>“<\/strong>, and so I’ve been focusing on learning Angular (1, not 2\u00a0yet… but soon!).\u00a0I’ve set myself several tasks\u00a0learning angular, one of which is developing a starter Genesis child theme using Angular and Gulp (since I’ve been wanting to check out and use Gulp more too… I still love you, Grunt). Here\u00a0is what I’m trying to do with this project:<\/p>\n Primary objective:\u00a0<\/strong>Create a view area that will display all the contents of posts and pages without a page reload using\u00a0Genesis and Angular.<\/p>\n Do this by:<\/p>\n If you’ve used Angular, you know you need to specify I’m a part of the community at WP Developer Club and KnowtheCode.io<\/strong><\/a>, and Tonya does a great job walking through the So, here’s how I finally landed on the markup I needed to be able to add\u00a0the basic Angular directives to my Genesis Markup…<\/p>\n (Note:\u00a0<\/strong>Unless otherwise noted, all PHP goes in the <\/p>\n With Angular, there are several directives you need to place in your HTML for an app to work, or in this case, for a Genesis child theme to assume an app-like state. This include:<\/p>\n No big deal if you’re working with straight HTML or a custom theme, but for frameworks, you need to filter the markup already included and running in your parent theme. In this particular case,\u00a0I need\u00a0to\u00a0be able to add this like Let’s start with the easy stuff… adding In many Angular tutorials (and maybe even the documentation), you will find that you’re typically adding Angualr to the <\/a><\/p>\n In order to filter and add these directives (or any property), we’re going to use the provided filter If you’re running the Genesis Sample child theme, you’ll probably get a result like this:<\/p>\n <\/a><\/p>\n Great! So, we just need to use a simple filter to add on our directive, like this:<\/p>\n And BOOM! <\/a><\/p>\n Excellent! You can use the same technique to add controllers like This means we can and should now add a view… But how??…<\/p>\n The process is very similar, except that we want to add only At first, I thought, “Just do the same thing as before, but instead run: Instead, we need to use the After adding this filter, we get the output we need to add the view to this HTML element:<\/p>\n <\/a><\/p>\n Awesome! Moving right along.<\/p>\n You might be wondering, “Why are we adding Let’s find out…<\/p>\n If you haven’t already, jump over and check out Josh Pollock’s article on Torque Mag: The Basics of AngularJS with the WordPress REST API<\/a>.<\/p>\n Thinking along the lines of Josh’s code, how can we get this to work? Simple. First we want to remove\u00a0default loop from Genesis (on all pages, for the sake of this example, quick and dirty). Then, we want to output some basic HTML with a Next, we want to make sure we’ve got the Angualar app up and running in an enqueued JavaScript file, like so:<\/p>\n\n
ng-app<\/code>\u00a0and
ng-view<\/code>\u00a0in your html markup so that your Angular app will run.\u00a0This is easy to do with a starter theme like _’s, but if you’re building on top of a framework like Genesis, you need to use the available
hooks and filters<\/code>\u00a0to manage your markup.<\/p>\n
markup.php<\/code>\u00a0file and structure in Genesis. Check it out and join up if you’re thirsty for knowledge!<\/p>\n
function.php<\/code>\u00a0file and all JavaScript has been enqueued from a
main.js<\/code> file)<\/p>\n
Adding Directives and\u00a0Properties with Values to Attributes<\/h2>\n
\n
ng-app<\/code><\/li>\n
ng-repeat<\/code><\/li>\n
ng-model<\/code><\/li>\n
ng-whatever<\/code>…….<\/li>\n<\/ul>\n
ng-app<\/code>,
ng-controller<\/code>,
ng-view<\/code>, etc. to things like
<head><\/code>,
<main><\/code>, or any other element already provided by Genesis.<\/p>\n
ng-app<\/code>\u00a0to our project.<\/p>\n
<html><\/code>\u00a0tag, as in
<html ng-app = "myApp"><\/code>. This increases the scope of the Angular app to the entire HTML document. This great, but since I only need it on the front end (for now!), I’m just going to add it to the
<body><\/code>\u00a0tag:<\/p>\n
genesis_attr_body<\/code>. Actually, if you’re using Kint<\/strong><\/a>, you can check and see all the functions firing on that filter\u00a0this:<\/p>\n
add_action( 'genesis_loop', __NAMESPACE__ . 'check_body_class_filters' );\r\n\r\nfunction check_body_class_filters() {\r\n global $wp_filter;\r\n d($wp_filter['genesis_attr_body']);\r\n}<\/pre>\n
add_filter( 'genesis_attr_body', __NAMESPACE__ . 'add_ng_app_to_body' );\r\n\r\nfunction add_ng_app_to_body( $attributes ) {\r\n \r\n $attributes['ng-app'] = 'myApp';\r\n \r\n return $attributes;\r\n}<\/pre>\n
ng-app<\/code>\u00a0is now in our body tag:<\/p>\n
ng-controller<\/code>,
ng-repeat<\/code>, etc. where you need.<\/p>\n
Adding Directives with No Values (i.e. ng-view)<\/h2>\n
ng-view<\/code>\u00a0with\u00a0no value, instead of what we just did. The result we’re looking for is something like
<div ng-view><\/code>, not
<div ng-view="myView"><\/code>. So, how do we accomplish this?<\/p>\n
$attributes['ng-app'] = '' or null<\/code>. However, this does not return as part of the array, and you don’t get anything in there.<\/p>\n
genesis_attr_{context}_output<\/code> filter. This returns a string of the output\u00a0<\/strong><\/em>which we can then filter and return. In my case, I want to filter the
<main class="content">\u00a0<\/code>element string. So, I did this to concatenate on the string:<\/p>\n
\/\/*Add the ng-view to the <main class="content" element\r\nadd_filter( 'genesis_attr_content_output', 'add_ng_view_to_content', 99, 3 );\r\n\r\nfunction add_ng_view_to_content( $output ) {\r\n$output .= ' ng-view';\r\nreturn $output;\r\n}<\/pre>\n
ng-view<\/code>\u00a0to the
<main><\/code>\u00a0tag??” Great questions! For now,\u00a0I want\u00a0the
<main><\/code>\u00a0element to be the part that changes when rendering pages and posts. Genesis will use this element tag no matter the layout (full-width, content-sidebar, sidebar-content, etc.), so I want this to be the element that is updated by Angular.<\/p>\n
Does it work??<\/h2>\n
controller<\/code>\u00a0and some bindings to test. This is all pretty easy to do:<\/p>\n
\/\/*Remove Standard Genesis Loop\r\nremove_action('genesis_loop', 'genesis_do_loop');\r\n\r\n\/\/*Add a controller in the Angular view to work with\r\nadd_action('genesis_loop', __NAMESPACE__ . 'do_ng_view_content');\r\nfunction do_ng_view_content() {\r\n$output = '<div ng-controller="example">\r\n<form>\r\n<input type="text" ng-model="post.placeholder" \/>\r\n<\/form>\r\n<div>{{post.placeholder}}<\/div>\r\n<\/div>';\r\necho $output;\r\n}<\/pre>\n
'use-strict';\r\n\r\nangular.module('myApp', [])\r\n.controller('example', ['$scope', function ($scope) {\r\n$scope.post = {\r\nplaceholder: 'Enter Text'\r\n};\r\n}]);<\/pre>\n
The result?:<\/h2>\n