Widgets and Widget_Zone.xml - please help

Topics: Controls
Mar 18, 2009 at 8:59 PM
I'm fairly new to BlogEngine.NET but I have a blog all set up and running.  I recently added the Google Reader widget and couldn't get it to work properly when I noticed something.  I can't edit widgets (newly added or default ones such as Category List).  When I click the edit link it pops up the page for editing but I get a null reference error.  So I had a look at my be_WIDGET_ZONE.xml file and noticed that it never adds any widgets to it (the only ones in there are TextBox, Admin, Search, MonthList, TagCloud and PageList).

I'm not sure exactly how it's supposed to work but under App_Data/datastore/widgets I only have the be_WIDGET_ZONE.xml file and one other .xml file (for TextBox), shouldn't all the other widgets from be_WIDGET_ZONE.xml each have a file?  Either way new widgets should surely be added to the be_WIDGET_ZONE.xml file right?

I have the same sort of problem with extensions, when I add a new one it never creates an xml file under datastore/extensions.  On the admin/extensions screen new extensions don't show up so I can't edit them.

Am I missing something? Somebody please help me.
Coordinator
Mar 18, 2009 at 11:18 PM
Are you by any chance storing your data in a database using the DbBlogProvider?  If so, the data you're looking for would be in the be_DataStoreSettings table.

If you're not using a database, you might want to double check you have Write access setup for the App_Data folder.
Mar 18, 2009 at 11:29 PM

I really appreciate your help and any ideas you (or anyone else) can offer.

I am using the built in storage, I didn't set up a database for it so everything should be in the App_Data folder I think. As for permissions, I have no trouble when it comes to permissions as far as adding posts or users or anything so I don't know what would be any different with this. The folder definitely has Write access.

Mar 18, 2009 at 11:31 PM

PS I just wanted to add that I don't get any errors or anything, its just not doing anything. Thanks.

Coordinator
Mar 18, 2009 at 11:34 PM
Are you using BE 1.4.5?

What about the null reference error when you try editing a widget.  Are there some details you see on the error page when you get the null reference error?  Some of the information on that error page could help determine what the problem might be.
Mar 18, 2009 at 11:39 PM

Yes I am using 1.4.5

As for the null reference error, yes there are some details there that would probably be helpful unfortunately I'm away from the computer so I don't have them right now. I will post them in the morning though, so hopefully someone can help me then. Thanks again for your assistance.

Mar 19, 2009 at 2:22 PM
Edited Mar 19, 2009 at 2:44 PM
So here is the error I get when clicking the edit link of any of the widgets:

Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error:

