The Medium Has the Message and My Blog Is Trying to Catch Up

I’ve really been digging the content I’ve been finding through Medium for the last few months or so. The Web is ever-evolving and to me Medium represents a new paradigm for Web publishing and content consumption. It’s sort of blogging combined with content crowd-sourcing combined with highlighting like I have on my Kindle combined with… Well, it’s unique, so it’s not really just the sum of those parts.

To me, one of the best parts of Medium is the Staff Picks and Top Stories. These two categories give me solid content to read that is either vetted by the platform owners or popular with the platform readers. One of the cool things about this is that it cuts across all topic areas. I’m as likely to want to read one of Eric Elliott’s (@_ericelliott) excellent posts about JavaScript and its communities like this or this or something like When the heck did learning to code become cool? And why it sucks to be a beginner today… which are squarely in my own wheelhouse to interesting takes on Web design like Optical Adjustment – Logic vs. Designers.

But what makes it even more fun is the stuff I run across that to many people would seem sort of random. None of us is so one-dimensional that we cannot enjoy reading something completely new to us. Medium ensures that when we go off on one of those mental tangents, that it’s a higher quality one.

When I spot one of these seemingly random posts, I can see about how long it might take me to read it, so it’s clear going in if how much time I’ll need to invest. (I’m a pretty fast reader, so for me the number is usually an upper bound – YMMV.) Those times must be built up magically based on how long people really spend and the posts and seem pretty accurate to me.

How many minutes?

The biggest thing I notice as I read posts on Medium is that I feel a need to up my own game, to write more pithy and valuable posts. Ever since I started blogging, I’ve had a little voice in my head that writes posts that come out of ordinary, every day experiences. These aren’t the “here’s a piece of code to fix a particular problem” posts, but often the softer stuff that makes the fact that the code exists have more purpose. It might have nothing to do with my professional life at all. (Maybe it’s hard to believe, but I do have a few other interests besides SharePoint.) I wish I actually spent the time to get more of those posts written.

I found an article that shows how to make your own blog a bit more “Medium-like” and I’ve added some new plugins to my blog here based on those suggestions. (See WordPressium: Creating a Medium-like Experience)

As of today, you can do a few new things on my blog…

Selection Sharer

Courtesy of Hans van Gent’s Selection Sharer plugin, you can now highlight any piece of text in one of my posts and send it as a Tweet, post it to LinkedIn, or send it in an email. (This assumes I ever say anything quotable, which I know is a huge assumption.) I would expect that he’ll add some more sharing options over time.

Reading Time

The Reading Time plugin adds some info on how long a post might take to read. You’ll see the estimate based on an average reading speed at the top of each post as you visit it. As you stay on the page, a little progress bar shows how much of that time has elapsed. Of course, reading a post full of code is different than just reading prose, so time will tell how useful this is. It can at least be a little game; can you beat the progress bar?

I hope that you find these two new capabilities useful. Let me know what you think!

Displaying Blog Posts in Different Sites in SharePoint 2010

SharePoint blogs are no one’s favorite. There is just enough functionality there to make them useful, but not enough functionality to make them useful enough. On top of that, blogs are sites, not lists. That seems counterintuitive on one level – isn’t it just a list of posts? – but it makes sense on other levels. There are actually three important lists in a blog site: Posts, Comments, and Categories. There are two other lists as well – Photos and Links – but I rarely see them used in blog sites.

Because there are multiple lists and the site itself has some unique functionality, it actually does make sense that it is a separate site that uses a unique Site Template.

image

One problem with this is that it is then difficult to display blog posts in other sites. Sure, you can use the Content Query Web Part (CQWP) to do it, but the display options out of the box are pretty abysmal. Other options are an RSS Web Part or even search.

However, if you want to display blog posts elsewhere with any sort of fidelity, you will probably want to use a Data View Web Part (DVWP).

