简体   繁体   中英

How can I share common style information (css, images, etc.) across MVC sites?

It's dead simple to share functionality across multiple MVC projects. You just put the code into its own project and reference it in as many solutions as your heart desires. Clean, standard, glorious.

Is there any means to do this for styling code? I'd like to have our common CSS files, the ones that give our applications a similar look and feel, in just one place. Right now I have to spawn new copies for every new application. Thus if something needs to be fixed, it needs to be fixed a dozen times in a dozen places.

Has anyone else dealt with this? I can't separate out the CSS files into their own project, nor do I really want to have a web application that's just css sitting somewhere so all of the applications can use the files remotely via fully-qualified Urls. Is there a TFS trick you can do with source control to link the files together? Is there something I haven't thought of?

Here is the "dead simple" solution for sharing web resources between projects without using CDN, LESS, SASS, NuGet, etc:

  1. Create common Solution Folders containing the resources to be shared, or simply designate one of the projects to be the master.
  2. Use "Add as Link" to add the shared resource files to each project as needed.
  3. Add an AfterBuild task to each project file that will copy the linked files to project folders. This is only needed so that Visual Studio test/debug (F5) will work locally.

If you need the details on how to do this, keep reading.

Configuring Solution Folders for the Shared Resources

** Note that if you're simply going to share files directly from one project to one or more additional projects then you can skip this step.

Visual Studio solution folders do not have to reflect physical file system folders, but doing so will help preserve your sanity. So first create the folders on your local file system and copy the resource files into them. The new folders should be located under your solution folder. For example:

\MySolution
   \Common
      \Images
      \Scripts
      \Styles

Back in Visual Studio, right click on the Solution Items folder and use Add Solution Folder to replicate the new file system folders.

Next, add the files to the new solution folders by right-clicking each folder and using Add Existing Item to add the contents of the folders.

Add Shared Resources as Links

For each project that will use the shared resources, right-click the project folder and choose Add Existing Item . Browse to the common folder, select the desired files, click the drop-down arrow next to the "Add" button and choose "Add as Link".

You may get a source control warning about adding files that are outside of the project directory structure, but this can be ignored since the linked file will be under source control at its source.

Add an AfterBuild Task to Copy Files

When you publish the application to a server the linked files will copied to the project folders to which they are linked and everything works as expected. However, in the development environment the linked files do not physically reside in the project folders. So when you hit F5 to test your application in VS, the shared resources will be missing.

The simple solution is to add an MSBuild task to copy the linked files from their source after each build. This needs to be done to for each project that contains the shared resource links.

Right-click the project and choose Unload Project . Right-click the project again and choose Edit <ProjectFileName> . Scroll to the bottom and add the following (just above "</Project>"):

  <Target Name="AfterBuild">
    <!-- Copy linked content files to local folders so that they are available in the debugger. 
         This is only an issue when running the application locally. The linked files should 
         be automatically published to the correct folder when publishing to a web server. -->
    <Copy SourceFiles="%(Content.Identity)"
          DestinationFiles="%(Content.Link)"
          SkipUnchangedFiles='true'
          OverwriteReadOnlyFiles='true'
          Condition="'%(Content.Link)' != ''" />
  </Target>

** Copy task adapted from this link in TheCodeDestroyer's answer.

Save the project file then right-click and choose Reload Project .

Why not just have one site host that base styling and the other sites reference those styles? I don't see anything wrong with this.

You could create a CDN application of sorts to do this, too.

MVC App #1

<link src="~/css/styles.css" />

MVC App #2

<link src="http://mvcapp1.com/css/styles.css" />

1 - Look into CSS template systems as mentioned :

SASS-Lang Less

http://css-tricks.com/sass-vs-less/ (really good article to start, many related items to in his related posts widget)

These allow you to code your stylesheets in organised manners. You can quickly add dynamic configurations and global changes easily.

2 - Developer your own CSS global listing system :

If you prefer not to use the above CSS stylesheet system. Example