Line 247:		{
Line 248:			WidgetEditBase edit = (WidgetEditBase)LoadControl(fileName);
Line 249: edit.WidgetID = new Guid(node.Attributes["id"].InnerText);Line 250:			edit.Title = node.Attributes["title"].InnerText;
Line 251:			edit.ID = "widget";

Source File: c:\inetpub\wwwroot\mysite\technologies\blog\admin\WidgetEditor.aspx.cs    Line: 249

Stack Trace:

[NullReferenceException: Object reference not set to an instance of an object.]
   User_controls_WidgetEditor.InitEditor(String type, String id) in c:\inetpub\wwwroot\mysite\technologies\blog\admin\WidgetEditor.aspx.cs:249
   User_controls_WidgetEditor.Page_Init(Object sender, EventArgs e) in c:\inetpub\wwwroot\mysite\technologies\blog\admin\WidgetEditor.aspx.cs:43
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
   System.Web.UI.Control.OnInit(EventArgs e) +99
   System.Web.UI.Page.OnInit(EventArgs e) +12
   System.Web.UI.Control.InitRecursive(Control namingContainer) +333
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +378
 

This is the piece of code from admin/WidgetEditor.aspx.cs where the error comes from:

/// <summary>
 /// Inititiates the editor for widget editing.
 /// </summary>
 /// <param name="type">The type of widget to edit.</param>
 /// <param name="id">The id of the particular widget to edit.</param>
 private void InitEditor(string type, string id)                                                                <------The id being passed in is always 00000000-0000-0000-0000-000000000000
{
  XmlDocument doc = GetXmlDocument();
  XmlNode node = doc.SelectSingleNode("//widget[@id=\"" + id + "\"]");        <------The node from this line is coming back null
  string fileName = Utils.RelativeWebRoot + "widgets/" + type + "/edit.ascx";

  if (File.Exists(Server.MapPath(fileName)))
  {
   WidgetEditBase edit = (WidgetEditBase)LoadControl(fileName);
   edit.WidgetID = new Guid(node.Attributes["id"].InnerText);
   edit.Title = node.Attributes["title"].InnerText;
   edit.ID = "widget";
   edit.ShowTitle = bool.Parse(node.Attributes["showTitle"].InnerText);
   phEdit.Controls.Add(edit);
  }

  if (!Page.IsPostBack)
  {
   cbShowTitle.Checked = bool.Parse(node.Attributes["showTitle"].InnerText);
   txtTitle.Text = node.Attributes["title"].InnerText;
   txtTitle.Focus();
   btnSave.Text = Resources.labels.save;
  }

  btnSave.Click += new EventHandler(btnSave_Click);
 }

Coordinator
Mar 19, 2009 at 6:05 PM
Thanks for posting the error message.  It's actually only slightly helpful.  It basically shows that the widget doesn't have an ID, and that's probably because when you add the widget, it's not correctly getting added, and isn't getting an ID --- something we already we're thinking.

So, when you add a widget, the widget gets visibly added to the sidebar, but the be_WIDGET_ZONE.xml file isn't updated.  I would definitely try double checking the Write permissions.  It's possible write permissions weren't propagated down to all the files and sub-folders within App_Data.  You could try removing Write permissions, then add them back.

Is everything else in your blog working right?  If you add a blog post, can you upload a file/image into the post?  Those images/files would be stored under App_Data\files.  Can you add a Page in the control panel?  Pages get stored under App_Data\pages.  See if these things work ...
Mar 19, 2009 at 6:18 PM
Thanks for all your help.

I have double checked the permissions on the App_Data folder and all folders beneath that (datastore, files, logs, pages, posts, profiles).
The Write permissions are set up the same for all of them and I see nothing wrong there.

Everything else on the blog is working fine.  I can add blog posts and upload images into the post (post xml file is created with no issues, image goes in the files folder no problem).
Pages add just fine.

If I remove the Write permission and try to add a post or anything I get an error, which I don't get with the permissions in there.
So I would think (?) that I should be getting an error when it's trying to add the widget xml file if it's a permission problem but I don't get an error, it just doesn't add it.

I'm still very confused but thanks again for all your time.
Mar 19, 2009 at 6:49 PM
Does anyone know where in the code it creates the widgets xml file?
Coordinator
Mar 19, 2009 at 7:00 PM
There's a few files.  There's the WidgetZone.cs file under App_Code\Controls that initally loads the be_WIDGET_ZONE.xml file and adds each widget into the widget zone.

But probably of more importance right now is the WidgetEditor.aspx and WidgetEditor.aspx.cs files in the Admin folder.  The code behind file contains the AddWidget() method which calls the SaveNewWidget() method.  If you wanted to debug this and look into it, those areas are probably the first areas to look at.
Mar 19, 2009 at 7:35 PM
As far as the WidgetEditor.aspx.cs goes, it never gets to the AddWidget() function.  Here is the Page_Init() code from WidgetEditor.aspx.cs which gets called when you click the edit link for a widget:

 protected void Page_Init(object sender, EventArgs e)
 {
  if (!User.IsInRole(BlogSettings.Instance.AdministratorRole))
  {
   Response.StatusCode = 403;
   Response.Clear();
   Response.End();
  }

  string widget = Request.QueryString["widget"];                             <------This comes through fine as the name of the widget
  string id = Request.QueryString["id"];                                            <------This is always coming through as 00000000-0000-0000-0000-000000000000
  string move = Request.QueryString["move"];                                <------This is null
  string add = Request.QueryString["add"];                                    <------This is null
  string remove = Request.QueryString["remove"];                            <------This is null

  if (!string.IsNullOrEmpty(widget) && !string.IsNullOrEmpty(id))
   InitEditor(widget, id);                                                                    <------This passes the id (00000000-0000etc.) and the null reference error happens in the InitEditor function that is called

  if (!string.IsNullOrEmpty(move))                                                    <------It never reaches here or anything past here because of the null reference error
   MoveWidgets(move);

  if (!string.IsNullOrEmpty(add))
   AddWidget(add);

  if (!string.IsNullOrEmpty(remove) && remove.Length == 36)
   RemoveWidget(remove);
 }
--------------------------------------------------------------------------------------

So it's not in the AddWidget part it's long before that I think.
As for this line of code (string id = Request.QueryString["id"]; which is always coming through as 00000000-0000-0000-0000-000000000000) where does it get that id from is the real question?
Does the widget.js file have any role in this?

Coordinator
Mar 19, 2009 at 9:20 PM
When adding a new widget, I also have null values for most of those querystring values -- except for Request.QueryString["add"].  The value for "add" is the name of the Widget being added.  So if I add a Month List, the "add" querystring value is "Month List".  This querystring value is set in widget.js -- in the addWidget() function.  You can see in the addWidget() js function, it creates a callback (an AJAX request) to WidgetEditor.aspx.  It includes the "add" querystring value.

So, when you're adding a widget, the "add" querystring value should not be null.  The other values can (and will) be null.  And the "id" querystring parameter should actually be NULL (or an empty string).  The URL the Ajax request is done to should be something like:

http://localhost/blog/admin/WidgetEditor.aspx?add=Twitter&rnd=0.0686097119258483

... where the "add" querystring value is "Twitter" and the "rnd" querystring value is just a random value to prevent undesired caching.  Inside Page_Init, you can check what the URL is ...

Request.Url.ToString()

Also, I would look at maybe adding a line of code in the addWidget() JS function in widget.js.  I added the alert() statement below.

function addWidget(type)
{
  alert(type);
  CreateCallback(KEYwebRoot + "admin/WidgetEditor.aspx?add=" + type + "&rnd=" + Math.random(), appendWidget);
}
Mar 19, 2009 at 10:08 PM
Edited Mar 19, 2009 at 10:12 PM
Once I'm logged in, for my widget I see an edit link and a delete link, so nothing about adding (should there be?).

Okay, here is my "Request.Url.ToString()" when clicking the Edit button on the widget
http://localhost/mysite/technologies/blog/admin/widgeteditor.aspx?widget=Google Reader Picks&id=00000000-0000-0000-0000-000000000000

And here is my "Request.Url.ToString()" when clicking the Remove button on the widget (which seems to work fine except there isn't actually anything to remove since it hasn't been added)
http://localhost/mysite/technologies/blog/admin/WidgetEditor.aspx?remove=00000000-0000-0000-0000-000000000000&rnd=0.30717627852281653

In the widget.js I can see the addwidget() function, which if reached would give me the url you are talking about:
http://localhost/mysite/technologies/blog/admin/WidgetEditor.aspx?add=Google Reader Picks&rnd=0.30717627852281653

Looking through the code the only reference to it (the addwidget() js function) that I see anywhere is in WidgetZone.cs Render() function.

As for adding the "alert(type)" into the addWidget part of widget.js....I tried but, as I said it never makes it that far because it can't initialize the editor properly.

In your last post you keep saying when "adding a new widget", I'm not sure what you mean since I see no add button.  Basically to add it I'm adding the folder with the files to the blog/widgets folder.
Then I am adding a reference to it on my theme.master page and adding the control to the page.  I've also tried adding a GoogleReader.LoadWidget() function to the masterpages .cs Page_Load() function, although I'm not sure if that's supposed to be necessary (currently it's the only way to get the widget to show up).  I've also tried all this stuff without the LoadWidget call just to be clear.

Thanks for continuing to assist me, much appreciated.
Coordinator
Mar 19, 2009 at 10:18 PM
In your theme's site.master file, do you have a WidgetZone control?  It would look something like this:

<blog:WidgetZone runat="server" ID="rightzone" />

If you have that, then when logged into your blog, there should be a dropdown list containing a list of the available widgets.  Next to the dropdown list will be an "Add" button.  So you would select a widget from the dropdown list and click the "Add" button.  This calls the addWidget() JS function.

The dropdown list gets automatically populated with the widgets available in the widgets folder.

Mar 23, 2009 at 3:20 PM
You know, I knew somehow that at the end of this I would feel foolish, lol.

Apparently I have picked a theme that does not use the WidgetZone.
I tried adding it and using that instead of the individual widgets being put on the sidebar, as the theme I'm using currently does, but it screws up all the css for the widgets.
When I did add the widget zone all the xml files were created as they should be, so thanks for all your help.  I guess if I want better control over my widgets I'll have to switch themes or spend some time adjusting all the CSS for them.

Thanks again for all your help, it was much appreciated.  For now I'll just stick with what I've got as far as themes, at least I know why I can't do some stuff from the admin menu.