First things first

Remember in my last post when I said we would start reworking the multiline widget to display different content than it does out of the box?

I have a confession to make.

I lied.

Before we can look into extending a view to do something new and interesting, we should first look into widget extension itself, and how the wizard works. While it is still possible to create a new widget without using the wizard, in the vast majority of cases, you will want to use this. It will create the scaffolding correctly for you, stub out methods for easy overriding and create the yui file for you. If you later decide you have to add more functionality to the widget (I actually needed to extend the logic file…or I need an AJAX endpoint in my controller) then you have two options, you can either update the other files and edit the yml file manually (later post), or you can back up the work you’ve done, delete your widget, create a new one, and replace the code you’ve already developed. In most cases, I would recommend this as constructing your own logic or controller extension file is something of a pain.

So, what should we expect from the widget wizard? Well, first you have to figure out if you’re going from scratch or extending a current widget.

Step 1

It all starts here

If you’re old school, this is a pretty easy decision to understand. If you would go in and copy the Sample widget, rename it and then start creating your own view, logic and controller code, you’re going to want to select Create a New Widget. If, instead, you were going to go copy a widget to custom, rename it and then start tweaking, you’re going to want to select extend the widget. Details for creating a new widget may come in a future post, but for today, in order to get our feet wet with updating an existing widget, we’re going to select extend a widget.

Clicking this presents us with three input boxes, the first asks what widget we are extending. Just start typing the widget you want to use in, then select it from the drop down. Simple. Next, we are asked what we want to call our custom widget. There is code in the wizard that makes sure your widget name doesn’t already exist in the path you specify (more on that in the third field) and, should you accidentally be creating a duplicate widget, the system will save you from yourself and not let you create the widget. Finally, you’re asked what path you want to put the widget in. This is something of a change from the old file scheme, and generally a welcome one. All widgets must be nested in a folder, you can no longer create a widget at the root /custom/ level. This forces us to categorize our widgets. In the case of custom ones, this is generally pretty easy. In most cases, you will use the same subfolder in custom that you copied from in standard.

Major Decisions Here

Major Decisions here

Next up we get to define the components of our new widget. As we are extending from another widget (in this case a ProductCategorySearchFilter widget) we have to tell the wizard what parts we want to extend. For anything server side, such as form submission, retrieving data from the database, writing data TO the database (usually db writes will happen as part of an AJAX based form submission), new data components being exposed to the view, or other server side actions, such as working with a session variable and data manipulation, we need to extend the controller. If you’re going to add new communication between front end and back end, such as looking something up from the DB based upon user interaction on the page, you will need to both extend the controller and select yes for the controller doing its own AJAX handling, which brings us into the second radio button. Spending a bit more time on the first though, the effect of selecting yes to the widget having its own controller is to cause the system to generate a controller file with a baseline constructor which pulls in all the code of its parent, and stubs for all of the methods of the controller allowing you to either add to, or override those methods. If you decide to override a method, bear in mind that future updates to that widget that touch those methods might impact your widget. RNT/Oracle will generally communicate in the patch notes if these updates are likely to impact custom code. If so, you can choose on a per widget basis not to go to the new widget version until you have sanity checked that your own widget does not break.

Selecting yes to the widget doing its own AJAX handling will do three things. First, it will create a stub method in your controller to handle the AJAX request, secondly, it will automatically select yes for you on the Does this widget have its own JavaScript question and thirdly, it will stub out a JS endpoint for your AJAX request. As mentioned above, this is necessary if you are going to need to have any front end/back end interactions between your custom widget. This can also be used if you want to alter how the AJAX interaction of the parent widget operates.

Next you need to select if your widget modifies the parent view. This is probably the most common type of edit you would do to a widget (outside of basic CSS restyling), though getting used to extending a view can take some effort. The recommended option is to extend the view. This allows you to add content to the widget between the block tags that exist within the parent widget. In cases of view code contained between block declarations in the view, this allows you to override that section of HTML/PHP. This takes some getting used to as some view code is not contained between blocks and has to, in my experience be duplicated within a block and then the original removed from the DOM using the logic file, but this allows you to more cleanly edit the view without erasing the content already there. Short upshot of view extending, if you’re just adding content, you’re golden no matter what. If you’re changing content in the parent view, and that content exists between an opening and closing block tag, you can override it (more on this in the extending the view tutorial), and if it exists outside of an opening and closing block tag, you create your own DOM elements either before or after the element in question and then use JS to remove the original element from the DOM.

Your other option with a view modification is to override it. Use this option sparingly. There are two reasons for this. First, it obviously breaks the entire view for later inheritance. More importantly, however, it breaks the link to the logic file, forcing you to construct your own. This is likely due to the tight interaction between the DOM, generally presented by the view and the JS logic that acts on it with subscriptions, events, etc. For this reason, overriding the view will, in nearly all circumstances, cause functionality to fail and should generally be avoided.