In this post, I’ll show you the quick steps to make that work, without much beautification. I’ll assume you already have your blog site up and running. The basic idea is that we will created a DVWP in the blog site, make a few manual edits to it, and then copy it into a page in another site. One note: I’m a bit more of a hack, so I would shortcut past a few of these steps. I’m trying to make it very straightforward and involving as little manual coding as possible.

Step 1: Create the DVWP

Open the blog site with SharePoint Designer. The home page of the blog site is default.aspx, so make a copy of that page and edit it in Advanced Mode. You’ll want to use the Design View or Split View for this. Enjoy them now, as they are gone in SharePoint Designer 2013!

On the ribbon, choose Insert / Data View / Empty Data View. If you choose a list at this point, you’ll end up with an XLV Web Part instead, which won’t work for our purposes because they cannot pull information from other sites – only DVWPs are good for this. Click on the ‘Click here to select a data source’ link and choose the Posts list.

image

Add whatever columns you’d like to display in your DVWP as a Multiple Item View. For this example, I’ve chosen Title, Created, and Created By.

image

Right click on the Title column and choose Format item as / Hyperlink to / Display form. The link will have a hard-coded URL, which is bad, but remember we’re just doing the basics here. It’ll work to get you to the actual post for the other site.

image

Make whatever other changes you’d like in the DVWP (Paging, Item Limits, column formatting, etc.), save the page, and test it in the browser. You should see your DVWP where you inserted it in the page. Mine is right up top:

image

Step 2: Modify the DVWP’s DataSource

Once you have the DVWP showing what you’d like to see, we have a couple more things we need to do to the DVWP to make it work in the other site.

Somewhere in the code for the DVWP, you’ll see the DataSources section. It’ll look something like this, depending on how you’ve formatted the DVWP:

<DataSources>
  <SharePoint:SPDataSource runat="server" DataSourceMode="List" UseInternalName="true" UseServerDataFormat="true" selectcommand="&lt;View&gt;&lt;/View&gt;" id="dataformwebpart1">
    <SelectParameters>
      <WebPartPages:DataFormParameter Name="ListID" ParameterKey="ListID" PropertyName="ParameterValues" DefaultValue="{AEC1CA2C-EFA6-4218-A742-5939F94E0DDE}"/>
      <asp:Parameter Name="StartRowIndex" DefaultValue="0"/>
      <asp:Parameter Name="nextpagedata" DefaultValue="0"/>
      <asp:Parameter Name="MaximumRows" DefaultValue="10"/>
    </SelectParameters>
    <DeleteParameters>
      <WebPartPages:DataFormParameter Name="ListID" ParameterKey="ListID" PropertyName="ParameterValues" DefaultValue="{AEC1CA2C-EFA6-4218-A742-5939F94E0DDE}"/>
    </DeleteParameters>
    <UpdateParameters>
      <WebPartPages:DataFormParameter Name="ListID" ParameterKey="ListID" PropertyName="ParameterValues" DefaultValue="{AEC1CA2C-EFA6-4218-A742-5939F94E0DDE}"/>
    </UpdateParameters>
    <InsertParameters>
      <WebPartPages:DataFormParameter Name="ListID" ParameterKey="ListID" PropertyName="ParameterValues" DefaultValue="{AEC1CA2C-EFA6-4218-A742-5939F94E0DDE}"/>
    </InsertParameters>
  </SharePoint:SPDataSource>
</DataSources>

We need to add the WebURL parameter, as I describe in my older post Using a DataSource in a Data View Web Part (DVWP) in a Different Site in SharePoint Designer 2010. You should use the relative path to the blog site as the value. In my case, it’s “/sites/demos/blog”.

The end result should be something like this:

<DataSources>
  <SharePoint:SPDataSource runat="server" DataSourceMode="List" UseInternalName="true" UseServerDataFormat="true" selectcommand="&lt;View&gt;&lt;/View&gt;" id="dataformwebpart1">
    <SelectParameters>
      <WebPartPages:DataFormParameter Name="ListName" ParameterKey="ListName" PropertyName="ParameterValues" DefaultValue="Posts"/>
      <WebPartPages:DataFormParameter Name="WebURL" ParameterKey="WebURL" PropertyName="ParameterValues" DefaultValue="/sites/demos/blog/"/>
      <asp:Parameter Name="StartRowIndex" DefaultValue="0"/>
      <asp:Parameter Name="nextpagedata" DefaultValue="0"/>
      <asp:Parameter Name="MaximumRows" DefaultValue="10"/>
    </SelectParameters>
  </SharePoint:SPDataSource>
</DataSources>

Note that you can delete the DeleteParameters, UpdateParameters, and InsertParameters sections because we’re only displaying data in the DWP (SelectParameters are used for that).

You’ll also need to remove the listname attribute in the DVWP header, which will look something like this:

listname="{AEC1CA2C-EFA6-4218-A742-5939F94E0DDE}"

Save the page again and test it in the browser. Nothing should have changed and the DVWP should be working just fine.

Step 3: Export the DVWP

I usually just copy and paste the DVWP code from one SharePoint Designer window to the other, but here we’re going to use the Export / Import mechanisms instead.

You should already have the page open, so simply click in the upper right corner of the DVWP and choose Export.

image

