mshtml – changing innerHtml of an element

This has turend out to be a wery pesky problem,.. i just wanted to add to javascript tags that i was reading from another web-page.. But as it tuns out you cant just do it,.. So if you do something like this ,.. it woud not work ,.. innerhtml will not be updated.

HTMLScriptElementClass script = (HTMLScriptElementClass)html.createElement("script"); 
script.innerHTML  = "/**/";

So i decided on another approach (c: If i could not access it, i would make my own,..

//get the html element 
HTMLScriptElementClass script = (HTMLScriptElementClass)html.createElement("script");
script.setAttribute("type", (object)"text/javascript", 0);
script.setAttribute("id", (object)id, 0);
((HTMLBodyClass)html.body).appendChild(script);
// make your own element which holds the changed element
object oScript = html.GetType().GetMethod("getElementById").Invoke(html, new object[] { (object)id });
oScript.GetType().GetProperty("text").SetValue(oScript, "/**/", null);

// remove the old element  to the DOM
html.removeChild((HTMLScriptElementClass)html.getElementById(id));

// insert your own element in to the DOM 
html.Document.Body.AppendChild (element);

well that’s how I did it ,.. and if you are wondering how to read DOM from other pages using .Net take a look at this ,.. (c:
http://cambridgecode.blogspot.com/2009/11/simple-html-parsing-code-using-mshtml.html
Cheers and out.

CSS – full screen overlay layer

Often when you display a gallery of pictures, you want to dim the website in to the background. I have tryed implementing several solutions based on placing a html element on top of all the others by setting position to absolute, and height and width to 100%. That worked ok as long as the page was no bigger than the screen. But when i scrolled the page i noted that my absolute layer was attached to the top of the page,.. so it scrolled with the page,.. so that was clearly not the way to go,..
So here’s what i came up with to solve this,..

.dim
{
			height:100%;
			width:100%;
			position:fixed;
			left:0;
			top:0;
			z-index:1 !important;
			background-color:black;
}

and it worked as a charm,.. position fixed did the trick,. woohoo,..
to make this overlay more fancy you can add opacity to it by setting a
semitransparent png pixel to the background(works in most browsers)
or do it the old fashioned way

filter: alpha(opacity=75); /* internet explorer */
-khtml-opacity: 0.75;      /* khtml, old safari */
-moz-opacity: 0.75;       /* mozilla, netscape */
opacity: 0.75;           /* fx, safari, opera */

How to write the best HTML mail code

I found this wonderfull site http://www.email-standards.org/, that gives a good overview of all available webmail servises and thair compabilaty with HTML standards. It’s som interesting reading (c:

W3C Validate your youtube embed code

Her’s the thing if you take embed code from a youtube chanel and paste it on your webpage you get loads of validation errors.  Try to validate a youtube page (c;
So how do you fix this ,.. here’s an eksample of such embed code

<object width="{$width}" height="{$height}">
<param name="movie" value="{$playUrl}"/>
<param name="allowFullScreen" value="true"/>
<param name="allowscriptaccess" value="always"/>
<embed src="{$playUrl}" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="{$width}" height="{$height}"/>
</object>

this will fail validation bigtime,.. to remedy this get rid of the embed tag, which is  leftover from the good netscape days. Like this

<object type="application/x-shockwave-flash" style="width: {$width}px; height: {$height}px" data="{$playUrl}">
<param name="movie" value="{$playUrl}" />
</object>

Get YouTube video Data via JSON

I will start with one big thanks to peaple from goole and their documentation of Youtube API (c: thay rock ,..
Well, I wanted to get the title of a youtube video by using javascript, and this proved to be very dificult until i found this article
It apears that Youtube Data API alows you to get all the data you need, title, thumbnail You name it, well read the article (c:

ony how i only wanted the title and this is how i did it ..
first add you function.

<script type="text/javascript">
 function FeedCallback( data )
 {
 //get title from YouTube Data API via JSON
   document.getElementById('Title').innerHTML = data.entry[ "title" ].$t;
 }
 </script>

Now this is the busines end of it all

 <script type="text/javascript" src =
 "http://gdata.youtube.com/feeds/api/videos/<yourVideoID>?v=2&amp;alt=json-in-script&amp;callback=FeedCallback"
 </script>

This bit is described her under how it works, here are the bolts and bits of this url

<yourVideoID> is your video ID (c:
v=2 instructs the server to use version 2 of the Youtube API to handle this request
alt=json-in-script instructs the server to send the data in JSON format wrapped inside a call to the callback function; this method is used to avoid crossdomain restrictions imposed by modern browsers.
callback=FeedCallback is the name of the callback function that will handle the JSON data.

that is sweet (c:

P.S here’s some more http://code.google.com/intl/da-DK/apis/youtube/2.0/developers_guide_json.html

How to programaticly update item fields in Sitecore

It is quaite streat forword, there is one thing thou that you should take notice of..
if you just get tour item from master database you can get up getting the wrong version of the item in a wrong language ,.. so this eksample will compile but jeald falsy results.

string guid ="{............}"
Database database = Factory.GetDatabase("master");
Item item = database.GetItem(guid);
item.Editing.BeginEdit();
 using(new EditContext(item))
 {
     item.Fields["fieldname"].Value = "new value";
}
item.Editing.EndEdit();

So to get the right version from the right language, you should do something like this.

Database database = Factory.GetDatabase("master");

Item item = database.GetItem(guid,Sitecore.Globalization.Language.Parse("da"),Sitecore.Data.Version.Latest);

item.Editing.BeginEdit();
 using(new EditContext(item))
 {
      item.Fields["fieldname"].Value = "new value";
 }
item.Editing.EndEdit();

Notice that i am using Sitecore.Globalization.Language.Parse(“da”) to get the language i wanted and Sitecore.Data.Version.Latest to get  the newserst version of my item. (c:

an that is all she wrote (c;

Sitecore6 Lucene indexing webconfig setup Tip

As far as I remember all indexes are build onpublish event in Sitecore. But that is not the case with Sitecore6x to my suprise indexes for web database were never built. So i took a look at the webconfic and to my amazment i had to ad the folowing to make it work as intended.

<database id="web" singleInstance="true"  type="Sitecore.Data.Database, Sitecore.Kernel">
...
 <indexes hint="list:AddIndex">
    <index  path="indexes/index[@id='system']" />
 </indexes>
...
<Engines.HistoryEngine.Storage>
   <obj  type="Sitecore.Data.$(database).$(database)HistoryStorage,  Sitecore.Kernel">
          <param connectionStringName="$(id)"  />
          <EntryLifeTime>30.00:00:00</EntryLifeTime>
    </obj>
 </Engines.HistoryEngine.Storage>
<Engines.HistoryEngine.SaveDotNetCallStack>false</Engines.HistoryEngine.SaveDotNetCallStack>

</database>

more info about Sitecore and Lucene indexing here
http://sdn.sitecore.net/upload/sdn/articles/administration/lucene-search-engine/lucene-search-engine.pdf

well there you have it, another successful fix (c:

Performance tricks when developing Sitecore solutions

When developing you want your solution to be as streamlined as possible, you don’t want to save logs and media files. To cut down in the size of the Sitecore development environment this is what you can do.
Open your web confic and look for this bit:

      <!-- Agent to cleanup work files -->
      <agent type="Sitecore.Tasks.CleanupAgent" method="Run" interval="06:00:00">
        <!-- Specifies files to be cleaned up.
             If rolling="true", [minCount] and [maxCount] will be ignored.
             [minAge] and [maxAge] must be specified as [days.]hh:mm:ss. The default value
             of [minAge] is 30 minutes.
             [strategy]: number of files within hour, day, week, month, year
             [recursive=true|false]: descend folders?
        -->
        <files hint="raw:AddCommand">
          <remove folder="$(dataFolder)/logs" pattern="log.*.txt" maxCount="20" minAge="7.00:00:00" />
          <remove folder="$(dataFolder)/viewstate" pattern="*.txt" maxAge="2.00:00:00" recursive="true" />
          <remove folder="/App_Data/MediaCache" pattern="*.*" maxAge="90.00:00:00" recursive="true" />
        </files>
      </agent>

Change all maxAge atribute to 01:00:00, this wil remove all older files when this agent runs. No more gigabytes of log files to bloat up your solution ,.. sweat (c;

How to avoid Access Denied error while using AllWebs

Hwile running SPSecurity.RunWithElevatedPrivileges we can brows AllWebs whithout hitting the Access denied wall (c:  Her’s how it gows

StringBuilder sb = new StringBuilder(); 
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite sitecol = new SPSite(sharePointRootSite))
{
sb.AppendFormat("{0}", "<ul>");
foreach (SPWeb web in sitecol.AllWebs)
{
if (web.DoesUserHavePermissions(login, SPBasePermissions.ViewPages))
sb.AppendFormat("<li><a href='{0}'>{1}</a></li>", web.Url, web.Title);
}
sb.AppendFormat("{0}", "</ul>");
}
});

This way you only have to show the user only the sites which he/she have promissions to se.
Another good thing is by wraping our statement in a using statement it handles the disposing of IDisposable objects by it self.
it essentially calls .Dispose() when it is done.

Things to remember when using Membership.UpdateUser(MembershipUser user)

You got to love programming it thows you one curve ball efter another (c: thats why i love it so ,..
Her is a good thing to remember,.  when updating membership users, Lets say you want to do something like this

user.IsApproved = true;  //reactivate user
user.Comment = “mjau”; //change comment
Membership.UpdateUser(user);

this code will run just fine, but the result is not what you would expect
When it executes it will only update user.Comment = “mjau” on the other hand user.IsApproved will never be updated.
To make it work you must call Membership.UpdateUser() everytime you make an update, like this.

user.IsApproved = true;  //reactivate user
Membership.UpdateUser(user);

user.Comment = “mjau”; //change comment
Membership.UpdateUser(user);

Well,  that is my conclusion after some trail and error  runs

happy coding

Edit: Check out Sky Sanders Solution for this problem:  http://stackoverflow.com/questions/2721658/membership-updateuser-not-really-updating-the-database/2722173#2722173