labs.steveottenad.com

Help: Pages are downloading rather than being served properly

I woke up this morning to an email from a client alerting me that our Sitecore mobile site was prompting her to download the front page of the site, rather than showing up normally. On hitting it in my browser, I was forced to immediately download a file called ‘download’, with no file extension, that contained the exact HTML source of our homepage.

To troubleshoot we took the following steps (in order)

  • Visit the homepage with ‘default.aspx’ appended to the url (worked)
  • Visit any interior page besides the homepage (all other urls worked)
  • Visit the homepage in many other browsers (failed)

Finally we opened up Fiddler (link), and loaded the homepage normally, then with default.aspx appended to the url. After inspecting both requests, we noticed the failing request was being served with a “text/vnd.wap.wml” mime type.

We ended up going with this solution to solve our issue. Basically what was happening was the wml file was being served to an older phone, and our cdn was caching the request and giving it priority over the text/html request that should be served to normal browsers.

Stubborn Sitecore 302 Redirect

I ran into a very odd instance today where Sitecore was automatically passing a 302 redirect to the “page not found” url. This occurred while trying to access a static file located on the file system. The same behavior manifested itself through both ajax calls from the same server and normal requests from the browser. After further inspection, adding the files path to our sites “IgnoreUrlPrefixes” node in our config file made direct access available. The catch with our site was that we utilized a second config file located in the App_Config/Include folder to handle this. For whatever reason, adding our path to the main web.config made no difference.

Hopefully this saves someone some some time while troubleshooting

Sitecore Development Setup Environment Tips

During the last couple of days I’ve recorded a few tips/gotchas while assisting a co-worker in setting up a sitecore developement environment.

Before Install:

  • Ensure that both the new machine and the old one are running (at least) similar versions of SQL Server, we had one on SQLExpress and it caused some large issues down the road. Read the rest of this entry »

Run multiple sitecore sites from one installation

It is possible, and in fact quite simple, to run multiple “sites” from one sitecore installation by making a few tweaks to a couple settings. Just follow the steps below and hopefully be up and running in a few minutes. Note: This is for a local installation with IIS 7 running, a live/production environment shouldnt be much different, but I have not tested it there so please try this in a non-production setup first.

Read the rest of this entry »

Find your Sitecore Version

To find your Sitecore version:

  1. Log into sitecore, the default url is http://YOURDOMAIN/sitecore/login.
  2. When logging in, be sure to use the “Desktop” user interface, you can doublecheck this setting by clicking the “options” link on the login screen, and selecting the desktop icon.
  3. Once logged in, click the “Sitecore” button in the lower right hand corner (reminiscent of the Start button on a windows machine)
  4. Click: All Applications -> System -> About Sitecore.
  5. Voila!

Finding your sitecore version

Sitecore Broken Link?

We ran across a pretty puzzling Sitecore bug today. It seems that when you are including links to items in Sitecore, if the item you are linking to is not published, the link will not appear. This is quite counter intuitive, as most developers (myself included) would expect a broken link.

In Sitecore, make sure to publish the page/item you are linking to, otherwise the link will not appear AT ALL.

Sitecore Hangs on Publishing

We ran into an issue today around a Sitecore installation getting stuck or locking up when the client was trying to publish content. After booting all the users off the system and looking for solutions we ended up restarting the “Sitecore” app pool. Everything resumed normal operation after the site was down for 2-3 minutes while the app pool cycled.

Sitecore Initializing Screen

Sitecores "initializing" screen shown during publishing

Steps

So to outline the steps for this process:

  • Get to the computer that has your Sitecore installation running, either locally or remotely.
  • Open the start menu and search for “IIS”
  • Right click on the first result (“Internet Information Services (IIS) Manager”) and select “Run as Administrator”
  • Continue
  • Wait for the program to start and expand your website. You should see “Applications Pools” underneath the dropdown.
  • Select application pools and find the Sitecore app pool. Mine was just named “Sitecore” with classic managed pipeline and 1 application running
  • If you select this app pool, you’ll see “Application Pool Tasks” and a Recycle , Stop, and Start links below it.
  • You can either recycle it, or simply Stop it, wait a few minutes, and then start it again.
  • After thats complete, try publishing again. Yay!

Sitecore publishing lockup - app pool tasks

The app pool tasks panel on the right pane of IIS Manager

Popcorn.js Custom Plugin

I took on a custom Popcorn.js plugin for a client of ours who needed to display certain metadata about a video at certain points throughout the video. Initially, this process was shaping up to be a bear, requiring hacky delays to show/hide the information. This method also wasnt synced to the video, so if the client was at full CPU load, the content would routinely get out of sync with the video.

Popcorn.js

Luckily, Mozilla put out the Popcorn.js framework a few weeks ago to deal almost exclusively with these types of problems. However, the included plugins, while super useful, weren’t doing what I needed. Below is a quick walkthrough of my thought process and code samples to create this demo

Existing plugin

Popcorn does supply a couple of design patterns for authoring plugins, but after a few attempts, these werent’ yeilding results as fast as I wanted. I chose to alter an existing plugin that Popcorn ships with, the “Subtitle” plugin [source, extracted from the complete popcorn source].

Code Walkthrough

  Popcorn.plugin( "subtitle" , {
      manifest: {

This section is defining the title of your plugin, in this case “subtitle”, and preparing the plugin to take stock of what arguments it will expect and what type each of those arguments are

manifest: {
        about: {
          name: "Popcorn Pop Plugin",
          version: "0.1",
          author: "Steve Ottenad",
          website: "http://labs.steveottenad.com/"
        },
        options: {
          start: {
            elem: "input",
            type: "text",
            label: "In"
          },
          end: {
            elem: "input",
            type: "text",
            label: "Out"
          },
          target: "subtitle-container",
          text: {
            elem: "input",
            type: "text",
            label: "Text"
          }
        }
      },

This “manifest” section defines each of the arguments that the plugin can accept, as well as what type of objects the arguments are. Note that these manifest arguments are only necessary if you want to use the plugin you are building with Butter, Mozillas WYSIWYG editor that utilizes Popcorn.js

 _setup: function( options ) {
      var c = document.getElementById(f.target);
      f._container = document.createElement("div");
      c.style.width ='0px';
      if (!c && n.plugin.debug) throw Error("target container doesn't exist");
      c && c.appendChild(f._container);
}

Guess what this does? Ya, it is fired at the moment you call your plugin, NOT the moment it is called using the “Start” attribute. Make sure you are scoping your plugin correctly, this was the toughest part for me. The problem is that the plugin can/will create multiple instances of itself, so proper closure is important. In my finished code, I am using the “f” variable to store all instantiation variables and elements (I’m creating a div), and then reference that later in the start/end functions through the “C” variable. You can see the assignment of the f._container to the ‘c’ variable at the end of this function

start: function (f, c) {
	var outer = document.getElementById(c.target);
	c._container.innerHTML = c.text+'<br /><br /><a href="#" class="play button">Play</a>';
	var ref = this;
	ref.pause();
	animateItem(outer, c.width);
	$('.play').live('click', function(){
		toggleState(ref,this,false)
	});
	$('.pause').live('click', function(){
		toggleState(ref,this,true)
	});
 
},

The start function is what fires when your video gets to the point (in seconds) you defined in the plugin call. Each instance you create will have this function assigned to it, so again, its important to scope all your variables and pass in the reference to the function itself, which contains all your _setup variables. Another option would be to do most of your heavy lifting here in the start function if it wont slow down the video and/or doesnt need to be instantaneous

We start be referencing the target we passed in when calling the plugin, then insert some html into the container we created in the _setup function. We can reference all the options we passed into the plugin by using “c.” then the option name. Next, I’m assigning “this” to a variable, since we will need the reference to the actual element we are working on later in the game with some click handlers. The “animateItem” is handling the animation of the element we’ve created and then we’re assigning play/pause click handlers to allow for toggling of the video

end: function (f, c) {
	var outer = document.getElementById(c.target);
	c._container.innerHTML = 'All Done.';
	c._container.style.display="none";
	animateItem(outer, '0px');
},

Any functions you need to fire on the ‘end’ option (in seconds), but before the video actually reaches its end should go here in the “end” function. Im just using it to print out a message, then immediately hide the box, to make room for another instance of the plugin.

Type Mismatch on wpadder.js

I encountered an odd error today working on a SharePoint 2010 Publishing site. After adding all my usual scripts, I was no longer able to use any Web Part adding functionality. Clicking “add a web part” in the web part zones did nothing. Trying to insert a webpart via the ribbon brought up the web part adder, but the majority of it was blank and just kinda busted.

I did however get this error

SCRIPT5: Type mismatch.
wpadder.js?rev=hnGJJEMcU5XH%2BCq7PlSxJw%3D%3D, line 2 character 13993

in the IE debugger under the Script tab error console.

Solution

Sharepoint (and possibly IE in general) has issues with any plugins/scripts that try to extend the Array Prototype. It appears that it breaks quite a few functions and generally is a good idea not to extend it if you dont have to.

So, to wrap it up. If you run into this problem, search through all your javascript for the string “Array.prototype”, or even “Array.” and you should come up with a hit (hopefully), comment that out or find a workaround for that piece of code and you’re good to go

Addition

We (mainly Adam Toth) found that less.js also causes an issue, due to the fact that it redefines all the prototype functions for Arrays. The same root problem, but it was a bit tricker to find. Make sure to do a full-text search on your entire project for the best results. I like Astrogrep to do this. It’s fast, thorough, and free.

Using jQuery to parse YouTube/Vimeo URL’s

Here is a handy script to help parse a url and determine if it contains a vimeo/youtube link, then if it does, return the iframe object to play it. It should be handy for any type of user-generated link field where you would rather display the video inline than link off to it.

The Function

Updated July 11 with better Vimeo regex

function getEmbeddedPlayer(url, height, width){
	var output = '';
	var youtubeUrl = url.match(/watch\?v=([a-zA-Z0-9\-_]+)/);
	var vimeoUrl = url.match(/^http:\/\/(www\.)?vimeo\.com\/(clip\:)?(\d+).*$/);
	if( youtubeUrl ){
		output = '<iframe width="'+width+'" height="'+height+'" src="http://www.youtube.com/embed/'+youtubeUrl[1]+'?rel=0" frameborder="0" allowfullscreen>';
	}else if(vimeoUrl){
		output =  '<iframe src="http://player.vimeo.com/video/'+vimeoUrl[3]+'" width="'+width+'" height="'+height+'" frameborder="0"></iframe>';
	}else{
		output = '<p>no video url found - vimeo and youtube supported</p>';
	}
	return output;
}

How to call it

Note: this uses jquery to grab the value of a text field, but the getEmbeddedPlayer() function does not rely on jquery to work

var width = 640;
var height = 360;
var url = $('#url').val();
var output = getEmbeddedPlayer(url,height,width);
$('#results').html(output);

Try It

Find Video