Twitter Search feed on SharePoint 2010 using RSS Feed Viewer Webpart
Our company uses a SharePoint blog site to make it easy for our attendees to TechEd to share their session notes and other information. This year we wanted to add a twitter search feed for auteched to the front page to make it easier to view what’s going on.
As Twitter provides with their search api, an rss feed of search queries, an easy way to do this was using the RSS Viewer web part built into SharePoint 2010.
Here’s how we set it up:
RSS Feed Url
http://search.twitter.com/search.rss?q=auteched
Xslt
I prefer to keep my xslt sheets separate from the webpart as it makes it easier to edit them and reuse the styles.
Here’s the xslt we ended up using:
<?xml version="1.0" encoding="utf-8" ?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:google="http://base.google.com/ns/1.0" > <xsl:output method="html" /> <xsl:template match="rss/channel"> <link rel="stylesheet" type="text/css" href="/SiteAssets/XSLT/templates/twittersearch.css" /> <xsl:apply-templates select="item" /> </xsl:template> <xsl:template match="item"> <xsl:variable name="twittername"> <xsl:value-of select="substring-before(author,'@twitter.com')" /> </xsl:variable> <xsl:variable name="fullname"> <xsl:value-of select="substring-after(author,'@twitter.com ')" /> </xsl:variable> <xsl:variable name="authorurl"> http://twitter.com/<xsl:value-of select="$twittername" /> </xsl:variable> <xsl:variable name="imagelink"> <xsl:value-of select="google:image_link" /> </xsl:variable> <xsl:variable name="utcpubdate"> <xsl:value-of select="pubDate" /> </xsl:variable> <xsl:variable name="localpubdate"> <span class="utcdate"><xsl:value-of select="$utcpubdate"/></span> </xsl:variable> <div class="twit_holder"> <div class="twit_img"><img src="{$imagelink}" class="twit_img" /></div> <div class="twit_content"> <a class="twit_author" target="_blank" href="{$authorurl}" title="{$fullname}"> @<xsl:value-of select="$twittername" /> </a> <span class="authorname"> <xsl:value-of select="$fullname" /> </span> <div class="twit_tweet"> <xsl:value-of select="description" disable-output-escaping="yes"/> </div> <div><a target="_blank" href="{link}"><xsl:value-of select="$localpubdate" /></a></div> </div> </div> </xsl:template> </xsl:stylesheet>
Css
Then it was just a matter of styling it with some css. I don’t claim to be the most amazing css guru, but I’m happy with how it turned out. Here’s the css used:
.twit_tweet a {
font-size: 13px;
color: #111111;
width: 400px;
}
.twit_date {
font-size: 10px;
color: #333333;
font-style: italic;
}
.twit_author {
font-size:16px;
font-weight:bold;
}
.twit_open {
font-size: 8px;
color: #333333;
}
.twit_holder {
padding-bottom: 15px;
width: 260px;
}
.twit_img{
width: 48px;
height: 48px;
float: left;
}
.authorname{
font-style:oblique;
font-size: 10px;
color: silver;
}
.twit_content{
min-height:48px;
margin-left: 58px;
position:relative;
}
End result
Improvements
The timestamp from the twitter api is in GMT. It would be great to be able to convert this to the local time of the user via some javascript. That was outside the scope of this task however.
Supermarkets vs. Takeaway. (File Systems vs. Search)
One of the things I think people have the hardest time getting their head around when switching from a file system based document storage solution to a search oriented solution is why. “I’ve already learnt where everything is. I don’t need to search for what I need. I can just go to where it is. Why should I change?”
Another problem is that search is called search.
search –verb
to go or look through (a place, area, etc.) carefully in order to find something missing or lost
That does not sound easy to me. Search should really be called ask or request.
An analogy that I think works to answer this question is the difference in efficiency between going to a super market and getting takeaway food.
Supermarkets
The super market is the filing system. Each file is a product, and they’ve been sorted into aisles and sections that group all the like products together, based on some established guidelines (hopefully) on where things should go.
I’m going shopping. This is my regular supermarket, so I know where most things I usually need are. I can walk in, walk to the aisle I need and pretty quickly get the product (file) I’m looking for. If I’m not sure exactly which brand I’m after, I can still pretty quickly find it by going to the right place.
Sometimes I need to find something I don’t usually buy. If I know my supermarket well, I can usually figure out where it should be and start looking, but then sometimes they’ve put it in that organic section instead of where I’d expect it, so I better check there as well. But then maybe it’s under gluten free…
|
and of course, the level of organisation varies… |
And then what about when I have to go to the supermarket across town? I’ve got no idea how this place is organised. I might need to check a map (if I can find that), or else maybe I could ask someone and have them help me find something. I’m not sure they’re going to want to help me with all my shopping though. If I want to keep coming here, I’m going to have to make a concerted effort to figure out where everything I need lives.
And then I just have to pray the supermarket doesn’t decide to reorganise…
That starts to sounds a lot more like searching to me; manually.
Takeaway Food
After all that shopping, I’ve decided I don’t have any energy left to make dinner, so I’m going to get takeaway.
So I walk up to the counter, and I ask for what I want, and it is presented to me.
| lunch! |
This is what search gives you! You place your order, and you receive your item. Naturally different implementations of search are better or worse at giving you what you asked for, sometimes they mix up your order.
But overall, provided the menu is clear, and your order is coherent, they usually get it right. And you can always ask again if they don’t.
If I’m in another city and looking for food, I can go to any takeaway store and ask for what I want. I don’t need to know where they keep their food, or how they organise it. The experience for me, is the same where ever I go.
Renaming folders in a Document Library with PowerShell
After a bit of stuffing round with Rename-Item (don’t try) I discovered this is actually pretty easy.
You just need to use the .MoveTo() method:
PowerShell
#get the folder $folder = $web.GetFolder("http://sharepoint/DocLib/FolderName") #set the path $path = "http://sharepoint/DocLib/NewFolderName" #move the folder to the new path $folder.MoveTo($path)
Mobile Devices not able to Sync after upgrading to Exchange 2010
After moving a mailbox to our Exchange 2010 server, we discovered that an iPhone was unable to sync mail to it.
A quick test at: https://www.testexchangeconnectivity.com/ indicated this error:
Exchange Activesync returned an HTTP 500 response.
The error points to a permissions issue, which was misleading.
Google pointed me at this: http://msexchangeteam.com/archive/2009/12/08/453472.aspx which suggests it maybe a proxying issue.
This didn’t seem to be our issue, so eventually I found this article: http://blog.sallarp.com/exchange-2010-iphone-activesync-issue/ by Björn, you can always depend on a Björn.
Björn pointed me to this http://www.ffoutpost.net/2009/11/10/resolve-issues-with-activesync-not-working-in-exchange-2010 which resolved the issue.
- Goto Active Directory Users and Computers > View > (enable) Advanced Features
- Open the Properties of the user in question.
- Goto the Security tab and select Advanced.
- In the default Permissions tab enable the "Include inheritable permissions from this object’s parent"
- Wait for the AD to replicate and try to sync the iPhone again. If all goes well, it should have fixed the syncing permission issue.
Office 2010 and SharePoint 2007 – Opening files
When opening documents stored on a SharePoint 2007 site with Office 2010 beta 2 you will get an error stating that office was unable to open the document.
To get around this issue you need to set up a "fake proxy" in internet explorer:
|
|
|
|
|
|
Unfortunately this opens a pretty large security hole in IE by detecting every site as local intranet.
You can get around this by disabling automatic intranet detection:
|
|
Nine Thousand Nine Hundred and Ninety Nine more bottles of beer on the wall…
I think this may possibly be the greatest SQL I’ve written all year, if not ever.
First off a function to convert numbers to words:
begin
declare @result varchar(max)
SELECT @result = case
when @n = 1 then ‘One’
when @n = 2 then ‘Two’
when @n = 3 then ‘Three’
when @n = 4 then ‘Four’
when @n = 5 then ‘Five’
when @n = 6 then ‘Six’
when @n = 7 then ‘Seven’
when @n = 8 then ‘Eight’
when @n = 9 then ‘Nine’
when @n = 10 then ‘Ten’
when @n = 11 then ‘Eleven’
when @n = 12 then ‘Twelve’
when @n = 13 then ‘Thirteen’
when @n = 14 then ‘Fourteen’
when @n = 15 then ‘Fifteen’
when @n = 16 then ‘Sixteen’
when @n = 17 then ‘Seventeen’
when @n = 18 then ‘Eighteen’
when @n = 19 then ‘Nineteen’
when @n > 19 then
case
when @n BETWEEN 20 AND 29 then ‘Twenty’ +
case
when cast(RIGHT(cast(@n AS varchar),1) AS int) = 0 then ”
else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar),1) AS int))
end
when @n BETWEEN 30 AND 39 then ‘Thirty’ +
case
when cast(RIGHT(cast(@n AS varchar),1) AS int) = 0 then ”
else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar),1) AS int))
end
when @n BETWEEN 40 AND 49 then ‘Fourty’ +
case
when cast(RIGHT(cast(@n AS varchar),1) AS int) = 0 then ”
else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar),1) AS int))
end
when @n BETWEEN 50 AND 59 then ‘Fifty’ +
case
when cast(RIGHT(cast(@n AS varchar),1) AS int) = 0 then ”
else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar),1) AS int))
end
when @n BETWEEN 60 AND 69 then ‘Sixty’ +
case
when cast(RIGHT(cast(@n AS varchar),1) AS int) = 0 then ”
else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar),1) AS int))
end
when @n BETWEEN 70 AND 79 then ‘Seventy’ +
case
when cast(RIGHT(cast(@n AS varchar),1) AS int) = 0 then ”
else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar),1) AS int))
end
when @n BETWEEN 80 AND 89 then ‘Eighty’ +
case
when cast(RIGHT(cast(@n AS varchar),1) AS int) = 0 then ”
else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar),1) AS int))
end
when @n BETWEEN 90 AND 99 then ‘Ninety’ +
case
when cast(RIGHT(cast(@n AS varchar),1) AS int) = 0 then ”
else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar),1) AS int))
end
when @n BETWEEN 100 AND 999 then
dbo.num_to_text(cast(LEFT(cast(@n AS varchar), 1) AS int)) + ‘ Hundred’ +
case RIGHT(cast(@n AS varchar), 2)
when ’00′ then ”
else ‘ and ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar), 2) AS int))
end
when @n BETWEEN 1000 AND 9999 then
dbo.num_to_text(cast(LEFT(cast(@n AS varchar), 1) AS int)) + ‘ Thousand’ +
case RIGHT(cast(@n AS varchar), 3)
when ’000′ then ”
else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar), 3) AS int))
end
when @n BETWEEN 10000 AND 99999 then
dbo.num_to_text(cast(LEFT(cast(@n AS varchar), 2) AS int)) + ‘ Thousand’ +
case RIGHT(cast(@n AS varchar), 3)
when ’0000′ then ”
else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar), 3) AS int))
end
when @n BETWEEN 100000 AND 999999 then
dbo.num_to_text(cast(LEFT(cast(@n AS varchar), 3) AS int)) + ‘ Thousand’ +
case RIGHT(cast(@n AS varchar), 3)
when ’00000′ then ”
else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar), 3) AS int))
end
when @n BETWEEN 1000000 AND 9999999 then
dbo.num_to_text(cast(LEFT(cast(@n AS varchar), 1) AS int)) + ‘ Million’ +
case RIGHT(cast(@n AS varchar), 5)
when ’00000′ then ”
else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar), 6) AS int))
end
else ‘really big number’
end
else ”
end
RETURN @result
end
Result:
Not brilliant, not perfect, but useful. Where it really becomes a work of art though is in the application:
@i integer = 100,
@container_plural varchar(max) = ‘bottles’,
@container_singular varchar(max) = ‘bottle’,
@contents varchar(max) = ‘beer’
)
AS
declare @s varchar(max)
declare @container varchar(max)
SET @s = dbo.num_to_text(@i)
SET @container = @container_plural
IF @i = 1 SET @container = @container_singular
while @i > 0
begin
print @s + ‘ ‘ + @container + ‘ of ‘ + @contents + ‘ on the wall,’
print @s + ‘ ‘ + @container + ‘ of ‘ + @contents + ‘,’
print ‘Take one down, pass it around,’
SET @i = @i - 1
IF @i = 1 SET @container = @container_singular
SET @s = dbo.num_to_text(@i)
IF @i = 0
begin
print ‘No more ‘ + @container_plural + ‘ of ‘ + @contents + ‘ on the wall!’
end
else
begin
print @s + ‘ more ‘ + @container + ‘ of ‘ + @contents + ‘ on the wall!’
end
print ”
end
Result:

Why Bing Sucks
Outlook 2010 has a neat little "Map It" button next to addresses in your contact form.
I thought I’d give it test and tried to Map my parents address in the charming seaside town of Mornington:
Unfortunately the mapping seems a little off… they did get a charming little sea side town…
But on consulting with Google maps, we find that this charming little sea side town, is quite possibly as far as you can get from Mornington and still be in Australia.
I guess we should give them points for hitting the right landmass.
Debugging Windows Server 2008 crash dumps
- Download debugging tools from Microsoft:
x64 – http://www.microsoft.com/whdc/devtools/debugging/install64bit.mspx
x83 – http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx - Install the complete tools.
- Right click WinDbg and Run as administrator.
- Set the Symbol File Path from the File menu.
- Set the path as: SRV*c:\temp\symbols*http://msdl.microsoft.com/download/symbols

You may have to wait a little while for the symbols to load before you can proceed with the next step. - Open the minidump file
- The file is usually located in %windir%\Minidump
- Wait for the file to finish loading. You will see a Bugcheck Analysis screen once it is finished loading.
- To get detailed information of the crash, click !analyze -v.
This can give you further information about a crash or blue screen which may point you at a driver or application that is causing the crash.
Remove missing devices from Device Manager
Sometimes you can have issues caused by devices that have been physically removed from a system, but are still configured.
It is not possible to normally see these devices in the Device Manager unless you have set a system variable.
The variable you need to set is DEVMGR_SHOW_NONPRESENT_DEVICES and it needs to be set to 1 (true).
You can do this quickly and easily via the command prompt:
- Right click Command Prompt and select Run as administrator
- Type: set DEVMGR_SHOW_NONPRESENT_DEVICES=1 and press Enter.
- Type: start DEVMGMT.MSC and press Enter:
- In Device Manager click View and click Show hidden devices:
- Non present devices will have a faded icon. Right click and select Uninstall:




