We have developed a system that uses a single code base, consisting of four Visual Studio projects with an admin website, and customer facing website (each system has its own MS SQL database).
This has been working great, as all new websites (including admin) reference the same code base projects from within SVN, therefore any changes made to the code base are then available to all websites.
Each website has a different master page, and different user controls (.ascx), and therefore partially different although the main coding behind the sites is the same.
The issue we are having now is if there is a bug, a feature change or a new feature we have to implement it in ALL the sites separately (for both admin and customer site). Which is starting to drive us insane, and also means we have a HUGE margin of error for implementing the changes.
I have thought about using svn:externals but this will become messy.
Branching from a master website and master admin system could be the option, but merging to get the new code is a major issue with the sites not being exactly the same.
I think a nice overview would be say that the markup is totally different per site (except the admin site, which is just a theme change) but the code bases are the same.
What is the best way to manage this or are we stuck doing a lot of copy and paste?
Which points would you like clarity on?
Issues that arise are such as in page JavaScript being different, HTML layouts can be completely different bewtween websites. But the code for the pages is the same.
So I would need to 'synchronise' file and folder such as those found in app_code, but there are issues here as well.
Site 1 and Site 2 could be exactly the same, just a different theme. Site 3 has a different theme as well, but it also has some bespoke code that is only required by this site, some of the code in app_code also acts differently to Site 1 and Site 2
Now I could easily achieve this with branching, but when merging up to the new branches, if there are code differences then there are going to be major conflicts.
Merging would also become a large task and take too long, as we would need to merge only certain folders and files, although you cannot merge a single file through the branch (this could be wrong).
For example:
In the root there is a download.aspx which returns a stream as the response rather than a page, this is used to push all the download requests through the system.
So this page in Site 1 and Site 2 is the same, but in Site 3 it does something extra which no other site requires or needs.
We don't want this bespoke feature to be an overload as we don't want/need it for the other websites, we can now no longer merge this file, from the master website, it must be manually merged.
Hope this explains better what I am trying to achieve.
Basic site structure
|- App_code
|- App_Themes
|- Bin
|- Content
| |- Flash
| |- Images
| |- Scripts
| |- Uploaded
|
|- Controls
| |- MasterPage
| | |-MasterPageControls
| |
| |- Navigation
| |- Search
| |- Templates
| | |- Control Templates
| | |- Page Templates
| |
| |- WebServices
|
|- Errors
|
Everything under Controls Navigation, Search, Templates is .ascx files.
In the root there are several files including default.aspx, download.aspx and preview.aspx
These are the main pages for the website (ignoring Error pages), all pages are dynamically created from the DB.
The Controls folder is where most of the changes between websites happens in the MasterPage, and all other user controls.
I ran into this exact problem a few months ago when we started a significant rewrite of our web app. We had two separate versions of nearly identical sites. The back-end code was 99% identical, while the JavaScript, CSS, and other front-end stuff was very different. We had these two sites in separate trunks in the same SVN repository, and it soon became a nightmare of copying & pasting common code between them. Patching and merging was too painful to be useful, due to slight variations in the files.
Our solution was neither SVN-related nor builing of a common library. Instead, the concept of a separate site is defined in a single codebase via multiple config files and a heirarchy of CSS, image, and language resource files. Site-specific features are enabled by config values.
Each site gets a unique name (say, "foo" and "bar"), which is retrieved from the Web.config file at run-time. The name is used to determine which config file is loaded and which client-side files to use. The setting is blank in SVN. It is set by our deployment scripts when copied to the web servers. On our local development machines, an environment variable defines the site we want to work with.
The file structure of the site-specific files would look like this:
|- Config
| |- AppSettings.foo.config <- overrides Web.config AppSettings for "foo" site
| |- AppSettings.bar.config <- overrides Web.config AppSettings for "bar" site
|- Content
| |- CSS
| |- main.css <- default CSS file for all sites
| |- main.foo.css <- CSS overrides for "foo" site
| |- Images
| |- logo.jpg <- default logo
| |- logo.foo.jpg <- logo used if site name is "foo"
| |- logo.bar.jpg <- logo used if site name is "bar"
This has worked great for us, so far. Adding a new feature to a specific site is as easy as adding the feature to our code-base, and only enabling it for that site.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With