In IE(, I get this prompt

image

and I just choose to save the Posts.webpart file somewhere I’ll be able to find it again.

Step 4: Import the DVWP into the Other Site

Now we’ll add the DVWP to the other site. Navigate to the page where you’d like to display the DVWP, and put the page into Edit Mode. Position the cursor where you’d like the DVWP and on the ribbon, choose Insert / Web Part.

I’m going to add mine right under the intro text on a Team Site. You’ll see that there’s an option to Upload a Web Part, which I’ve highlighted below. Click on that, browse the the Posts.webpart file you saved in Step 3, and then click upload.

image

You’ll have to reply to a prompt to save the page and then you’ll be right back at the page without your DVWP. What? Yeah, some bad UI here. But you should see a new Category called Imported Web Parts, and your Posts Web Part should be listed there. (I uploaded twice by accident in the screen grab below, but you get the idea.) You can insert the Posts DVWP wherever you’d like in the page.

image

As I mentioned, you can also copy and paste the DVWP code from one page to another, depending on your comfort level.

Next Steps

Now your users can read blog info wherever you’d like to display it, without going to the blog site itself. If you’d like to, you can format the posts anyway you’d like in the DVWP, of course. To keep things simple, I’m just displaying some basic info in a list-oriented view. You could mimic the display from the blog site or anything else that tickles your fancy.

Customizing the Display of a SharePoint 2010 Blog

I’ve changed pages countless times in SharePoint Designer, but this case, where I wanted to make a relatively small change to the home page of a Blog site, proved especially onerous.

In most cases, overriding the default XSL is as simply as editing what’s there and saving your changes.

It would seem that the team that works on blogs doesn’t chat with the rest of the product group, because blogs work differently. Blog pages use an XSL file called blog.xsl, which live in the _layouts folder on the Web Front Ends (WFEs).

On the home page of a blog site (default.aspx), there are several XLV Web Parts, but the main one is the one which displays the most recent posts. All I wanted to do in this case was display a different column instead of Created By (@Author) . Because in many organizations someone different that the author is the person who types the post, we had added a Written By column to the Posts list. The logic was simple: if the Written By column had a value, show it, otherwise show the Created By column as usual.

I wanted to keep the XLV Web Part in place in case we needed to work with it in the future, plus the markup it emits is a bit crufty and I didn’t want to have to replicate it all with a custom DVWP. (In retrospect, this *may* have been easier.)

It should have been pretty easy to make the change, but I went down some rat holes. I don’t want *you* to go down those rat holes, so here’s what ended up working.

Open the page in SharePoint Designer, position your cursor on the XLV Web Part which displays the posts and in the List View Tools section of the ribbon, choose Customize XSLT / Customize Entire View.

image

This pulls the XSL from blog.xsl into the page, in theory so that we can customize it. However, don’t go down that path; there be monsters. Instead, find the line:

<xsl:include href="/_layouts/xsl/blog.xsl"/>

and Ctrl-Click on the href link to the blog.xsl file. This will open the blog.xsl file in a different SharePoint Designer window for the root of the Site Collection. This is handy, because you now want to save a copy of blog.xsl in a Document Library in the root site of the Site Collection. I usually create a Document Library called XSL anyway to hold frequently-used XSL templates, like the ones I have in my SPXSLT Codeplex Project. I named my copy BlogWrittenBy.xsl.

Close the default.aspx page you opened in the blog site now WITHOUT saving it. Remember? Monsters. Open it again. See, no monsters.

Since we had added a new custom column called Written By, I needed to add it to the ViewFields section so that the XLV Web Part would retrieve values for it:

<ViewFields>
  <FieldRef Name="Title"/>
  <FieldRef Name="Body"/>
  <FieldRef Name="Author"/>
  <FieldRef Name="PostedByWithDate"/>
  <FieldRef Name="CategoryWithLink"/>
  <FieldRef Name="Permalink"/>
  <FieldRef Name="EmailPostLink"/>
  <FieldRef Name="NumCommentsWithLink"/>
  <FieldRef Name="PublishedDate"/>
  <FieldRef Name="PostCategory"/>
  <FieldRef Name="Written_x0020_By"/>
</ViewFields>

Then I saved the file. Yes, that customizes (or unghosts) the file. I’m OK with that.

Back to the BlogWrittenBy.xsl file I saved above. I found the section of the XSL where Created By (@Author) is emitted:

<xsl:when test="@Name='Author'"><span class="ms-postfootercolor"><xsl:value-of select="'by '"/></span><xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&amp;nbsp;</xsl:text><xsl:value-of select="$thisNode/@Author.span" disable-output-escaping="yes" /></xsl:when>

and replaced it with this:

<xsl:when test="@Name='Author'">
  <xsl:variable name="ShowPerson">
    <xsl:choose>
      <xsl:when test="string-length($thisNode/@Written_x0020_By.id) &gt; 0">
        <xsl:value-of select="$thisNode/@Written_x0020_By.span" disable-output-escaping="yes"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$thisNode/@Author.span" disable-output-escaping="yes"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <span class="ms-postfootercolor"><xsl:value-of select="$thisNode/../@resource.wss.ByPrefix"/></span><xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&amp;nbsp;</xsl:text><xsl:value-of select="$ShowPerson" disable-output-escaping="yes" />
</xsl:when>

This added the conditional logic we wanted.

Next, off to the browser, where I opened the page for editing. In the Tool Pane for the List View Web Part which shows the blog posts, I went to the Miscellaneous section and added a link to my XSL file in the Xsl Link field. In my case, since it was stored in the root of my Site Collection, the link was /XSL/BlogWrittenBy.xsl.

Then I saved the change and voila! Exactly what I wanted.

There are other ways to accomplish what I did here with a deployable feature and managed code, etc. In this case, it was a small farm with only a production environment and a single blog where we wanted to make the change. All you enterprise types just gasped, but this is the reality in many organizations.

Obviously it wasn’t all as simple as what I outline above. Here are some of the things I found:

  • If I edited the XSL in SharePoint Designer (after the Customize Entire View step), my changes worked great in SharePoint Designer,. However, when I went to the browser, I saw the page the same way it had looked before. I believe this is because the blog.xsl file was pulled in anyway, and no amount of jiggling things could get me past that.
  • If I tried to add the XSLLink in SharePoint Designer, which ought to work, it always stripped off the leading / in the link to the XSL file. This meant that the link was invalid and blog.xsl was used again.
  • The sequence I ran through above seems to be the only reliable way to make this work. It’s pretty quick (after 47 tries) and I did it twice as I was writing this. Of course, I had a copy of the original default.aspx file to work with. Never edit the default files without making a copy.

Here are two threads from the MSDN Forums that helped a bit. I didn’t have any luck with the ddwrt:ghost="hide" approach.

http://social.technet.microsoft.com/Forums/en-ZA/sharepoint2010customization/thread/669d7d94-45ad-4fa0-8fe9-069d44ba07fa

http://social.technet.microsoft.com/Forums/en-ZA/sharepoint2010customization/thread/9e5862b2-5271-47b8-8c9c-7742b7af55eb

Moving My Blog from WordPress.com to Hosted WordPress.org

I’ve been thinking about moving my blog from WordPress.com to some sort of hosted environment running WordPress.org’s version of WordPress for a while. With all of the jQuery and CSS stuff that I do and other possibilities for customization and monetization, it just makes a lot of sense for me to have more control over my own blog. I’ve loved using WordPress.com and their platform is generally fantastic; I’ve just outgrown it.

It ought to be pretty easy to do a move like this, at least in my limited view of the world. As it turned out, some parts are relatively easy, but other parts are abysmally unclear or just plain don’t work. I figured I’d document some of the thornier bits in case other might want to go down this road. I think I’m a pretty savvy guy, but I ran into some really annoying or undocumented (at least that I could find) things.

WordPress.com’s site has some instructions that make all of this sound pretty easy. I mean, it’s computer stuff. How hard can it be, right?

First off, exporting the content from my existing blog just plain didn’t work with IE8. I’ve known for a while now that the WordPress platform doesn’t work well with IE, but IE is my default browser because it’s what most of my client work with. I’m sort of a Microsoft guy.

I kept trying to run the export and was getting errors. I fiddled and fiddled, looking at the XML coming out, tweaking values, etc. For instance, as you can see below, the XML seemed to be malformed. so I tried deleting the offending tags, etc., but to no avail.

image

On a whim, I tried doing the export in Firefox, and it worked fine. On the first try. Once I did the export with Firefox, I had a good XML file so that I could do an import on the other end.

Lesson one: WordPress likes Firefox better than Internet Explorer.

I think that is probably a safe statement across the board. There are certainly odd behaviors in the online editor in WordPress with IE, and that’s probably one of the main reasons why so many of us Microsoft folks use Windows Live Writer instead.

I chose HostGator for my hosting company. They are on WordPress.com’s preferred list, my pal Bjorn (@furuknap) recommended them, and they are cheap. Well, everyone’s cheap these days, really. But HostGator has a 20% off thing going, and I love cheap that’s even cheaper.

When I was setting things up up at HostGator, the site asked for my domain name. I didn’t think much of that, but it turned out to be a problem. The issue was that once everything was up and running and I installed WordPress (That install was fairly painless – sort of the promised single button click, except for the other 6 fields you had to fill out next without any real explanation. I guess every process starts with the “one button click”.), anything I did in the HostGator environment was linking me over to the WordPress.com “production” version of my blog – the old one. More fiddling, and I finally started a chat session with someone at HostGator. They were really helpful, but these aren’t the technologies I focus on, so some of it was Greek to me. It’s not that I couldn’t figure it out, but was it worth it? The mumbo-jumbo was different than my usual mumbo-jumbo.

Lesson two: Just because you know one set of technologies well doesn’t mean that you know all of them.

This may be obvious, reader, but don’t tell me that you haven’t tried to build a server or something you really shouldn’t have done. Maybe it’s that “man thing”; asking for directions is actually OK.

What the helpful guy/gal (sometimes it’s impossible to know in a teeny chat window with foreign names – should I have asked?) ended up doing was setting up temporary URLs for my new HostGator blog site. They would need to switch it back later, but that was supposed to allow me to move forward.

Lesson three: Maybe you shouldn’t believe *everything* you hear from an expert.

Not that s/he was wrong, necessarily, but it didn’t fix everything.

There were a few more chat sessions at this point to find out passwords and such, but they weren’t significant. Let it suffice to say that the UI behind the marketing screens don’t follow through at HostGator any more than they do anywhere else.

Lesson four: When marketing says something will be easy, we all know we shouldn’t believe that.

BUT WE STILL DO. What’s wrong with us?

The next step was to do the actual import of the XML file. The import kept just stopping with no errors, warnings, or messages of any kind. But when I looked at the setup, I would see all my posts – through December 2007, or March 2008, or…  Back to Bing, where the posts I found said basically, it will time out and you just need to keep running the import over and over until everything is there. What? Could that be true? Every time I ran the import after the first instance, all sort of errors flew by on the screen. The posts said that was OK, so I kept going.

Lesson five: Sometimes something which just looks totally wrong is supposed to be right?

I’m not so sure about this one.

After eight or ten imports (or more – I didn’t count well enough), everything looked like it *might* be there. The errors from the last few imports looked worse and worse, but they were “OK”, right?

At this point, I had my blog up and running with the temp URLs in the new environment at HostGator. I don’t like to trust technology too much, so I started to compare what I currently had on my blog with what I now had ion my new blog. You know, comparing counts of things, how the theme was applied, seeing what was missing, etc.

Lesson six: *Always* check your work.

There were still some problems that gave me pause. I’ve got over 600 posts on my blog with over 2500 comments and 500+ tags (I know, too many tags, but there you go). There’s far too much there to check everything; all I can do is spot check, really.

Here were my big concerns after more fiddling:

The Post counts on my Tags were all set to zero after import. In the grand scheme of things, maybe this isn’t so important, but I sort of like the Tag Cloud widget. Since all the post counts were zero, the tag cloud was uniquely uninteresting. Singularities are only interesting to physicists. I’m guessing that there’s some script I could run to fix this up (though it should be right from the import, IMO).

On my current blog, I use sourcecode tags supported by the SyntaxHighlighter Evolved plugin to embed source code. I’d like to continue using this plugin, as I find it makes the code snippets the most useful compared to any other approach I’ve seen. My blog is mainly about technology, and it contains a lot of code snippets; they have to be usable or what’s the point? The issue is that the code snippets in my existing posts seem to have gone across encoded. So rather than seeing this:

clip_image002

I was seeing this:

clip_image004

Another thing where some script probably would fix things up, but should I have needed to?

The comment count on my new blog was different than on my existing blog. As I mentioned, when I did the import, I had to run it probably eight or more times to get everything imported. On every run after the first, I got all sorts of errors, but it *seemed* like most everything moved over. The posts I read said this was “normal”, but since the comment count was different, I wondered what else might be out of whack.

Old blog:

clip_image006

New blog:

clip_image008

That didn’t seem right to me. Since there were all of those odd errors and the numbers didn’t match, I had no idea what the mismatch was caused by. And the new blog had *more* comments than the old one. How could that make sense?

All this trouble seems so unnecessary! It would seem that when there is an offer of an export/import capability, it should just work. Because I was using WordPress.com, I *couldn’t* do any wacky customizations; all instances there should be vanilla to a large degree, if not totally.

So after about four hours (or more; I should have kept track), I’m tossing in the towel. I don’t want to spend so much time on a one-time activity. I’m hiring the WordPress Happiness Engineers to do a Guided Transfer for me.

Final lesson: It doesn’t always make sense to learn how to do something if you are pretty sure you are only going to do it once.

I’ll probably never move my blog from one platform to another again, or at least I won’t do it again for a long time. It’s should be truly worth the $119 I’m going to pay Automattic | WordPress.com to do the work for me. (I sincerely hope that’ll turn out to be true; you’ll hear about it in this space if it isn’t.)

p.s. Thanks to Josh McCarty and Bjorn Furuknap for their support and suggestions along the way in this process. I hope the two of you don’t think less of me for hiring the Happiness Engineers.