Sharepoint 2010 – Meeting Workspace Templates with Content

August 8, 2012 § Leave a comment

Very frustrating thing about meeting workspace templates is that you can’t include content in the template. Of course, the first time you make a meeting workspace template, you’re going to want to include content. For instance, you make a meeting workspace template for a particular group, and that group always has the same members in it. It would be nice to have the template pre-populate the attendee list so that you don’t have to enter it once the meeting workspace has been created.

So, since this is a pain in the ass, and we need it to work, let’s hack it.

I found it easier to start with a template that is not derived from a meeting workspace template. So create a new site, modify it to your satisfaction (including whatever content you want), then save the site as a template. Download the .wsp to your local system and extract it using a tool like iZarc.

Go ahead and create another site, using the Blank Meeting Workspace template. Don’t modify it – just save the site as a template. Downlod the .wsp to your local system and extract it using a tool like iZarc.

Changes:

[WHATEVER]WebTemplate\Elements.xml
Change BaseTemplateID=”2″
Change BaseTemplateName=”MPS”

It helps to have the second wsp for comparison here.
[WHATEVER]ListInstances\Elements.xml
Add the “Meeting Series” and “Workspace Pages” list instances.

[WHATEVER]ListInstances\Feature.xml
Add the “Meeting Series” and “pages” ElementFile locations.

[WHATEVER]ListInstances\Files
Add the pages folder (and its contents)

[WHATEVER]ListInstances\Files\Lists
Add the “Meeting Series” folder (and its contents)

Use a tool like iZarc to package the whole folder back into a .cab file. Rename the .cab file to .wsp. Upload it to the solution gallery.

Now you can create a meeting workspace with this template, and the content will be included.

TADA!

Anonymity / Authenticity – why not both?

March 14, 2011 § 1 Comment

I was reading this ReadWriteWeb article about Moot’s point of view on anonymity online, which is obviously to come down on the side of anonymity. It compares this to the opposing point of view, which is that signing your name to something increases authenticity.

Is it not blindingly obvious that both are true? For certain things, maintaining your anonymity is beneficial and allows you to express your opinions without fear of reprisal. For other things, signing your name to your opinion forces you to put a certain amount of thought into your sentiment and be prepared to defend it.

So, while using my Facebook account to comment on TechCrunch (just like posting on my technical blog under my real name) is fine, you’re not going to see me regularly posting on 4Chan or even Reddit under my real name, because sometimes I want to sign my name, and sometimes I don’t.

Cars, Computers, and Interface Design

February 1, 2011 § Leave a comment

A few days ago, I was reading about how Apple could dominate car tech (if it wanted).

Two weeks of car shopping has driven home two big points for me: User interface matters. Car companies aren’t all that good at it.

Really? Because last I checked, car companies are pretty good at user interface. It takes me less than 5 minutes (in any car) to figure out to make it start, go forward, reverse, stop, turn left, right, turn on and off the radio, change the station, change the volume, turn on the air, heat, defrost, adjust the seat, mirrors, steering wheel, put on a seat belt, and start driving. And yes, there are a lot of buttons. So?

On the dream in code forums, one person asks a similar question:

A new car can have over hundred controls. For example, 10 controls for radio, 5-10 for heating and ventilation, 10 for windows, 10 for wipers, washers and so on. Most people can master these very quickly. Why is it that the car with so many controls is easier to use than a video recorder that has few controls. What makes the car’s interface so good and that of the video recorder so bad.

I love this answer:

…a car’s buttons are shallow in depth hence why there are so many, and a camcorder has fewer buttons that do more things (depth) in conjunction with other buttons.

The last thing I would want to do, while driving, is deal with some sort of menu tree when all I want to do it turn on my headlights.

