Navigatie

Contact

Send mail to the author(s) E-mail

View Richard Soeteman's profile on LinkedIn

RSS 2.0 | Atom 1.0 | CDF

Archief

Categorieën

Blogroll

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Sign In

Zoeken

# Tuesday, 16 February 2010
Tuesday, 16 February 2010 08:57:09 (GMT Standard Time, UTC+00:00) ( CMSImport | Package | UmbImport | Umbraco )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

I’m very pleased to announce that CMSImport 1.0.3 is released. Now I can hear you think CMSImport? Must be a fork of the great UmbImport package. No this isn’t the case. A few weeks back Niels (AKA @Umbraco) asked me to change the name since Umbraco HQ got a lot of requests about this package. So now the name is CMSImport and that’s not going to change anymore.

CMSImport PRO

Finally we’ve finished our commercial edition of CMSImport.  CMSImport PRO gives you all the options of the default package and the following extra features:

  • Update Content
  • Save Import Steps
  • Schedule imports for a certain time and day

Pricing

You can buy a single domain license of CMSImport. With a single domain license you are allowed to use  CMSImport PRO for a single domain and all subdomains, such as www.example.com, accept.example.com, and local.example.com.

We also have a Enterprise license available. With an Enterprise license you are allowed to install the CMSImport PRO on unlimited production web servers, and use it for unlimited Umbraco instances within the Enterprise. 

A single domain license will be available for  99 Euro, an enterpise license for 389 euro.

When you buy a license you’ll get free updates within 90 days of purchase and  free updates for all minor releases within a major release.  For example, if you purchased a  1.0 version of CMSImport, you get free updates of all 1.x versions through our client area.

Special 1.0 offer.When you buy the 1.0 release you’ll get a free update to 2.x. This is a 1.0 offer only!

What’s more in this release?

Several issues are solved in this release(both in the free and Pro release):

  • "item with the same key already added" error when using duplicate column names
  • Automapping column names
  • The imported document creator is not always the administrator anymore. It's using the logged in user now. When you schedule an import you can select the user that should be used as the creator of the document
  • Special characters in CSV are now supported, we’ve changed the reader from ANSI text to Unicode
  • Sometimes CSV replaced spaces with empty strings, this is solved now
  • With member import you can now merge any member property into the template. Simply surround the member property with [#(property here)]
  • Using a renamed Umbraco folder. This is possible now, although it will be better to change it after install, otherwise you have to install manually.
  • We’ve removed the limitation to allow only one DataAdapter. We are thinking to build a DataAdapter pack which contains adapters to import from wordpress, Rss, Outlook, excel etc. These adapters will be available for free in the Commercial Edition and for a small fee for the Free edition.

Roadmap

In the 1.x version we will add the following functionality:

  • FieldAdapters. Sounds boring but this is a big thing. When you import data now, sometimes the import will fail. For example if you import boolean as text (true/false) and want to store that in a True/False field in Umbraco it will fail. Umbraco expects that the value will be 0/1. FieldAdapters will solve this problem. If a insert of data fails. CMSImport will check if 1 o more FieldAdapters are available to convert the data in the right format. This will be added to version 1.1 which must be ready before CodeGarden 2010.
  • Dictionary Import. Need I say more?
  • Hierarchical imports(PRO only).

In the 2.x version we will add the following functionality:

  • Hierarchical import support in Data Adapters. Not the same as the 1.x Hierarchical import feature ;-)
  • Export/import definitions (PRO only). An easy way to deploy Import definitions

More Info

For more info, download, or purchase you’ll go to http://www.cmsimport.com/

Comments [0] | | # 
# Wednesday, 03 February 2010
Wednesday, 03 February 2010 15:45:02 (GMT Standard Time, UTC+00:00) ( Umbraco )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

Just a small blogpost to announce that I’ve just made a new release of the Package Action Contrib project. The following actions are added to the project:

  • AddConfigurationSection
  • PermissionForApp
  • AddLanguageFileKey
  • MoveFile
  • UpdateAppTree

You can download the new release and documentation from codeplex. I’ve also updated the WIKI page on our.umbraco.org.


Many thanks to the contributors of this release, Simon Dingley, Chris Houston, Dirk de Grave and Søren Spelling Lund for submitting their code!

Comments [1] | | # 
# Monday, 04 January 2010
Monday, 04 January 2010 21:37:53 (GMT Standard Time, UTC+00:00) ( Umbraco )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

This forum post  triggered me to share some code that I had. A while back I was building a site which  let the customers define their own custom overviews One requirement was that users could define the sort by property . To do this you can use the property picker but it wasn’t friendly enough for my case so I ended up building a custom macro parameter type.

To start you need to create a new class library and add references to the following assemblies:

  • Businesslogic
  • Cms
  • Interfaces
  • Umbraco
  • System.web

In the example below I’ve created a class that inherits from dropdownlist. This was the easiest way since I needed a dropdownlist and didn’t want to play with the control tree, Now more important is that this class inherits from the IMacroGuiRendering Interface.  This add two properties ShowCaption, to show the caption on the parameters tab and more important value which holds the selected value . 

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Text;
   4:  using System.Web.UI.WebControls;
   5:  using umbraco.interfaces;
   6:   
   7:  namespace MacroRenderDemo
   8:  {
   9:      public class OrderBy : DropDownList, IMacroGuiRendering
  10:      {
  11:          protected override void OnLoad(EventArgs e)
  12:          {
  13:              base.OnLoad(e);
  14:              if (this.Items.Count == 0)
  15:              {
  16:                  this.Items.Add(new ListItem("Title", "nodeName"));
  17:                  this.Items.Add(new ListItem("Date", "createDate"));
  18:              }
  19:          }
  20:   
  21:          #region IMacroGuiRendering Members
  22:   
  23:          public bool ShowCaption
  24:          {
  25:              get { return true; }
  26:          }
  27:   
  28:          public string Value
  29:          {
  30:              get
  31:              {
  32:                  return this.SelectedValue;
  33:              }
  34:              set
  35:              {
  36:                  this.SelectedValue = value;
  37:              }
  38:          }
  39:   
  40:          #endregion
  41:      }
  42:  }

When you build the project and add the binary into the bin folder of your Umbraco site you still can’t select the new type from the parameter type list. First we need to register the class  in the database. Below you’ll see the database table that holds all the Macro property types.

dbrecords 

It is important that you add the Assemblyname  including the namespace to the macroPropertyTypeRenderAssembly column and add the name of your class to the  macroPropertyTypeRenderAssembly column .

Now we can use the parameter in our macro’s

parameters

and off course we can now use the new parameter in our template when we select the macro

InsertMacro

Another example how flexible Umbraco is. If a requirement isn’t available out of the box, usuallyall it takes is to implement an interface and write a few lines of code.

Comments [4] | | # 
# Saturday, 02 January 2010
Saturday, 02 January 2010 09:34:32 (GMT Standard Time, UTC+00:00) ( Umbraco )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

Let’s start with wishing you all the best for 2010. 2009 was an insane year for me, I had given myself one year  being successful in business running my own Umbraco  projects instead of being a .net contractor. That turned out great, I’ve got a lot of new customers, have build a few great sites for my customers  and did a few Umbraco consulting jobs. So now it’s time to make plans for 2010.  First thing is that I’m moving to a real office instead of working from home. I’m really excited about this because I’m moving to an office building with lots of small companies, I think that’s really inspiring.

When I’ve started investigating Umbraco back in 2008 we had a small amount of companies in the Netherlands (mostly freelancers) that where building websites based on Umbraco. Nowadays I see new companies that build Umbraco websites every week, not only small shops but also really big agencies. For this year my focus will be on helping companies (worldwide) being successful implementing Umbraco sites for their clients by offering consultancy services and custom package development  instead of building sites from front to end.

As you might know I’m also working for a long time on UmbImport PRO. My plan was to release this package last year. It’s the top prio on my todolist for Q1 this year. Also another package will see the light this year, UmbLinkChecker. As the name says this will be a package that checks every link in your published site, not only in content but also hard coded links in your templates etc., I will build a free and Pro version. Since Umbraco has more than 75000 active installs I think it’s profitable to build commercial packages for Umbraco and we will see more and more commercial packages from different vendors. Hope the Umbraco store will be back up in 2010 and filled with great products.

The last year I couldn’t find enough time to blog or write WIKI’s and helping the community with their problems on the forum. I’m hoping this year that will change, since I’ve got a lot of info that I’d like to share.

Have a great 2010!

Comments [0] | | # 
# Sunday, 27 December 2009
Sunday, 27 December 2009 07:37:27 (GMT Standard Time, UTC+00:00) ( Package | Umbraco )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

Usually I develop websites that require login functionality for one or more roles, now this is all cool for my clients but it’s a nightmare for me because I simply can’t remember all the login and passwords. To make my life and other developers life’s a little bit easier I’ve developed the Memberswitcher package. This package let's you easily login members and switch between members by simply selecting a member from a pull down list instead of enter the username and password. It’s using a lower level asp.net membership method to login the member based on the username and is fully compatible with all the asp.net Membership controls. Also the methods to fill the Membergroup and Member pulldowns are using Membership methods, so it will work with the Umbraco members but also with other membership providers.

Once installed, an extra macro is added to the list. In your template select the Memberswitcher macro, optional specify a node to redirect to once logged in and that’s it.
<umbraco:Macro RedirectToNodeAfterLogin="" Alias="MemberSwitcher" runat="server"></umbraco:Macro>

When you visit the website you’ll see the control in action. First select the Membergroup and Member.

membershwitcher_1 
When you click the Login selected member button you’ll be logged in as you can see in the following screenshot that is using the asp.net LoginStatus control.

membershwitcher_2

Needless to say:
DO NOT USE THIS PACKAGE IN A PRODUCTION ENVIRONMENT!!

Download the package here

Comments [0] | | # 
# Tuesday, 27 October 2009
Tuesday, 27 October 2009 20:06:12 (GMT Standard Time, UTC+00:00) ( Umbraco )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

A few weeks back I had this  issue when deploying a site. I needed to modify a documenttype to add a few properties and after a few minutes an error was raised and the only thing I could see when I deleted the property and saved the documenttype again, or opened a document based on that document type was the following error message (thanks Dan for the picture). 

error-delete (3)

Did I make a backup? ehh no, so I needed to fix this. Okay let’s look at  the error message again. An Object reference not set error is thrown while deleting the property. Love that Umbraco is open source and I can have a look at the source code. Below you see the method that is responsible for deleting the property from the documenttype.

   1:          public void delete()
   2:          {
   3:              // flush cache
   4:              FlushCache();
   5:   
   6:              // Delete all properties of propertytype
   7:              foreach(Content c in Content.getContentOfContentType(new ContentType(_contenttypeid)))
   8:              {
   9:                  c.getProperty(this).delete();
  10:              }
  11:              // Delete PropertyType ..
  12:              SqlHelper.ExecuteNonQuery("Delete from cmsPropertyType where id = " + this.Id);
  13:              this.InvalidateCache();
  14:          }