//cdn.com/assets/css/reset.css
//cdn.com/assets/css/main.css
//cdn.com/assets/css/page_home.css
//cdn.com/assets/css/page_cart.css

even...

//cdn.com/assets/global/form_styles.css
//cdn.com/assets/global/global_shortcuts.css

In these, the same form padding, table and tr and other padding rules. Example

.black{color:#000 !important}
.right{float:right}
.left{float:left}

I know I sound like framework mentality but it works..

You can quickly alter the global to ensure all pages are updated.

The CDN storage and compass suggestions are valid too. You see storing on a CDN will save the headache of worrying about application failure / speed / load.

Your application can simply be like

/cloud/servers/settings/global/db
/cloud/servers/settings/global/librarys
/cloud/servers/settings/global/css_config.php (example)

/cloud/servers/1/webapp.com/
/cloud/servers/1/webapp.com/model
/cloud/servers/1/webapp.com/view
/cloud/servers/1/webapp.com/view/themes/tpl
/cloud/servers/1/webapp.com/inc

/cloud/servers/1/webapp2.com/
/cloud/servers/1/webapp2.com/model
/cloud/servers/1/webapp2.com/view
/cloud/servers/1/webapp2.com/view/themes/tpl
/cloud/servers/1/webapp2.com/inc

//cdn.com/assets/css

3 - Configuration of Approach

I personally think that the question should be about the approach of your overall development methodology. Having CSS sit on a CDN application, or having a CSS on a separate server which syncs to the CDN for production live mode is a good idea - keeping it separate and maintaining it via a stylesheet language is even better. You can then quickly use skins, css libraries, image libraries and more. Keeps things organised, faster and much better and ENJOYABLE to look at and take pride in coding with.

Keeping it and using a better system is what is needed. You should use manual and the classical approach of a folder structure IMO. You won't have to worry about responsive application design for mobile/tablet and other bearing issues with updating one CSS line for all the apps or even single apps - even languages, and dealing with multi site development teams.

JUST MY HUMBLE OPINION

Would also strongly recommend a CSS stylesheet language, sure many people hate them. But they are becoming quite useful, especially SAAS it's not a hype like NodeJS was.. it actually works. And does wonders. Look at TopShop, GorgeousCouture.. Arcadia sites.. multiple languages, multiple currencies.. servers and teams working on the same cross brand and several applications for each store..

Well, I don't know much about asp.net development, so forgive me, if it's not the case, but

If resource files in your project have Build Action set to None or Content and Copy to Output Directory set to Copy... , you can easily create the Class Library type of project and place all the files there (preserving the paths), and then reference this "Class Library" in every project that needs the files. Every file will be copied to every referencing project on solution build.

For Embedded Resource build action it will also work, but, you'll need to find a way to specify the assembly, which contains these files (because it will differ from Assembly.GetEntryAssembly ).

Personally I don't like or want the CDN solution as if you have many pages they depend on CDNs 100% up time. After some research I found this solution which was perfect for my use I hope whoever will look for an alternative this is one of them:

http://mattperdeck.com/post/Copying-linked-content-files-at-each-build-using-MSBuild.aspx

We had the same problem and for our purposes we put all general CSS/JS/Images/Layout View into NuGet package and reuse it from every application where we need it. It perfectly works for us.

If you're open to using Sass, Compass extensions might be just what you need.

http://compass-style.org/help/tutorials/extensions/

An extension, when bundled as a gem, allows you to easily include the styles contained within the gem from anywhere on the system that has the gem installed. I recently used this in my latest application (a specialized multi-user CMS where each user has their own subdomain that has a customized layout, but all of the components/widgets have the same styling throughout the application). Setting up a new subdomain's styling is as simple as running a single command and customizing the template I've setup that has a skeleton of a simple layout.

Compass extensions can be used to hold images and JavaScript files as part of a template , but deployed files aren't automatically updated like the styles are (templates from a Compass extension differ from the stylesheets, as the templates are for copying and the stylesheets are for importing).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM