Cloning an Existing Feature

The question often comes up about how to customize mojoPortal features. Here I am talking about content system features not core features of site administration, just things that plug into the content system as features like the blog, image gallery or forums, etc.

I don't recommend anyone to just start hacking away at the mojoPortal code to make customizations. If you do that you end up with a fork and no easy way to upgrade to newer versions of mojoPortal. There are really only 2 ways to go when you find yourself wanting to modify an existing feature. You can consider contributing your enhancement back to the project if its is something that you think would be of general use to everyone, or you can clone an existing feature before you start customising it so that it is a separate custom feature that will not be overwritten by the existing mojoPortal feature when you upgrade. Even if you would like to contribute your enhancement back to the project, it may not always be possible due to issues you may not have considered. For example if your enhancement requires schema changes like new columns or tables in the database, it cannot go back into the project unless its implemented for all 5 databases that we support. We can't go breaking the other data layers. You may or may not have the time or wherewithal to do all that so it may fall on a core developer to implement the needed changes for the other data layers and this will be subject to the time and interest constraints of the core developers. It may also be subject to code review and re-factoring before we would consider integrating it. At any rate, feel free to offer contributing as we consider it on a case by case basis and if we see a lot of value in your enhancement we may fast track it. But please be understanding if not.

The rest of this article will describe the basic steps for cloning a feature which allows you to move forward with your customizations without fear of losing the ability to upgrade, and also frees you from concerns about constraints in getting your changes into mojoPortal. However, before you clone a feature and before you make any changes to the code you should make sure that you really understand how it works in the first place.

The basic goals/steps of cloning are:

  1. Create your own projects, a Web Application Project for the UI, a class library for the Business logic and a class library for the data layer.
  2. Use a different folder name for your feature so it doesn't clash with the original and make changes in the code to reflect that path differences now that it is in a new folder for links to supporting pages from the ModuleControl.
  3. Use your own namespace in the C# code to differentiate it from the original feature.
  4. Use a new feature guid to identify it as not the same feature as the one you clones
  5. Use your own database tables so that you are free to change the schema
  6. Use a different settings configuration file than the original
  7. Use different resource (.resx) files than the original

Lets take the Blog feature as an example. Suppose you would like to be able to attach a file to every post or some other change where you will need additional database columns or tables.

I would copy one of the mojoportal.sln files and rename it, then you can add your custom projects to this solution. Create a Web Application Project for the UI, a Class library for the business logic and a class library for the data layer.

Copy the Blog folder from the mojoPortal.Features.UI project up beneath your web UI project and then rename the folder, then include it in your project. Change the namespace and review the code for any links where the path needs to be modified to reflect your custom folder.

Copy the BlogResoures.*.resx files from mojPortal.Features.UI/App_GlobalResources to the App_GlobalResources folder in your wbe project, then rename them to somecustomname.*.resx. You don't need to copy the .designer.cs files. After you rename the .resx files include them in your project and VS will autmatically create the .designer.cs files.

Create a folder in your Web prject named Setup, then a folder beneath it names applications.

Copy the mojoPortal.Features.UI/Setup/applications/blog folder and put it beneath your applications folder and rename it.

Look in the FeatureDefinitions folder beneath that folder and rename the file 2000_BlogModule.config to somecustomname.config. Next open this file with a text editor and change the feature guid. You can generate a new guid using MS SQL like SELECT newid(), or in .NET code using Guid.NewGuid().ToString(). You also need to change the feature name, modify the controlSource to reflect the new path, and change the resourceFile to the new name of your rersource.resx withouth the .resx extension.

Next copy the data layer classes from mojoPortal.Features.Data.MSSQL/Blog into your own data layer project and change the namespace.

Next copy the business classes from mojoPortal.Features.Business/Blog into your own busines logic project, change the names space. Add a reference to you data layer prject and then change the code to use the namespace you created in your data layer.

Next, go back to the web project and modify it to use the new namespace you created in your business project.

Create a folder named ProviderConfig beneath the /Setup folder in your web project, then create a folder beneath it named indexbuilders.

Copy the file mojoPortal.Features.UI/Setup/ProviderConfig/indexbuilders/blogindexbuilder.config to the same folder you just created, then rename it to yourcustomnameindexvbuilder.config. Open it with a text editor and change the namespace and assembly name to reflect your custom project.

The next step is to create new set of tables and procedures identical to the current feature but with a different prefix. We can accomplish this by doing a simple find and replace to change the table prefix. Scripts are located in 2 folders beneath this /Setup/applications/[applicationname]/ folder, the first is for the initial installation and it should have only 1 script in it, the rest of the scripts are upgrade scripts and they are in a different folder. You are probably only interested in a single database platform like MS SQL, so the first script is in /SchemaInstallScripts/mssql and the rest are in SchemaUpgradeScripts/mssql. Using a text editor like TextPad, you can do a find and replace of mp_ which is the prefix used in the mojoPortal blog. Replace it with some other prefix like joe_ or something that can identify your custom code easily from the rest of mojoportal. You will also need to go through all of the methods in your data layer to change it to reference your prefix anywhere it calls stored procedures or references tables otherwise your data layer is still talking to the original tables. Alternatively you could just use SQL Server Management to generate a script with the very latest version of the tables and related stored procedures then modify them to change the prefix as needed. Now when you run these scripts it will create your custom tables procs etc. Note that the mojoPortal.Features.UI project uses a post build event to copy the /Setup folder up to the Web project. You should do the same with your project.  Then you can visit the /Setup/Default.aspx page to install your feature.

The final step is to setup your own post build event in your web project to copy the needed files up to the Web project. You can copy and modify code from the post build event in the mojoPortal.Features.UI project. Right click the project in Solution Explorer and choose Properties. On the Build Events tab, click the Edit Post Build... button and then copy the post build code. Paste it into youyr own project modifying it and chopping out things not needed. It should be fairly obvious what you need to change and what you can leave out from other features.

Now, if you have done everything correctly and your solution builds, you should be able to visit /Setup/Default.aspx and your feature will get installed and you can add it to a page just like the orginal blog. Now you are free to code away on your changes knowing that you can still upgrade the rest of mojoPortal with no problems.

For additional background information see the article Using The Installation System.