Apple certainly does create some exceptional user interfaces – the iPhone is obviously a shining example of that. And yet 8 out of 50 states prohibit handheld use of a phone while driving, and 30 out of 50 states prohibit text messaging while driving. (http://www.ghsa.org/html/stateinfo/laws/cellphone_laws.html) This is because devices which require concentration to use necessarily divert your attention from the more pertinent task, which is driving.

Humans think and remember in physical space; we have a well developed sense of spatial memory. This is what allows us to type while not looking at the keyboard, pick something up off of the desk without looking, remember where we left our keys (well some of us), and so on. This is also what allows us to reach down to the volume knob and change the volume on the radio without significant distraction from the task at hand (driving). We know where the volume knob is, and we know which way to turn it. It is a physical object in physical space and our brains have evolved to be able to interact with such objects without using a significant amount of focus.

When you change that user interface so that there is simply one button to enter a virtual menu of options, sometimes many levels deep, we’ve suddenly made the task one that requires a significant level of concentration. We can’t rely on our built-in spatial memory any more, because multiple functions are mapped to the same physical space. At this point, we have to build a representation in our heads to keep track of where in the virtual space we are. Which app am I in, which submenu am I on, where are the buttons on the screen, and so on. We’ve gone from something as familiar and simple as a knob to something that requires (comparatively) a great deal of thought.

Of course, car manufacturers have tried to reinvent the automotive user interface before. In fact, several have them have even developed some very Applesque interfaces. BMW’s iDrive is probably one of the best known of these, and although it went through a number of revisions, and some users were quite fond of it, the overwhelming response was negative.

The design rationale of iDrive is to replace a confusing array of controls for the above systems with an all-in-one unit…iDrive has caused significant controversy among users, the automotive media, and critics. Many reviewers of BMWs in (automobile) magazines disapprove of the system. Criticisms of iDrive include its steep learning curve and its tendency to cause the driver to look away from the road too much.
http://en.wikipedia.org/wiki/IDrive

This article on cnet discusses iDrive (as well as Audi’s MMI and Mercedes-Benz’s COMAND systems) in some detail. In the article, Wayne Cunningham rates each of the systems according to Jakob Nielsen’s Usability Heuristics. I find this interesting, as the second heuristic is “Match between system and the real world”, which is something that buttons and knobs are obviously quite good at, and nested menus of options are not.

Of course, if this type of design would function so poorly in an automobile, why do we love our phones, laptops, tablets, televisions, and video games so much in other facets of our lives? The obvious answer is that we aren’t driving while using them, and we want to be engaged with our technology. This should quite obviously lead not to the question of how to redesign the interface of the automobile, but how to redesign the process of driving. Since we are not able to use these devices while driving, we can choose to either design the device to suit the task (as discussed above), or modify the task to suit the device.

It isn’t Apple that is likely to succeed in this venture. The Distronic Plus cruise control system that Mercedes Benz is using is a step in the right direction. Google’s work on cars that drive themselves are even more so. Optimistically we have 10 years before cars that can drive themselves are available. At that point the game changes. The design of our cars won’t be constrained by the requirement that the driver maintain focus on the road.

Maybe then Apple will rock the world with its groundbreaking automotive interfaces, but until then, leave my knobs and buttons alone.

DBNull is stupid

January 28, 2011 § 1 Comment

DBNull is stupid. If you’re using it, stop.

Take this basic code:

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Dim obj1 As Object

        Dim obj2 As Object

 

        obj1 = "a"

        obj2 = "b"

 

        Try

            AssignValue(obj1, obj2)

            MessageBox.Show(obj2.ToString())

        Catch ex As Exception

            MessageBox.Show(ex.ToString())

        End Try

    End Sub

 

    Public Sub AssignValue(ByVal obj1 As Object, ByRef obj2 As Object)

        If (obj1 <> obj2) Then

            obj2 = obj1

        End If

    End Sub

End Class

 

This is a somewhat contrived example, but basically, we want to give obj2 the value that obj1 has. We do a simple check to make sure that they aren’t the same before bothering to do so. This is more important in code where you’re setting a property (rather than just a variable) which may execute some other code, like setting a dirty flag or even writing to persistent storage.

Anyway, the code executes, and obj2 is assigned the value of obj1 (“a”). So what’s the problem? Let’s change the value of obj1 to DBNull.Value.

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Dim obj1 As Object

        Dim obj2 As Object

 

        obj1 = DBNull.Value

        obj2 = "b"

 

        Try

            AssignValue(obj1, obj2)

            MessageBox.Show(obj2.ToString())

        Catch ex As Exception

            MessageBox.Show(ex.ToString())

        End Try

    End Sub

 

    Public Sub AssignValue(ByVal obj1 As Object, ByRef obj2 As Object)

        If (obj1 <> obj2) Then

            obj2 = obj1

        End If

    End Sub

End Class

 

Should be no problem, right? The AssignValue sub will be called and obj2 will be assigned a value of DBNull.Value. Except that it doesn’t. Actually, what you get is an exception that states:

{“Operator ” is not defined for type ‘DBNull’ and string “b”.”}

Well, crap. Ok, we’ll check for DBNull.Value in our AssignValue sub.

    Public Sub AssignValue(ByVal obj1 As Object, ByRef obj2 As Object)

        If (IsDBNull(obj1) AndAlso Not IsDBNull(obj2)) OrElse

            (Not IsDBNull(obj1) AndAlso IsDBNull(obj2)) OrElse

            obj1 <> obj2 Then

 

            obj2 = obj1

        End If

    End Sub

Run our code again and everything works great. Wait, what if obj1 and obj2 are both set to DBNull.Value?

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Dim obj1 As Object

        Dim obj2 As Object

 

        obj1 = DBNull.Value

        obj2 = DBNull.Value

 

        Try

            AssignValue(obj1, obj2)

            MessageBox.Show(obj2.ToString())

        Catch ex As Exception

            MessageBox.Show(ex.ToString())

        End Try

    End Sub

Another exception, of course!

{“Operator ” is not defined for type ‘DBNull’ and type ‘DBNull’.”}

Ack! Seriously? Ok, let’s change our AssignValue sub again. We’ll check to see if obj1 is DBNull while obj2 is not, or obj2 is DBNull while obj1 is not, or both obj1 and obj2 are not DBNull and not equal to each other.

    Public Sub AssignValue(ByVal obj1 As Object, ByRef obj2 As Object)

        If (IsDBNull(obj1) AndAlso Not IsDBNull(obj2)) OrElse

            (Not IsDBNull(obj1) AndAlso IsDBNull(obj2)) OrElse

            (Not IsDBNull(obj1) AndAlso Not IsDBNull(obj2) AndAlso obj1 <> obj2) Then

 

            obj2 = obj1

        End If

    End Sub

Wow, we’ve finally managed to implement what should be a simple comparison and we only had to do 5 comparisons to do it. Maybe it’s just me, but this seems excessive for what we’re trying to do. I understand that it’s necessary to represent null database values in our objects, but generics (and therefore Nullables) were introduced in .NET 2.0 – stop using DBNull.

Twitter, jQuery, and Performance

January 21, 2011 § Leave a comment

This writeup by John Resig concerning Twitter’s recent performance problems is an interesting read. It points out that some changes in jQuery 1.43 were responsible for part of the performance degradation, but the larger problem had more to do with how jQuery was being used. John points out two things that we would all do well to pay attention to.

  1. It’s a very, very, bad idea to attach handlers to the window scroll event.
  2. Always cache the selector queries that you’re re-using.

If you’d like to explore this topic further, this jQuery performance optimization video by Addy Osmani is great. You’ll need to block off half an hour or so to watch it, but it offers some excellent tips that are really useful if you’re in and out of jQuery on a regular basis.

MVC, mobile views, and RAZR

January 21, 2011 § 1 Comment

I thought that this whitepaper on making your MVC web application mobile friendly was a very good read. The only thing that struck me was the section on remembering the user’s preference regarding using the mobile presentation versus the standard presentation:

It’s often convenient to redirect mobile visitors to the mobile pages only on the first request in their browsing session (and not on every request in their session), because:

  1. You can then easily allow mobile visitors to access your desktop pages if they wish – just put a link on your master page that goes to “Desktop version”. The visitor won’t be redirected back to a mobile page, because it’s no longer the first request in their session.
  2. It avoids the risk of interfering with requests for any dynamic resources shared between desktop and mobile parts of your site (e.g., if you have a common Web Form that both desktop and mobile parts of your site display in an IFRAME, or certain Ajax handlers)

To do this, you can place your redirection logic in a Session_Start method. For example, add the following method to your Global.asax.cs file…

I frequently browse the web on my Android phone – in fact, I probably browse the web more on my phone than I do on my computer. I don’t want my mobile/standard preference stored in the session. I want it stored in a persistent cookie so that I don’t have to reset my preference every time I visit your site. This isn’t even difficult – here is an excellent reference to using cookies with .NET.

The section regarding the different methodologies for presenting mobile specific pages talks about using different Razor views for mobile/standard:

Since the Model-View-Controller pattern decouples application logic (in controllers) from presentation logic (in views), you can choose from any of the following approaches to handling mobile support in server-side code:

  1. Use the same controllers and views for both desktop and mobile browsers, but render the views with different Razor layouts depending on the device type. This option works best if you’re displaying identical data on all devices, but simply want to supply different CSS stylesheets or change a few top-level HTML elements for mobiles.
  2. Use the same controllers for both desktop and mobile browsers, but render different views depending on the device type. This option works best if you’re displaying roughly the same data and providing the same workflows for end users, but want to render very different HTML markup to suit the device being used.
  3. Create separate areas for desktop and mobile browsers, implementing independent controllers and views for each.This option works best if you’re displaying very different screens, containing different information and leading the user through different workflows optimized for their device type. It may mean some repetition of code, but you can minimize that by factoring out common logic into an underlying layer or service.

If you want to take the first option and vary only the Razor layout per device type, it’s very easy…

The Razor views look very slick, and unfortunately, I haven’t had much time to play with them yet. Telerik recently posted a .NET Web Forms Views -> Razor converter on GitHub that looks like it would give you a good kickstart if you’re trying to switch over a project that you’ve already started.

What’s your reading level?

December 20, 2010 § Leave a comment

I happened across this article on technologyreview.com about a new search option on google for Reading Level, which is pretty cool. You can go to advanced search and choose to filter your search results based on basic, intermediate, or advanced reading levels. You can also just get a reading level “rating” for the search results. While I am going to explore this a little further, being the narcissist that I am, I thought I’d search myself and see what google thinks of me.


click for results

I’m pretty happy with that 75%, but I think I’ll use it much like this programmer competency rating as a yardstick for improvement.

Do you want to find out what your reading level is? Click here to search.

Follow

Get every new post delivered to your Inbox.