Have you visited the new DrHyman.com?

Dr. Mark Hyman is a family physician, a four-time New York Times bestselling author, and an internationally recognized leader in the field of Functional Medicine.  His websites, DrHyman.com and UltraWellnessCenter.com, contains a wealth of information on Functional Medicine, his 7 Keys to Ultra Wellness, books, healthy recipes, dietary supplements and more.

Dr Hyman’s team was looking for a way to show the world who Dr. Hyman is while maintaining the many facets of his work under a single platform.  We knew that WordPress MultiSite would be the perfect platform to provide just what they needed. WordPress MS allows Dr. Hyman to manage DrHyman.com, UltraWellnessCenter.com and his microsites from one centralized location.

Using the Genesis theme framework, we worked with Dr. Hyman and his team to create a new design and layout for DrHyman.com and UltraWellnessCenter.com.

Working along with the consulting services of Margaret Roach and the design services of Kenneth Smith, the new DrHyman.com is clean, informative, easy to maneuver and easily manageable for Dr. Hyman and his team!

If you are interested in learning how you can maximize your current website with WordPress, please contact us today!

Thesis to Genesis Conversion Sale!

Due to the recent WordPress licensing controversy many people are rethinking their theme choice.  WordPress and the WordPress community has always been great to us and to show our support, WebDevStudios is offering to change your theme from Thesis to Genesis at a discounted rate of 50% off.*

With this special you are not only receiving a theme conversion at a hugely discounted rate, but you can also get the new theme for free! Yesterday Matt Mullenweg offered to buy the theme for anyone looking to switch off of Thesis, so the theme license is waived.

When we are done your site will look exactly the same, but you will be running on a GPL-friendly theme that is in full compliance with the WordPress software license.

If you are interested in taking advantage of this promo or would like more information contact us and be sure to mention the Thesis to Genesis promo!

* This offer and discounted rate is only good for exact conversion. Any additional alterations to your website will be billed at our regular development rate. Prices may vary depending on complexity of site design. This offer is good for a limited time and ends Thursday, July 22nd at midnight, Eastern time.

Have you updated to 3.0?

WordPress recently released version 3.0 with a variety of new features and updates such as a new default theme called Twenty Ten, a merge of MU and WordPress, a new lighter interface and 1,217 bug fixes and feature enhancements.  To view a complete list click here.

Have you updated your website to 3.0?  We have already updated all of our annual support clients to the newest version of WordPress at no additional charge.

If you are interested in upgrading your website to the newest version of WordPress or would like more information on one of our Support Packages contact us today!

Welcome Ronald!

WebDevStudios is proud to announce that we’ve recently added a new member to our team!  Ronald Huereca, author of WordPress and Ajax and creator of the Ajax Edit Comments plugin joined the WedDevStudios team earlier this month.  Brad met Ronald as one of the original panel members on WordPress Weekly along with himself and Jeff Chandler.

Ronald is an extremely knowledgeable developer and we are excited to work with him and add his expertise and insight to are already great development team. Welcome Ronald!

CollabPress v0.5 Released!

CollabPress, our new and popular task management plugin for WordPress, has a new version out: v0.5 beta! This new version adds a lot of great functionality including:

New task comments in CollabPress

Please download and help us test this new version. If you experience any issues please report them in our support forum.

Merry Christmas from WebDevStudios!

merry-christmas-from-wds

Change WordPress permalinks on pages to have a .html extension

We are working on a new website built with WordPress MU, BuddyPress and bbPress and our client requested that all of the pages and posts of each MU site have a .html extension. Ok, so posts are easy just head to your “Permalink Settings” page, click the “Custom Structure” radio button and add something like “/%postname%.html”. Pretty simple huh?

So what about pages? I found a great plugin called .html on Pages which will add a .html extension to all of your pages. This plugin will also automatically remove the .html extension from any pages that are nested  as a parent page. Soooo: yourwebsite.com/mypage.html will turn into yourwebsite.com/mypage/mysubpage.html.

We ran into a problem, well not so much a problem because the plugin does what it is supposed to do, but we want to not add .html to the end of the blog page. We want /blog.html to be just /blog so we had to make a few modifications to the plugin. If you are comfortable with php the mod is small and here it is:

