PinIt-button

A cli­ent of mine wan­ted to add PinIt sup­port for parts of their web site, main­ly their user com­mu­ni­ty image gal­le­ri­es.

I made a quick solu­tion for them, copi­ed here in case some­o­ne else needs somet­hing simi­la­re, or just wants to com­plain about my pro­gram­ming tech­ni­ques 🙂 Or pre­fe­rably make sug­ges­tions for impro­ve­ments…

To use it, regis­ter the name­spa­ce in eit­her your web.config, in /configuration/system.web/pages/controls:

<add tagPrefix="Controls" namespace="Paddy.Web.UI.HtmlControls" assembly="name-of-you-dll-file" />

Or, you can regis­ter it at the top of your .aspx file, as follows:

<%@Register TagPrefix="Controls" Namespace="Paddy.Web.UI.HtmlControls" %>

Then use it on the page like this:

<Controls:PinIt ID="ctlPinIt" runat="server" CountLayout="Horizontal" Url="Complete url" Media="Complete url to the image" Description="Optional description" />

Ple­a­se note that the con­tents of the Url and Media pro­per­ti­es needs to be ful­ly qua­li­fi­ed!

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;

namespace Paddy.Web.UI.HtmlControls
{
	public class PinIt : HtmlControl
	{
		private const string PinItscriptinclude = "PinItScriptInclude";

		#region Properties

		public CountLayouts CountLayout { get; set; }
		public string Description { get; set; }
		public string Url { get; set; }
		public string Media { get; set; }

		#endregion

		public PinIt()
			: base("a")
		{
			CountLayout = CountLayouts.Horizontal;
		}

		protected override void Render(HtmlTextWriter writer)
		{
			if (string.IsNullOrWhiteSpace(Url) || string.IsNullOrWhiteSpace(Media))
			{
				return;
			}

			// Register the Pinterest script
			var type = GetType();
			if (!Page.ClientScript.IsStartupScriptRegistered(type, PinItscriptinclude))
			{
				Page.ClientScript.RegisterStartupScript(type, PinItscriptinclude,
					@"<script type=""text/javascript"" src=""//assets.pinterest.com/js/pinit.js""></script>", false);
			}

			// Build the tag.
			writer.WriteBeginTag(base.TagName);
			RenderAttributes(writer);
			writer.Write(HtmlTextWriter.TagRightChar);

			// Render the image
			writer.WriteBeginTag("img");
			writer.WriteAttribute("src", "//assets.pinterest.com/images/PinExt.png");
			writer.WriteAttribute("alt", "Pin it");
			writer.WriteAttribute("title", "Pin it");
			writer.WriteAttribute("border", "0");
			writer.Write(HtmlTextWriter.SelfClosingTagEnd);

			writer.WriteEndTag(base.TagName);
		}

		protected override void RenderAttributes(HtmlTextWriter writer)
		{
			var parameters = new Dictionary<string, string> { { "url", Url }, { "media", Media } };
			if (!string.IsNullOrWhiteSpace(Description))
			{
				parameters.Add("description", Description);
			}

			Attributes.Add("href", "http://pinterest.com/pin/create/button/" + ToQueryString(parameters));
			Attributes.Add("class", "pin-it-button");
			Attributes.Add("count-layout", CountLayout.ToString().ToLower());

			base.RenderAttributes(writer);
		}

		private static string ToQueryString(IEnumerable<KeyValuePair<string, string>> dictionary)
		{
			var result = dictionary.Aggregate(
				new StringBuilder("?"),
				(builder, pair) => builder.AppendFormat("{0}={1}&", pair.Key, HttpUtility.UrlEncode(pair.Value)),
				builder => builder.ToString());

			return result.Substring(0, result.Length - 1);
		}

		public enum CountLayouts
		{
			Horizontal,
			None,
			Vertical
		}
	}
}

Receptdatabas

I många år har jag haft pla­ner på att göra en recept­da­ta­bas. Inte för­rän nu har jag kom­mit igång på all­var.

