In this series of blogs, I'm going to follow the development of an RSS Data Source. I'm going to use Visual Studio 2008, but I'll be using .Net 2.0 features so you should be able to follow along in Visual Studio 2005. You can also use the Express editions of Visual Web Developer (both 2005 and 2008 versions should work). All the code will be in VB.Net, but it should be straightforward enough for C# developers to understand (after all, its all .Net)
Continued from Part II.
Part III - Settings
In this part, we're going to add a setting page so that we can change the RSS feed that our Data Source downloads.
In current versions of the Reports Module, Data Source settings are stored in the ModuleSettings table provided by DotNetNuke. This ensures that all copies of the same module instance will share the same Data Source settings (Visualizer settings are not shared between copies). However, Data Source developers need not (and should not) access these directly. Instead, the Reports Module provides a layer on top of the ModuleSettings table called "Data Source Settings". When the Data Source is executed, the Reports Module passes a Dictionary containing these settings (inside the ReportInfo object). To allow users to edit the settings, we go back to the Settings.ascx file we created in Part I.
Let's start with the user interface for our settings page. All we need for now is a place for the user to enter a feed URL. When we're done, it should look like the screenshot below
Figure 1 - The finished settings UI
So, open up the Settings.ascx file and make sure you are in Design mode. First we need to add a label, so users know what they should type in our text box. In the Solution Explorer, find the file: controls/labelcontrol.ascx and drag it on to the design surface.
Figure 2 - Locating the LabelControl.ascx file
Next drag an ASP.Net TextBox control, from the Toolbox, on to the surface. You should have something that looks like this:
Figure 3 - Locating the LabelControl.ascx file
Now, set the properties of the controls to the following values:
Property |
Value for Label |
Value for Text Box |
ID |
feedUrlLabel |
feedUrlTextBox |
ControlName |
feedUrlTextBox |
N/A |
Width |
N/A |
100% |
Save your changes, and open up the code file: Settings.ascx.vb. Here, we need to add code to connect our text box to the Data Source settings. The key to this is the LoadSettings and SaveSettings methods provided by ReportsSettingsBase. First, we need to import some extra namespaces:
Imports DotNetNuke.Modules.Reports
Imports System.Collections.Generic
Then, we can implement the LoadSettings and SaveSettings methods.
Public Overrides Sub LoadSettings(ByVal Settings As Dictionary(Of String, String))
MyBase.LoadSettings(Settings)
feedUrlTextBox.Text = SettingsUtil.GetDictionarySetting(Settings, _
"FeedUrl", _
String.Empty)
End Sub
Public Overrides Sub SaveSettings(ByVal Settings As Dictionary(Of String, String))
MyBase.SaveSettings(Settings)
Settings("FeedUrl") = feedUrlTextBox.Text
End Sub
The LoadSettings method is provided with a System.Collections.Generic.Dictionary(Of String, String) containing the current settings saved for the Data Source. Our implementation uses the SettingsUtil helper class (provided with the Reports Module) to retrieve a value from the dictionary, or return a default value if it doesn't exist (in this case, an empty string).
The SaveSettings method is also provided with the current settings. However, this method is responsible for retrieving the values entered by the user and updating the settings.
Save the file, and navigate to the Settings page on your test module. You should see our new Settings control displayed, as in the screenshot below:
Figure 4 - Settings page so far
Oops, we still need to put the label text in! We're going to support the DotNetNuke Localization Framework, so we need to put the text in two places.
First, lets add the localized text. Create a Resource File called Settings.ascx.resx in /DesktopModules/Reports/DataSources/RSS/App_LocalResources file and open it. In Visual Studio, you get a nice table interface for editing resource strings. Add the following entries to the table (feel free to tweak the values as you want, just keep the name the same):
Name |
Value |
feedUrlLabel.Text |
RSS Feed URL |
feedUrlLabel.Help |
Enter the URL to an RSS feed to retrieve data from |
Your resource file should look like this after making those changes
Figure 5 - Resource File after entering values
Now, go back to Settings.ascx and set the following properties on the label we created earlier:
Property |
Value |
Text |
RSS Feed URL |
Suffix |
: |
CssClass |
SubHead |
Note: That's a colon (':') in the Suffix property. Also, CssClass is case sensitive.
Now, save and refresh your page. You should see something like the screen shot below:
Figure 6 - The finished Feed URL text box
Now, to change our Data Source code to use this new setting. Let's go back to the /App_Code/RSSDataSource/RSSDataSource.vb file and take a look at the signature for the ExecuteReport method:
Public Overrides Function ExecuteReport(ByVal report As ReportInfo, _
ByVal hostModule As PortalModuleBase, _
ByVal inputParameters As IDictionary(Of String, Object)) As System.Data.DataView
The important parameter here is the report parameter. There is a property called DataSourceSettings on that object which contains the same dictionary we created in SaveSettings. First, delete the FeedUrl constant we were using before. Then add following code to the beginning of the ExecuteReport method to get the Feed URL from the settings:
If Not report.DataSourceSettings.ContainsKey("FeedUrl") Then
Throw New RequiredSettingMissingException("FeedUrl", MyBase.ExtensionContext)
End If
Dim feedUrl As Uri = Nothing
If Not Uri.TryCreate(report.DataSourceSettings("FeedUrl"), UriKind.Absolute, feedUrl) Then
Throw New RequiredSettingMissingException("FeedUrl", MyBase.ExtensionContext)
End If
This code checks for the setting, and if it isn't present or if it isn't a valid URL we throw an exception provided by the Reports Module: RequiredSettingMissingException. We pass it the name of our setting and some contextual information about our Data Source (which is provided automatically by our base class. If the setting isn't present, the Reports Module will automatically display a useful error message indicating that the setting is missing.
While we're in the code, let's add HTML Decoding directly to the Data Source, so we don't have to use the HTML Decode converter in the Module Settings. To do that, we change the line that adds entries to the output table so that it automatically HTML Decodes the description:
dt.Rows.Add(title, New Uri(link), HttpUtility.HtmlDecode(description))
Make sure everything is saved and go back to the website. You should probably go back to the home page, just to make sure everything is properly recompiled. Go back to the settings page for the Reports Module, and make sure the RSS Data Source is selected. Then configure it with your favourite RSS feed. This time, I'll use my personal blog's RSS feed (WARNING: Shameless plug alert!).
Figure 7 - Testing the Settings UI
Once you've done that, make sure the HTML Decode property is set and the HTML Visualizer is properly configured, just like in part 2 and click Update. You should see the RSS feed displayed just like in Part 2, only now we can change the URL!
Figure 8 - The Final Results
Conclusion
At this point, we have a working RSS Data Source! You can stop here if you want, but in the next part I'll cover packaging the Data Source up so that it can be installed in any Reports Module installation.
Download the code so far.