Settings extensions
The settings item can be extended to provide custom features that don't necessarily have to involve saving a value to the registry. Think of the settings item as a multi-purpose item. It can be used to implement features that are unrelated to any of the other item types. One possible use for the settings item would be to display local movie showtimes based on a user-defined zip code. The example below shows how this could be accomplished.
The first step is to add a settings item to your primary feed. Set the enableextensions attribute to true and include 2 extension elements as child nodes of the settings item. If this were to be used in a real channel then I'd recommend changing the image to something that doesn't contain any references to "settings" to avoid any potential confusion.
<item type="settings" title="Movie showtimes" sdposterurl="pkg:/images/sdsettings.png" hdposterurl="pkg:/images/hdsettings.png" enableextensions="true"> <extension name="saveZip"/> <extension name="showtimesByZip"/> </item>
The next step is to code the 2 extensions and drop them in the source/extensions folder. The saveZip extension should be fairly easy to program and you could use the existing helloregistry example for the majority of the code. You can find a link below to download both examples so I'm going to skip the saveZip extension and move on to the showtimesByZip extension.
Function showtimesByZip() As Object extension = { title: "Showtimes by zip code", description: "Retrieve movie showtimes for a zip code", isEnabled: true, enableForItems: ["settings"], buttonLabel: "Local movie showtimes", codeToExecute: "execShowtimesByZip(xe)", enableParagraph: false, paragraphCodeToExecute: "" } return extension End Function
It's important to remember that the function name MUST match the file name for all extensions. Since the function above is named showtimesByZip then the file MUST be named showtimesByZip.brs.
The majority of the properties should be self-explanatory. We want to enable this for settings items so we include "settings" in the enableForItems array. There's no need to display any text on the settings screen for this extension so we set the enableParagraph property to false and leave the paragraphCodeToExecute string empty.
The only unique aspect of the code above involves the codeToExecute property. Instead of just specifying a function to execute we include the xe variable as an argument. The xe variable stands for "xml element" and represents the item that the extension has been installed on. By passing the xe variable as an argument we can now access all of the xml attributes on the settings item.
Function execShowtimesByZip(xe As Object) As Boolean showtimesUrl = "http://www.google.com/movies?near=" regvalue = getStrValFromReg("zipcode", "profile") if len(regvalue) < 5 then if not(execSaveZip()) then return false regvalue = getStrValFromReg("zipcode", "profile") endif showtimesUrl = showtimesUrl + regvalue
The showtimesUrl variable represents the url of the html document that we want to retrieve and display. The code above attempts to retrieve a zip code value from the registry and if it is less than 5 characters in length then it executes the saveZip extension. Since we know that the other extension exists there's no need to duplicate the code here to save the zip code. Just call execSaveZip() which is located in the other extension script. After a valid zip code is retrieved it is added to the end of the showtimesUrl.
if xe.item.Count() < 1 then item = xe.AddElement("item") item.AddAttribute("type", "document") item.AddAttribute("title", regvalue) item.AddAttribute("striphtml", "true") item.AddAttribute("stripews", "true") item.AddAttribute("regexfilter", "^.+<div id=movie_results>|<div id=navbar.+$") endif xe.item[0].AddAttribute("url", showtimesUrl) displayDocument(xe@title, xe.item[0]) return true End Function
Settings items are not intended to support child item nodes but in an extension you can pretty much make up your own rules. The code you use here doesn't have to comply with the orml specification. Since the displayDocument function requires a xml element as the second argument the simplest solution is to create a new item element and append it as a child node of the settings item. The item element only has to be created once since it will remain in memory as long as the channel is loaded. Make sure to add the url attribute each time the extension is executed just in case the zip code has been modified in the registry.
At this point you should now be able to load the channel and select the custom settings item. Two new buttons should appear on the settings screen labeled "Change zip code" and "Local movie showtimes." Press the "Change zip code" button to enter a zip code and save it to the registry. Press the other button to retrieve the zip code from the registry, append it to a url and load an external document.
Html search results
Search items require all search results to be returned as xml. Any xml format can be converted to orml through the use of a template but it is not currently possible to retrieve html search results and display them directly. One solution to this problem is to create a php script that will accept a search term and then return an orml feed containing 1 or more document items. When the document item is selected it will then retrieve and display the html document. The first step is to add the following code to your primary feed.
<item type="search" title="Search for movie showtimes by zip code" sdposterurl="pkg:/images/sdsearch.png" hdposterurl="pkg:/images/hdsearch.png" senddevid="false" paramname="zip" url="http://openrokn.sourceforge.net/getFeedForSearchResults.php"/>
Then create a php script that defines a search url and appends the "zip" parameter to the end of the url.
$zip = $_REQUEST['zip']; $url = "http://www.google.com/movies?near=" . $zip;
The search item requires that the results be returned as a primary orml feed so we have to begin the feed with either a grid or poster item. For this example we'll use a flat-episodic-16x9 poster item.
$doc = new DOMDocument("1.0", "UTF-8"); $doc->formatOutput = true; $orml = $doc->createElement("orml"); $orml->setAttribute("version", "1.2"); $orml->setAttribute("xmlns", "http://sourceforge.net/p/openrokn/home/ORML"); $doc->appendChild($orml); $channel = $doc->createElement("channel"); $orml->appendChild($channel); $poster = $doc->createElement("item"); $poster->setAttribute("type", "poster"); $poster->setAttribute("style", "flat-episodic-16x9"); $poster->setAttribute("title", "Results"); $channel->appendChild($poster);
We now have a primary feed that contains an empty poster item. The next step is to create 1 or more document items and append them as child nodes of the poster.
$docitem = $doc->createElement("item"); $docitem->setAttribute("type", "document"); $docitem->setAttribute("title", "Google"); $docitem->setAttribute("shortdesc", "Movie showtimes for " . $zip); $docitem->setAttribute("sdposterurl", "http://openrokn.sourceforge.net/images/sddocuments.png"); $docitem->setAttribute("hdposterurl", "http://openrokn.sourceforge.net/images/hddocuments.png"); $docitem->setAttribute("url", $url); $docitem->setAttribute("striphtml", "true"); $docitem->setAttribute("stripews", "true"); $docitem->setAttribute("regexfilter", "^.+<div id=movie_results>|<div id=navbar.+$"); $poster->appendChild($docitem);
And lastly, set the mime type and print the xml.
header("Content-type: application/xml"); echo $doc->saveXML();
That's it! You can now use the search item to enter a zip code and retrieve a list of document items that each contain an external url with the user-defined zip code. You could use this same process to display localized weather or news articles or to perform any type of search that returns html results.
The examples above have been added to a fully functional Roku channel that can be downloaded at the link below.
Absolutely Wonderful!!!
This is Exactly what I was looking for!
And to top it off, Your instructions are clear and easy for a novice like me to fully grasp!!
Thank you Again!
~Gary