View also asks you if you want to include the parent CSS. In most cases, you will want to do this (I don’t know why this isn’t defaulted to yes) as you will want to start from the basic look and feel and then potentially tweak the css from there. If you leave it set to no, the widget will not have its parent css applied and you will have to create your own styling from scratch.

The final heading to deal with here is the JavaScript heading. First you determine if the widget has its own JavaScript. This will create a logic.js stub for you to add your own methods to, modify the constructor and override existing methods, much like extending the controller. If you are adding new YUI components to the widget (such as adding autocomplete to the keyword widget) then you will specify these on the next line where it says Add module. This link will give you a dialog that allows you to begin typing a YUI module for inclusion into the widget. If you miss a module post-creation, not to worry, a simple edit of the YML file, which is created with all widgets, can get it added.

Also in the JavaScript heading is if you want to include the JS templates. These are typically used when the page does an AJAX refresh, such as with the Multiline widget. When a new search happens and data comes back, it uses this JS template to define the ‘new’ view.

Step-3

New Attributes

Old school CP developers will remember attributes living in the Controller file. These days they exist in the YML file and can be manually added and edited there, however the widget allows you a user friendly mode of adding new attributes, for use by the controller, view or logic files. These populate to the ci/admin page for your widget and allow for easy reference of what attributes the widget has.

Step-4

Description

This final piece might not seem important at first, but two years later when you’re doing a code audit, you’ll be kicking yourself if you don’t pay special attention to the Additional Details drop down. This allows you to add a Widget description to the reference page. Here is where you are going to want to outline exactly what your widget does, and how it differs from the baseline widget. This will make it easy for you to go in on a code review and bring that widget up to standard as you will know where in the widget to look. Please don’t ever ignore this.

Step-5

Success!

Finally, you will be presented with the following page showing you all the files you have created with the widget generator. Feel free to drop the widget onto your page now..it should be fully functional as-is…but it will be a clone of its parent. From here you can go into the view, the controller or the logic files (if you created them) and begin editing. Next up, we go in and look at one of those view extension files and talk about how we can modify the view of the widget we’re working with.

Customer Portal 3 – Brave New World

Dystopian connotations aside, the new framework is fully upon us a year in and it’s time for many to begin looking at the road forward. Those just starting on RNT will already be on CP3 and learning things right from the ground up (in theory). Those of us working on older sites have a bit of work ahead of us. Fortunately this work, when done right, can be a great way to learn how things are constructed now. If you’re like me, this will be hard at first (VERY hard in my case), but the work of upgrading a customized site from CP2 to CP3 will give you the chance to experience the changes and get a firm grip on them. If your site is highly customized you’ll be getting that grip for weeks to come. In order to document the various things to understand and pitfalls as well as best (or, lacking true expert opinion, at least decent) practices, I felt this would be a good time to begin blogging on the way things are done in CP3, using real world examples to document how things were, and how things are. We will start with the most basic of functions and then branch out to ever deeper customizations. To start, however, understand that it is not my intention at this time to go over basic MVC and how CodeIgniter itself works. While that may be post-fodder for a later date, these first handful of posts will handle CP3 itself, beginning with this first post, a broad overview of CP3 and how it works differently from CP2.

Back in the old days </grandpa voice> when we wanted to change a widget in any way other than by CSS, we had to copy that widget and make our changes to the view, controller or logic files as the case required. This came with a lot of flexibility, but also had the downside of divorcing that widget from the parent from that point forward. Your Multiline widget gets some neat new highlighting feature? Your CustomMultiline copy will never know about it. You’re going to have to go in and update your code…and who among us has that kind of time? With CP3, some real inheritance/extension has been introduced into widgets. When we create a widget we can choose to extend it from a base widget, and then determine what part of that widget we are impacting. Want to rearrange the display of the answers that the Multiline widget exposes? Then you’re going to modify just the view and ideally extend it. Need some neat new YUI features attached to your input box? Simply extend the logic file. Want to cause your input boxes to do a database write before form submission? Extend the controller with its own built in AJAX endpoint (more on that in a later post) and add a listener to the extended logic file for onBlur.

What all of this means is, we now have the potential to layer code on top of existing code in a way that preserves the baseline. If that baseline updates, our new widget gets the update as well. If we need to go one step further and override a method, either in the controller or logic, and we can’t simply include the parent (in the vast majority of cases we can) then only that small part of the whole codebase gets divorced, the rest of the code inherits just fine. There are exceptions to all of this, which we will go into in later posts, but by and large, inheritance is the watchword of the new framework. How things are done is going to feel very different, but hopefully through the following weeks, with plenty of examples, that learning curve can be simplified. Real world examples are critical for something like this, so the next post will be for performing what is likely the most basic extension for a widget, modifying the view. We will walk through, step by step, how to take the multiline widget and both add to as well as modify how it functions. There are a few gotchas in there, and I’ll go over those as they become relevant.

Stay tuned.