As you might have seen there is no check for null values on the 9 (c.getProperty(this).delete();). This is what caused the error while deleting the property. I assume it's sort of the same issue when opening a document. Now that I know this I can work on a solution. As I mentioned earlier, I needed to add properties to the document type. Below you find the code I’ve used to do that.

   1:   ContentType ct = ContentType.GetByAlias("_advertiser");
   2:          foreach (PropertyType i in ct.PropertyTypes)
   3:          {
   4:              if (i.Alias == "linkToSpecial")
   5:              {
   6:                  // Delete all properties of propertytype
   7:                  foreach (umbraco.cms.businesslogic.Content c in umbraco.cms.businesslogic.Content.getContentOfContentType(ct))
   8:                  {
   9:                      if (c.getProperty("linkToSpecial") == null)
  10:                      {
  11:                          c.addProperty(i, c.Version);
  12:                          c.Save();
  13:                      }
  14:                  }
  15:                  //Remove comment to delete the property from the doctype
  16:                  //i.delete();
  17:                  //ct.Save();
  18:              }
  19:          }

As you can see, I’ve used a  few hard coded values. _advertiser is the alias of the document type and linkToSpecial is the alias of the property that I wanted to add on the Document type. If you want to delete the property  remove  lines 9-13 and remove the comment on line 16 and 17. You can use this code in a usercontrol and use that usercontrol as a dashboard control. Needless to say, this code comes without a warranty.

I’ve added the issue to codeplex, please vote for it!. Hope this post is a nice work around for the issue.

Comments [0] | | # 
# Monday, 10 August 2009
Monday, 10 August 2009 19:18:04 (GMT Daylight Time, UTC+01:00) ( Umbraco )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

