The following code is a web user control that count access to a given documentType which contains a property with alias = WdT_Counter. It is intended for counting access to a web page. Through the variable startCount, passed by a Macro, you will be able to choose the number that means 0 for you (but 0 is not nice to see on a webpage, is it ?) It use dictionary entry to render in multiple languages ([#creation] and [#counter] are just bookmarks).
But, there is a bug. If document type already exists, and you add a new property, the new property is displayed as an empty field when you look at your document (Content section) but doesn't exist in cache. So that line 4 in Page_Load is causing crash. (the property doesn't exist yet). How can I fix that piece of code. I think that I should save and update cache before Page_Load event. Or should I publish document before access the node property ? or access directly Document instead of Node to load property value ? What is the best practice ?
Thanks for your help
public partial class WdT_Counter : System.Web.UI.UserControl
{
private string counter_text;
private int _startCount;
public int startCount { set { this._startCount = value; } }
I'm not completely sure what you're doing: are you trying to keep track of the number of visits for each document of type 'WdT_Counter'? If so, I think you're method is not really best practice because you're using the document api on the frontend which has really bad performance as it hits the database quite often, even for reading a single property. Besides that, you're constantly updating the cache for each visit to such a page, and this may slow down your complete system.
Consider keeping 'visitor tracking' info in custom tables and read that info using a single sql query.
Thanks for your kind answer. I'll try to explain what I was planing to do:
In an existing website, I have added a property "WdT_Counter" to a "webpage" doctype with a custom "WdT_Counter" datatype, stored as NVarChar on umbraco DB. The meaning was to allow editors to see in the back-end how many times their single pages were read, adding a label displaying the counter in the back-end.
That number can also be viewed front-end, on the visited web page and formated according to a text string saved as dictionary entry.(In dictionary you would find a string like : viewed [#counter] since [#creation].
So, yes, I thought it was a good idea to read that property from cache - and probably I was wrong from a performance point of vue, cast the string to int, and add 1 to that number before to display.
On the same operation, I save the new number to the document and refresh the cache for next access.
As an option, I decide that counter shouldn't automatically start from 0 but from whatever the editor wants (ex. he decides that the page should displays 726 visits at first visit and number grows up from there)
This was first of all an exercise to manipulate apis, I realize that your method to store the number in a custom table is much better and I never thought performances issues were so tough.
But my main question is: When you have added a new property on a previously existing documentType (maybe you have already hundreds of existing pages of that kind) and you don't want to click the "save and publish" button on every single page, what could you do avoid that a call like
causes an error on the page? I think that the page crashes because the just added property is not saved in the cache yet, even when you republish the entire site. (It doesn't exist when I try to access it). It goes in the cache only when you click "save and publish" or doesn't it ?
a very simple access counter - need help
The following code is a web user control that count access to a given documentType which contains a property with alias = WdT_Counter. It is intended for counting access to a web page. Through the variable startCount, passed by a Macro, you will be able to choose the number that means 0 for you (but 0 is not nice to see on a webpage, is it ?) It use dictionary entry to render in multiple languages ([#creation] and [#counter] are just bookmarks).
But, there is a bug. If document type already exists, and you add a new property, the new property is displayed as an empty field when you look at your document (Content section) but doesn't exist in cache. So that line 4 in Page_Load is causing crash. (the property doesn't exist yet). How can I fix that piece of code. I think that I should save and update cache before Page_Load event. Or should I publish document before access the node property ? or access directly Document instead of Node to load property value ? What is the best practice ?
Thanks for your help
public partial class WdT_Counter : System.Web.UI.UserControl
{
private string counter_text;
private int _startCount;
public int startCount { set { this._startCount = value; } }
protected void Page_Load(object sender, EventArgs e)
{
Node n = Node.GetCurrent();
this.counter_text = umbraco.library.GetDictionaryItem("WdT_Counter");
string creationDate = n.CreateDate.ToShortDateString();
string counter = n.GetProperty("WdT_Counter").Value.ToString(); //or just Value ?
/ if (counter == "") { counter = _startCount.ToString(); }
int count = int.Parse(counter);
if (count < _startCount) { count = _startCount; } else { count++; }
this.counter_text = counter_text.Replace("[#creation]", creationDate);
this.counter_text = counter_text.Replace("[#counter]", count.ToString());
this.litCounter.Text = counter_text;
Document doc = new Document(n.Id);
doc.getProperty("WdT_Counter").Value = count.ToString();
User u = new User(0);
doc.Save(); // Is this necessary ? or Publish is good enough ?
doc.Publish(u);
umbraco.library.UpdateDocumentCache(n.Id);
}
}
Hi,
I'm not completely sure what you're doing: are you trying to keep track of the number of visits for each document of type 'WdT_Counter'? If so, I think you're method is not really best practice because you're using the document api on the frontend which has really bad performance as it hits the database quite often, even for reading a single property. Besides that, you're constantly updating the cache for each visit to such a page, and this may slow down your complete system.
Consider keeping 'visitor tracking' info in custom tables and read that info using a single sql query.
Hope this helps.
Cheers,
/Dirk
Hi Dirk,
Thanks for your kind answer. I'll try to explain what I was planing to do:
In an existing website, I have added a property "WdT_Counter" to a "webpage" doctype with a custom "WdT_Counter" datatype, stored as NVarChar on umbraco DB. The meaning was to allow editors to see in the back-end how many times their single pages were read, adding a label displaying the counter in the back-end.
That number can also be viewed front-end, on the visited web page and formated according to a text string saved as dictionary entry.(In dictionary you would find a string like : viewed [#counter] since [#creation].
So, yes, I thought it was a good idea to read that property from cache - and probably I was wrong from a performance point of vue, cast the string to int, and add 1 to that number before to display.
On the same operation, I save the new number to the document and refresh the cache for next access.
As an option, I decide that counter shouldn't automatically start from 0 but from whatever the editor wants (ex. he decides that the page should displays 726 visits at first visit and number grows up from there)
This was first of all an exercise to manipulate apis, I realize that your method to store the number in a custom table is much better and I never thought performances issues were so tough.
But my main question is: When you have added a new property on a previously existing documentType (maybe you have already hundreds of existing pages of that kind) and you don't want to click the "save and publish" button on every single page, what could you do avoid that a call like
string counter = n.GetProperty("WdT_Counter").Value.ToString()
causes an error on the page? I think that the page crashes because the just added property is not saved in the cache yet, even when you republish the entire site. (It doesn't exist when I try to access it). It goes in the cache only when you click "save and publish" or doesn't it ?
Hi,
But I would also suggest that you used a sql table for performance reasons.
/Jesper Ordrup
try/catch... of course... it was too obvious for a complicated mind like mine. Thank you very much Jesper.
Updating a property on the document for each visit, will result in a new version for each visit, or should anyway.
I'd consider using a statistics system for tis, like Google Analytics.
I will do it certainly. I had an eye on the rollback function and I can only agree with you.
is working on a reply...