Add the following code where ever you want inside of the plugin. This code filters any instance of /blog.html and returns /blog.

function blog_permalinks_page_link($permalink, $page) {
$pos = strpos($permalink, “/blog.html”);
if ($pos !== false) {
$permalink = str_replace(“/blog.html”,”/blog”,$permalink);
}
return $permalink;
}
add_filter( ‘page_link’, ‘blog_permalinks_page_link’, 10, 2 );

Next you will need to alter the html_page_permalink() function and add the following code to the top of it:

$string=$_SERVER['REQUEST_URI'];
$pos = strpos($string, “/blog.html”);
if ($pos !== false) {
switch_to_blog(1);//We are using WPMU if you are not you won’t need this line.
wp_redirect( get_option(‘home’).str_replace(“/blog.html”,”/blog”,$string), 301 );
exit();
}else{
$pos = strpos($string, “/blog”);
if ($pos !== false) {
$_SERVER['REQUEST_URI'] =str_replace(“/blog”,”/blog.html”,$string);
global $wp;
$wp->parse_request();
}
}

The above code makes the redirect of any hits on /blog.html to /blog (which shouldn’t happen because of the link filter) and hard-codes the request-URL so WordPress thinks it’s pulling from the page /blog.html when it’s now on /blog. That’s it, pretty simple… If you are not good with php you can download the modified plugin here: http://webdevstudios.com/downloads/html-on-pages.zip

I’m sure this plugin could easily be modified to work with other extentions like .htm or .php, which could cut down on the amount of 301 redirects you would have to make when migrating to WordPress which by the way everybody running a blog or basic CMS should be doing! ;)

SQL: Script to attach and detach Databases for mass moves

I dont know about most of you, but this is something that I have had to do on multiple occasions, moving databases to a new SAN/drive/etc.  And the environments that I normally have to support have WAY too many databases to sit and detach, move, then reattach by hand.  A lot of scripts out there arent very intuitive, and some other blogs I have read can be rather misleading. 

The following scripts were originally borrowed from somewhere out there, over the rainbow, and tweak to meet the requirements that make my life easier.  Unlike most scripts you will find, this one actually pulls out the filenames from the system database to help with locating, moving, and reattaching.  (This is sort of important since a lot of applications create thier own databases, and being that there are do many, I would have to sit and document everything). Obviously, from this script, I only want databases that are on the M: drive, so the script will only pull out those values. Change that to whatever you want it to be. @DBPath and @LogPath are the new locations where I will be moving the files to.

--Declare variables
DECLARE @DBPath varchar(400)
DECLARE @LogPath varchar(400)
SET @DBPath = 'H:SQLDATA'
SET @LogPath = 'I:SQLLOGS'
use [master]

--You can copy and past these results into a new query window for the re-attach script
Select 'EXEC sp_attach_db @dbname='''+ [name] + ''',',
'@filename1=''' + @DBPath + REVERSE(SUBSTRING(REVERSE(filename), 0, CHARINDEX('', REVERSE(filename), 1))) + ''',', +
'@filename2='''+ @LogPath + [name] +'_Log.ldf''' from sysdatabases
where dbid > 4 AND filename LIKE 'M:%'