Just a little quick tip. When you install Umbraco v4.0.2.1 (don't know about other versions) without runway and you publish your site, you will see a blank screen. This is because the data/umbraco.config file contains the runway site as you can see in the sample xml below. 

<!DOCTYPE umbraco[ &lt;!ELEMENT nodes ANY>  <!ELEMENT node ANY>  <!ATTLIST node id ID #REQUIRED> ]>
<root id="-1">
  <node id="1048" version="6f0d47e7-8cf1-43e5-a5ad-c687e0b78331" parentID="-1" level="1" writerID="0" 
creatorID="0" nodeType="1045" template="1042" sortOrder="2"
createDate="2008-05-02T09:52:36" updateDate="2009-02-18T10:19:26" nodeName="Runway Homepage"
urlName="runway-homepage" writerName="Administrator"
creatorName="Administrator" nodeTypeAlias="RunwayHomepage" path="-1,1048"> <data alias="bodyText"><![CDATA[<p>Runway gives you a bare-bones website that introduces you to a set of
well-defined conventions for building an umbraco website.</p> <p>The Runway website is very simple in form and provided without any design or functionality.
By installing Runway, you&rsquo;
ll begin with a minimal site built on best practices. You&rsquo;ll also enjoy the benefits of
speaking the same &ldquo;language&rdquo;
as the rest of the umbraco community by using common properties and naming conventions.</p> <p>Now that you know what Runway is, it is time to get started using Runway.</p>]]></data> <data alias="siteName">Runway</data> <data alias="siteDescription"><![CDATA[Off to a great start]]></data> ..................... </node> </root>

Work around for this issue is to republish the entire site first. I've added this issue to codeplex. Please vote here.

Comments [2] | | # 
# Tuesday, 30 June 2009
Tuesday, 30 June 2009 08:43:08 (GMT Daylight Time, UTC+01:00) ( UmbImport | Umbraco )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

I'm very pleased to announce that I finally released the V1 version of UmbImport. For those of you who don't know what UmbImport is:

UmbImport helps you import content or members from any datasource into Umbraco. The following datasources are supported by default:

  • SQL Server
  • CSV file
  • XML file

You can also create your own custom DataAdapter. Check out the following links to screencasts to see the power of UmbImport. 

The package is added to our.umbraco.org the new Umbraco community site , so you can download it there or use the UmbImport site. On our.umbraco.org you will find a forum also where you can drop your questions/feature requests/ bugs etc. In August I will release a manual also. If you find any issues please report it on the forum or comment on this post.

Comments [0] | | # 
# Monday, 04 May 2009
Monday, 04 May 2009 20:06:31 (GMT Daylight Time, UTC+01:00) ( Umbraco )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

In February I wrote this blogpost which describes the process of how to add a menu item to the context menu using the Umbraco V4 Event system. In UmbImport PRO I've used this mechanism. When I was testing this I came across a bug in my code when using a pagepicker, this was showing an empty tree in the node picker.

 EmptynodePicker

Then I got a little flashback to the level 2 course I attended last November where Niels told us to check if there was a menu attached to the node (which is not the case for the pagepicker) before adding menu items to it, otherwise an exception is thrown what will result in an empty tree. This is what happened in my case. In the example below I've only added node.Menu!= null check and now everything is working fine.

 

   1:  using System;
   2:  using umbraco.BusinessLogic;
   3:  using umbraco.cms.presentation.Trees;
   4:  using umbraco.interfaces;
   5:   
   6:  namespace UnpublishAction
   7:  {
   8:      /// <summary>
   9:      /// Add unpublish to the menu item
  10:      /// </summary>
  11:      public class AddUnpublishActionEvent :ApplicationBase
  12:      {
  13:          public AddUnpublishActionEvent()
  14:          {
  15:              BaseContentTree.BeforeNodeRender += new BaseTree.BeforeNodeRenderEventHandler(BaseTree_BeforeNodeRender);
  16:          }
  17:   
  18:          /// <summary>
  19:          /// Before a menu item gets rendered  we will add the unpublish action if the document is published
  20:          /// </summary>
  21:          private void BaseTree_BeforeNodeRender(ref XmlTree sender, ref XmlTreeNode node, EventArgs e)
  22:          {
  23:              ///Only unpublish when published
  24:              if (node.Menu!= null && !node.NotPublished.GetValueOrDefault(true))
  25:              {
  26:                  //Find the publish action and add 1 for the index
  27:                  int index = node.Menu.FindIndex(delegate(IAction a) { return a.Alias == "publish"; })+1;
  28:   
  29:                  //Insert unpublish action
  30:                  node.Menu.Insert(index, UnpublishAction.Instance);
  31:              }
  32:          }
  33:      }
  34:  }
  35:   

Download Source

Hope it didn't get you into trouble, sorry if it did.

Comments [0] | | # 
# Thursday, 16 April 2009
Thursday, 16 April 2009 23:02:37 (GMT Daylight Time, UTC+01:00) ( UmbImport | Umbraco )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

This post is deprecated

Check out documentation on http://www.cmsimport.com/documentation.aspx instead

As I mentioned earlier it's possible to create a custom data adapter which can be plugged into umbImport. The free edition supports one custom data adapter, the pro edition will support multiple adapters.  In this multi part series I will demonstrate how you can create your own data adapter by building an RSS import adapter. In this first part we will create the basic adapter in later post we will refine the functionality. For this first part I've installed Umbraco 4.0.1 and the packages Blog4Umbraco and UmbImport beta 1.

Create the adapter

You can create a custom data adapter by deriving from two classes:

  • UmbImportLibrary.BaseTypes.ImportDataAdapter.
  • UmbImportLibrary.BaseTypes.ImportDataUI.

The ImportDataAdapter class provides the real communication to the datasource and holds a reference to the ImportDataUI class which is responsible for the user input. For our RSS import adapter we will start by creating the UI class.

 
   1:      public class RSSDataAdapterUI : ImportDataUI
   2:      {
   3:          private Panel _rssContentPanel = new Panel();
   4:          private Literal _selectRssSourceLiteral = new Literal();
   5:          private TextBox _rssLocation = new TextBox();
   6:   
   7:          protected override void OnInit(EventArgs e)
   8:          {
   9:              base.OnInit(e);
  10:   
  11:              _rssContentPanel.ID = "RssContentPanel";
  12:              _selectRssSourceLiteral.ID = "SelectRssSourceLiteral";
  13:              _selectRssSourceLiteral.Text = "Specify the RSSLocation";
  14:              _rssLocation.ID = "RssLocation";
  15:              _rssLocation.Width = 400;
  16:              _rssContentPanel.Controls.Add(new LiteralControl("
"));
  17:              _rssContentPanel.Controls.Add(_selectRssSourceLiteral);
  18:              _rssContentPanel.Controls.Add(new LiteralControl("
"));
  19:              _rssContentPanel.Controls.Add(_rssLocation);
  20:              _rssContentPanel.Controls.Add(new LiteralControl(" example http://feeds.feedburner.com/umbracoblog 
"
));
  21:   
  22:              this.Controls.Add(_rssContentPanel);
  23:          }
  24:   
  25:          /// 
  26:          /// Returns the Datasource
  27:          /// 
  28:          public override string DataSource
  29:          {
  30:              get
  31:              {
  32:                  return _rssLocation.Text;
  33:   
  34:              }
  35:          }
  36:      }

The OnInit method generates the form. The only real interesting thing in this class is the datasource property. This will be used in UmbImport to initialize the import with the selected datasource.

   1:      public class RSSDataAdapter : ImportDataAdapter
   2:      {
   3:          private ImportDataUI _xmlImportUI;
   4:   
   5:          /// 
   6:          /// Alias of the import adapter
   7:          /// 
   8:          public override string Alias
   9:          {
  10:              get { return "RssImport"; }
  11:          }
  12:   
  13:          /// 
  14:          /// Get XML Data
  15:          /// 
  16:          /// 
  17:          public override IDataReader GetData()
  18:          {
  19:              return XmlToDataReader(DataSource, "//item");
  20:          }
  21:   
  22:          /// 
  23:          /// Validates the selected datasource
  24:          /// 
  25:          public override bool Validate()
  26:          {
  27:              bool result = false;
  28:              try
  29:              {
  30:                  using (IDataReader datareader = XmlToDataReader(DataSource, "//item"))
  31:                  {
  32:                      result = true;
  33:                  }
  34:              }
  35:              catch
  36:              {
  37:                  result = false;
  38:              }
  39:              return result;
  40:          }
  41:   
  42:          /// 
  43:          /// Holds a reference to the UI control of the adapter
  44:          /// 
  45:          public override ImportDataUI UIControl
  46:          {
  47:              get
  48:              {
  49:                  if (_xmlImportUI == null)
  50:                  {
  51:                      _xmlImportUI = new RSSDataAdapterUI();
  52:                      _xmlImportUI.ID = "RssImport";
  53:                  }
  54:                  return _xmlImportUI;
  55:              }
  56:          }
  57:      }

The Alias property will return the unique alias that we can use to select our adapter during the Import process. The GetData method will return a datareader initialized with the datasource. When importing XML it needs to be converted to a datareader first. The ImportDataAdapter Base class has a method XmlToDataReader what will convert the xml file to  a datareader. The Validate method will check if the selected datasource is valid. The UIControl property holds a reference to the RSSDataAdapterUI class. The ImportDataAdapter base class has more properties/methods that you can override but for this data adapter we are done.

When you compile the project and put the DLL in the bin folder of the Umbraco install the DLL will be picked up automatically by UmbImport.

Using the RSS import adapter

When you start UmbImport you will see in step 2 that you can select the RssImport data adapter

image

In the next step we will see the form that we have created in the RSSDataAdapterUI class. Here we can specify the RSS location.

image

In the Next step we can specify the location where to store the blogposts (Note: When using the Blog package blogposts will be arranged by data automatically) and we select the blogpost as document type.  In step 5 we will create the mapping between the fields from the RSS feed and the Umbraco Document Properties. You will see a lot of other fields from the RSS Feed. Just ignore them for now. In a later post we will filter the columns.

image

The result

When you click next and next again on the confirm screen the RSS feed will be imported.

image 

In the next post I will show you how to Import the comment data with the same Adapter. I will also show you how to filter the columns for the property mapping dropdowns. When you want to play with this import adapter then  download the source here.

Comments [0] | | #