Så jag har skri­vit ner och sor­te­rat alla tan­kar och idéer jag haft om det, vad jag vill att man skall kun­na göra där, jag har ett över­gri­pan­de hum om hur jag vill att det skall se ut (även om det inte är på detalj­ni­vå än), och jag har t.o.m. skaf­fat hos­ting för det. Men som med så myc­ket annat är det lite svårt att kom­ma igång i bör­jan, all infra­struk­tur skall upp så att man kan kom­ma igång med att imple­men­te­ra funk­tio­ner.

Det som jag just nu tyc­ker är job­bigt är att få rätt på data­bas­lag­ret. Jag har valt att låta NHi­ber­na­te, ett .NET based object per­sistence lib­ra­ry for rela­tio­nal data­ba­ses. Jag fick tip­set om det­ta från Jakob Røjel på Emen­tor, som trod­de att det kanske var lite lät­ta­re att ha att göra med än iBA­TIS, och jag tyck­te det kun­de vara en bra idé att slip­pa skri­va oänd­ligt många SELECT-/UPDATE-/INSERT-/DELETE-satser. Än så länge har jag inte ång­rat mig, NHi­ber­na­te under­lät­tar enormt, men det tar lite tid innan man får rätt på hur man skri­ver rela­tio­ner i map-filerna (som är XML-baserade). One-to-many är gans­ka enkelt, men many-to-many har jag inte rik­tigt fått rät på än. Men det kom­mer, jag är envis 🙂
Jag har ock­så köpt en licens för ett paket med vali­da­to­rer för .NET. De som finns i ASP.NET 1.0÷1.1 sak­nar mass­vis med funk­tio­na­li­tet, och fun­ge­rar inte med alla kon­trol­ler hel­ler. Där­för är jag glad över att MAD! widgets vali­da­tors finns. Vi använ­der dem i pro­jek­tet på Emen­tor, och de är extremt kraft­ful­la och flex­ib­la. En trev­lig finess är att man kan grup­pe­ra vali­da­to­rer, så att om du har t.ex. ett for­mu­lär som består av oli­ka delar, och en knapp som bara skall trig­ga vali­de­ring av en viss del av for­mu­lä­ret, så kan du grup­pe­ra ihop en Button/LinkButton/ImageButton med de fäl­ten, och låta de and­ra fäl­ten till­hö­ra en annan grupp som då inte vali­de­ras när du skic­kar iväg for­mu­lä­ret. Det stöd­jer ock­så avan­ce­ra­de and-/or-relationer mel­lan fält, t.ex. ”om den här kryssru­tan är ifylld skall man väl­ja ett vär­de i den här drop down-menyn, och som skall vara skiljt från det här vär­det” och lik­nan­de saker.

Det enda sto­ra som är kvar (för­u­tom att imple­men­te­ra all­ting för­stås), är att arbe­ta ut hur använ­dar­gräns­snit­tet skall se ut och vil­ka fär­ger som skall använ­das. Eftersom jag inte är gra­fi­ker så kan det ta tid, men det går ju all­tid att läg­ga på/modifiera i efter­hand, så det skall nog gå bra.

Recept­da­ta­ba­sen finns/kommer att fin­nas på www.ReceptDB.net.

Konvertera C++ till C#

Efter att en av våra pro­jekt­le­da­re frå­gat mig och en kol­le­ga om att tidsupp­skat­ta att even­tu­ell kon­ver­te­ra en appli­ka­tion skri­ven i C++ till C#, så leta­de jag runt lite på nätet för att se vad som fanns skri­vet om det.

Hit­ta­de en arti­kel skri­ven av Jes­se Liber­ty med titeln ”C++ -> C#: What You Need to Know to Move from C++ to C#”, som tar upp just det­ta.

Nu skall jag bara hit­ta tid till att läsa den här arti­keln ock­så… Har hit­tat en del bra böc­ker och artik­lar på sisto­ne som jag skri­vit ut i syf­te att läsa dem, men tiden ver­kar ald­rig infin­na sig… Nåja, om/när jag läst den­na arti­keln, så kanske jag skri­ver en recen­sion av den.