Now this is only the step for creating the scripts to re-attach the databases. The following is the detach script.
--Code to generate detach script
Select 'EXEC sp_detach_db ''' + [name] + '''' from sysdatabases where dbid > 4 AND filename LIKE 'M:%'

I hope this helps someone out, it has sure saved my butt some work a few times.

MOSS: Enable versioning from C#

 Add a web reference to the Lists.asmx web service.  Call it whatever you want, I used “PDLists”.  The following code will access a document library or list, and enable versioning.  Simple, but effective.

I use this code in a command line application, saves a lot of time from not logging into a site, finding the list or library, opening settings, opening versioning properties, and then enabling.

public static void EnableVersioning(string URL, string ListName)

{

PDLists.Lists EnableVersions = new PDLists.Lists();

EnableVersions.Credentials = CredentialCache.DefaultCredentials;

EnableVersions.Url = URL + “lists.asmx”;

XmlNode _response = null;

XmlNode ndList = EnableVersions.GetList(ListName);

XmlNode ndVersion = ndList.Attributes["Version"];

XmlDocument xmlDoc = new System.Xml.XmlDocument();

XmlNode ndProperties = xmlDoc.CreateNode(XmlNodeType.Element, “List”, “”);

XmlAttribute ndVersionAttrib = (XmlAttribute)xmlDoc.CreateNode(XmlNodeType.Attribute, “EnableVersioning”, “”);

ndVersionAttrib.Value = “TRUE”;

ndProperties.Attributes.Append(ndVersionAttrib);

XmlDocument doc = new System.Xml.XmlDocument();

XmlElement batchElement = doc.CreateElement(“Batch”);

XmlNode newItemhome = EnableVersions.GetListCollection();

try

{

_response = EnableVersions.UpdateList(ndList.Attributes["ID"].Value, ndProperties, null, null, null, ndVersion.Value);

}

catch (Exception ex)

{

Console.WriteLine(ex.Message + “\n ” + ex.StackTrace);

}

Console.WriteLine(“[versioning enabled]“);

}

MOSS: Excessive Sync errors on Sharepoint 2007 Front End Web Server

In several MOSS deployments with multiple front ends, I have noticed many sync issues in the event logs.
A runtime exception was detected. Details follow.
Message: Cannot insert duplicate key row in object 'dbo.UserMemberships' with unique index 'CX_UserMemberships_RecordId_MemberGroupId_SID'.
The statement has been terminated.
Techinal Details:
System.Data.SqlClient.SqlException: Cannot insert duplicate key row in object 'dbo.UserMemberships' with unique index 'CX_UserMemberships_RecordId_MemberGroupId_SID'.
The statement has been terminated.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at Microsoft.Office.Server.Data.SqlSession.ExecuteNonQuery(SqlCommand command)
at Microsoft.Office.Server.UserProfiles.WSSSynchSqlSession.SynchExecuteNonQuery(SqlCommand cmd, Boolean throwOnFail)
at Microsoft.Office.Server.UserProfiles.WSSSynchSqlSession.SynchExecuteNonQuery(SqlCommand cmd)
at Microsoft.Office.Server.UserProfiles.SiteSynchronizer.WriteChangeLogConsumed()
at Microsoft.Office.Server.UserProfiles.SiteSynchronizer.Synch()
at Microsoft.Office.Server.Diagnostics.FirstChanceHandler.ExceptionFilter(Boolean fRethrowException, TryBlock tryBlock, FilterBlock filter, CatchBlock catchBlock, FinallyBlock finallyBlock)

Why cant anything ever just work with Microsoft?
 
It could be do to backing up and restoring databases to different applications.  It causes the GUID for the content DB to be the same, causing a conflict during synchronization.
 
To get a list of all the GUIDs with sync issues you can use the following command from one of the front ends:

stsadm -o sync -listolddatabases 0

You can then use this information to query SQL and see which databases are having issues.  OR, you can use this VBS script to get the information:
Set Args = WScript.Arguments
Connstr = "Driver={SQL Server};Server=SQL2005;Database=Config_DB"
Set Connect = CreateObject("ADODB.Connection")
Connect.Open Connstr
strInput = Args.Item(0)
Set DB = Connect.Execute("SELECT Id, ClassId, Name, Status, Version, Properties FROM Objects WHERE (Id = '" & strInput & "')")
Do Until DB.Eof
WScript.Echo Db("Id")
WScript.Echo Db("ClassId")
WScript.Echo Db("Name")
WScript.Echo Db("Status")
WScript.Echo Db("Version")
'WScript.Echo Db("Properties")
DB.MoveNext
Loop

To help get a baseline in our environment, I just ran:


stsadm -o sync -deleteolddatabases 0

This doesnt remove the databases, it removes the sync error.  I let the servers run over the weekend, then checked again.
 
To fix the issue, we detatched the databases in order to issue the a new GUID.
 
Detatching the DB will not delete it, just remove it from the farm.
 
To detach:

stsadm -o preparetomove -contentdb -contentdb : -site
stsadm -o deletecontentdb -url -databaseserver -databasename

To reattach:
stsadm -o addcontentdb -url -databasename -databaseserver

I hope that saves someone else some time.