EditOverview
What is a
gravatar?
A gravatar, or globally recognized avatar, is quite simply an avatar image that follows you from weblog to weblog appearing beside your name when you comment on gravatar enabled sites. Avatars help identify your posts on web forums, so why not on weblogs?
This plugin's purpose is to allow a gravatar to be easily displayed within a Screwturn wiki.
There are 2 downloadable versions of the plugin:
- GravatarSimple.zip - supports the {gravatar} tag only
- GravatarFull.zip - supports the {gravatar} tag as well as showing gravatars as popups around a user's name when that user's name appears because of the ~~~~ tag or because of a standard link to an email address.
Editgravatar tag
The {gravatar:
xxx} tag returns a URL to the gravatar image. Use it within an img tag or image markup.
Gravatars are based on the hash of an email address. The
xxx value in the tag can be replaced with the following values:
- me - uses the current user's email address
- creator - uses the page creator's email address
- a wiki user name - uses that person's email address
- an email address
Example:
{gravatar:mike} = http://www.gravatar.com/avatar/29f47ef1cf66cbf23b30415ab28bb24d?s=80&r=any
Used in a simple image tag:
Editpopup on name links
This method shows gravatars as popups around a user's name when that user's name appears because of the ~~~~ tag or because of a standard link to an email address.
To get this to work, you will need to alter your theme's Screen_Styles.css file. Add the following elements:
a.grav { position:relative; }
a.grav img { height: 0; width: 0; border-width: 0;}
a.grav:hover span img { /*the span will display just on :hover state*/
position:absolute;
top:1.5em; left:0px;
height: 80px;
width: 80px;
z-index: 99;
text-align: center}
Also, add the following to Print.css:
a.grav img { height: 0; width: 0; border-width: 0;}
If you don't add these elements, the image will appear next to the name link instead of appearing as a popup.
I have tested this on a sandbox wiki, but am not using here.
EditSource code
Option Explicit On
Option Strict On
Option Compare Text
#Const SimpleVersion = False
Imports System
Imports Microsoft.VisualBasic
Imports ScrewTurn.Wiki.PluginFramework
Imports System.Web.Security
Imports System.Text.RegularExpressions
Public Class GravatarFmt
Implements IFormatterProvider
'See http://en.gravatar.com/site/implement for more info
Const HighestRating As String = "any"
Const AvatarSize As Integer = 80 'if you use a smaller size than 80, adjust the css as well
'The following CSS (or something like it) needs to be added
'to your theme. Without it, the tooltip effect won't work and
'gravatars will appear inter-mixed with your email links:
'
'a.grav { position:relative; }
'
'a.grav img { height: 0; width: 0; border-width: 0;}
'
'a.grav:hover span img { /*the span will display just on :hover state*/
' position:absolute;
' top:1.5em; left:0px;
' height: 80px;
' width: 80px;
' z-index: 99;
' text-align: center}
'Also, add this to your Print.css file in the Themes directory:
'
'a.grav img { height: 0; width: 0; border-width: 0;}
Private _host As IHost = Nothing
'regex to detect if a pattern looks like an email address
Private emailReg As New Regex("^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$", RegexOptions.Compiled)
'regex to find the {gravatar} tag
Private rTag As New Regex("{gravatar(}|(:[^}]*)})", RegexOptions.Compiled Or RegexOptions.IgnoreCase)
'This is the phrase 3 result of the ~~~~ tag:
' <span class="signature"><a href="Message.aspx?Username=userid">userid</a>, 03/31/2008 10:55 AM</span>
' <a href="Message.aspx?Username=userid">userid</a>
Private rSigs As New Regex("<a href=""Message.aspx\?Username=(.*?)"">(.*?)</a>", RegexOptions.Compiled Or RegexOptions.IgnoreCase)
Private rMailTo As New Regex("<a class=""emaillink"" href=""mailto:(.*?)"" title=""(.*?)"">(.*?)</a>", RegexOptions.Compiled Or RegexOptions.IgnoreCase)
Private Function TranslateIDToEmail(ByVal userID As String) As String
For Each usr As UserInfo In _host.AllUsers
If String.Compare(userID, usr.Username, True) = 0 Then
Return usr.Email
End If
Next
Return userID
End Function
Private Function DecodeHtmlAscii(ByVal s As String) As String
If s Is Nothing Then Return ""
Dim p1 As Integer = s.IndexOf("&#", 0)
Do While p1 >= 0
Dim p2 As Integer = s.IndexOf(";", p1 + 2)
If p2 >= 0 Then
Dim orig As String = s.Substring(p1, p2 - p1 + 1)
Dim cd As String = orig.Substring(2, orig.Length - 3)
Dim n As Byte = 0
If Not Byte.TryParse(cd, n) Then n = 0
If n >= 32 AndAlso n <= 127 Then
s = s.Replace(orig, Chr(n))
End If
End If
p1 = s.IndexOf("&#", p1 + 3)
Loop
Return s
End Function
Public Function Format(ByVal raw As String, ByVal context As ScrewTurn.Wiki.PluginFramework.ContextInformation, ByVal phase As ScrewTurn.Wiki.PluginFramework.FormattingPhase) As String Implements ScrewTurn.Wiki.PluginFramework.IFormatterProvider.Format
Try
Dim m As Match
#If Not SimpleVersion Then
'This loop converts the block created by the ~~~~ tag
'so it display a tooltip style gravatar; removing the
'entire loop will disable this feature, but not affect
'the rest of the logic:
'<a href="Message.aspx?Username=uid">uid</a>
m = rSigs.Match(raw)
Do While m.Success
Dim newStr As String = m.ToString
Dim ID As String = m.Groups(1).Value
Dim GravUrl As String = "<img src=""" & GetGravatarUrl(ID, context) & """ />"
newStr = newStr.Replace("<a href=", "<a class=""grav"" href=")
'newStr = newStr.Replace(String.Format(">{0}</a>", m.Groups(2).Value), String.Format(">{0}<span>{1}</span></a>", m.Groups(2).Value, GravUrl))
newStr = newStr.Replace(String.Format(">{0}</a>", m.Groups(2).Value), String.Format(">{0}{1}</a>", m.Groups(2).Value, GravUrl))
raw = raw.Replace(m.ToString, newStr)
m = rSigs.Match(raw)
Loop
'This loop converts the html created by the [email address] tag
'so it displays a tooltip style gravatar; removing the
'entire loop will disable this feature, but not affect
'the rest of the logic:
'<a class="emaillink" href="mailto:address@domain.com" title="address@domain.com">address@domain.com</a>
m = rMailTo.Match(raw)
Do While m.Success
Dim newStr As String = m.ToString
Dim ID As String = m.Groups(1).Value
Dim GravUrl As String = "<img src=""" & GetGravatarUrl(ID, context) & """ />"
newStr = newStr.Replace("class=""emaillink""", "class=""grav""")
'newStr = newStr.Replace(String.Format(">{0}</a>", m.Groups(3).Value), String.Format(">{0}<span>{1}</span></a>", m.Groups(3).Value, GravUrl))
newStr = newStr.Replace(String.Format(">{0}</a>", m.Groups(3).Value), String.Format(">{0}{1}</a>", m.Groups(3).Value, GravUrl))
raw = raw.Replace(m.ToString, newStr)
m = rMailTo.Match(raw)
Loop
#End If
'This loop converts the {gravatar} tags into a gravatar URL.
'Again, if this is removed, the other 2 items above are unaffected.
'This doesn't require any special css since it just returns
'a URL; how that URL is used is up to the wiki author.
m = rTag.Match(raw)
Do While m.Success = True
Dim OrigText As String = m.Value
Dim Parms As String = m.Groups(2).Value.Substring(1)
raw = raw.Replace(OrigText, _host.Format(GetGravatarUrl(Parms, context)))
m = rTag.Match(raw, m.Index + 1)
Loop
Return raw
Catch ex As Exception
_host.LogEntry(ex.Message, LogEntryType.Error, Me)
_host.LogEntry(ex.StackTrace, LogEntryType.Error, Me)
Return raw
End Try
End Function
'Syntax: {Gravatar:uid}
'or {Gravatar:name@domain.com}
'or {Gravatar} - uses the wiki's contact email
'or {Gravatar:me} - "me" translates to context.Username
'or {Gravatar:creator} - "creator" translates to the creator of the current page
'After all that, If no ID can be found (no current user)
'or if the ID is "system", use the email address entered
'as the Wiki's ContactEmail
Private Function GetGravatarUrl(ByVal ParmString As String, ByVal context As ScrewTurn.Wiki.PluginFramework.ContextInformation) As String
If ParmString = "me" Then ParmString = context.Username
If ParmString = "creator" Then
Dim pc As PageContent = Nothing
Try
pc = _host.GetBackupContent(context.Page, 0)
Catch ex As Exception
Return ex.GetType.ToString
End Try
ParmString = pc.User.ToLower
End If
If ParmString Is Nothing OrElse ParmString.Length = 0 OrElse ParmString = "system" Then
ParmString = _host.GetSettingValue(SettingName.ContactEmail)
End If
'some people like to obscure email using "&#nnn;" notation.
'supporting that by converting them back to their correct values.
ParmString = DecodeHtmlAscii(ParmString)
'doesn't look like an email address?
'try looking it up in the users.cs file
If emailReg.IsMatch(ParmString) = False Then
ParmString = TranslateIDToEmail(ParmString)
End If
'still doesn't look like an email address?
'add the domain of the current contact address to it.
If emailReg.IsMatch(ParmString) = False Then
Dim contactEmail As String = _host.GetSettingValue(SettingName.ContactEmail)
Dim p As Integer = contactEmail.IndexOf("@")
If p >= 0 Then
ParmString &= contactEmail.Substring(p)
End If
End If
Dim hsh As String = FormsAuthentication.HashPasswordForStoringInConfigFile(ParmString, "MD5").Trim.ToLowerInvariant
Return String.Format("http://www.gravatar.com/avatar/{0}?s={2}&r={1}", hsh, HighestRating, AvatarSize)
End Function
Public ReadOnly Property PerformPhase1() As Boolean Implements ScrewTurn.Wiki.PluginFramework.IFormatterProvider.PerformPhase1
Get
Return False
End Get
End Property
Public ReadOnly Property PerformPhase2() As Boolean Implements ScrewTurn.Wiki.PluginFramework.IFormatterProvider.PerformPhase2
Get
Return False
End Get
End Property
Public ReadOnly Property PerformPhase3() As Boolean Implements ScrewTurn.Wiki.PluginFramework.IFormatterProvider.PerformPhase3
Get
Return True
End Get
End Property
Public ReadOnly Property Information() As ScrewTurn.Wiki.PluginFramework.ComponentInformation Implements ScrewTurn.Wiki.PluginFramework.IProvider.Information
Get
Return New ComponentInformation(Me.GetType.Name, "Mike Mestemaker", "")
End Get
End Property
Public Sub Init(ByVal host As ScrewTurn.Wiki.PluginFramework.IHost, ByVal config As String) Implements ScrewTurn.Wiki.PluginFramework.IProvider.Init
_host = host
End Sub
Public Sub Shutdown() Implements ScrewTurn.Wiki.PluginFramework.IProvider.Shutdown
End Sub
End Class
The code for both versions is the same, but there's a compiler constant that hides the popup stuff in the GravatarSimple compile.
The HighestRating constant can be changed to limit gravatars that might not be appropriate for children.
Const HighestRating As String = "any"
Simply change it to any of the values listed on the gravatar site:
http://en.gravatar.com/site/implement.