[How to] Create a Theme

Tutorials, tips and tricks.

Moderator: moderators

[How to] Create a Theme

Postby mexijew » Sun Feb 17, 2013 8:51 pm

When Audiogalaxy died (RIP) I needed to find another way to access all my music while on the go. I got Subsonic up and running and immediately checked out all the themes. I love programs that allow skinning/theming so I got excited about theming Subsonic.

Unfortunately, information about theming was scarce-to-nonexistent. After poking around and experimenting, I was able to figure it out. Here's how I did it. (For articles on skinning/theming in general, search online. These notes are about where to put configs and images.)

  • Images go into a folder inside the "icons" folder.
  • CSS goes into the "style" folder. CSS controls, of course, backgrounds, text styles, line spacing, etc.
  • You need to add a ".properties" file to the "WEB-INF\classes\net\sourceforge\subsonic\theme" folder. The data in this file names the images used in the theme. (This most important file was the least obvious and hardest to discover as it is buried so deep in the folder structure.)
The first thing I did was create a working folder (I put it in My Pictures) and unpack the "subsonic.war" file from the install directory (on my Win7 system, C:\Program Files (x86)\Subsonic). I used 7-Zip http://www.7-zip.org/ which recognizes .war files as archives. I also needed a local copy of the outputted HTML so I could see changes instantly without having to install the new subsonic.war and restart the server. I saved the index.html file, which is actually a collection of framesets. Then I saved the sources of each of the frames ( .view files which are just HTML). I also had to change some lines in each source so they would point to the right places for the CSS and images.
I created a folder in the "icons" folder. This folder was for all the graphic images. In the "style" folder, I made a copy of "default.css" and renamed it to my theme name.
In the "WEB-INF\classes\net\sourceforge\subsonic\theme" folder, I made a copy of "default.properties" file and renamed it. Subsonic uses the .properties file to "hard-code" image sources into the HTML sent to the browser. You have to change the references to point to your images. Finally, I added a couple lines in "themes.txt" (in the same folder) to allow my theme to be listed in Subsonic.

I used my local HTML index and .view files to see CSS and image changes so I wouldn't have to keep stopping/restarting Subsonic. It actually wasn't hard to do (any more than skinning/theming already is) once I found the .properties files!

Once I got everything looking how I wanted, I used 7-Zip to pack everything into a "subsonic.war" file. (I only included the folders and files from the original plus my modifications. I didn't include "working" files like GIMP or .view files used to see my changes locally.) I stopped the Subsonic service, copied the .war file to the install directory C:\Program Files (x86)\Subsonic (NOT the "live" directory C:\Subsonic), then restarted the service. The theme could then be chosen after logging in as usual.
For distribution, you only need to include the CSS file, the .properties file, and the folder with your images. End users just need to copy those files to their appropriate locations in their own .war files, after adding the needed lines to their "themes.txt" files so the theme can be listed in Subsonic.

  • If you are theming and you want colored scrollbars in IE, you need to apply them to the html selector, not just body. Since the page is a frameset, the scrollbars belong to the parent (html) not the individual children (body). Or, just avoid IE altogether!
  • Your image folder and css filenames should have web-friendly names (lowercase, no spaces).
  • Stupid IE does not render .view files! When loaded locally, it just showed the sources of each frame. I had to change my "left.view" to "left.html". After warning me about running scripts from a local file, it showed all frames.
  • You may omit any CSS or .properties elements that you are not going to change. Any images that are not expressly changed in .properties default to the basic Subsonic images. Add '@import "default.css";' to the top of your CSS file and delete any lines in your CSS that do not change anything.
  • I made several waves of changes to see how the theme was shaping up in the live install. Sometimes after updating the .war, I needed to refresh the browser and/or individual frames in order to see the changes.
I wanted to add a "highlight" feature to the main icons in the top.view so when users hovered over them they would glow. However, I didn't want to go into the .jsp files to change actual coding. Theme files should never change underlying code; that's the whole point of separating style from content! So I "cheated" a little. In my .properties file, I named the image files to be used, but I added '" class="icon'. Subsonic inserts the rest of the line after the '=' operator in the .properties file into the outputted HTML. This results in an img tag with a class of "icon". Am I cheating by inserting the class attribute? You could say yes, or you could say that those top icons should have been differentiated anyway in the original coding! Anyway, after that, it was easy to make it glow using CSS3.Of course, in IE there are no cool transitions from regular to glow, but I just avoid IE anyway so happy me!

Posts: 1
Joined: Sun Feb 17, 2013 7:28 pm

Re: [How to] Create a Theme

Postby ForSSUx » Fri Apr 05, 2013 9:01 pm

Hi There,

I'm a little puzzeled . I tried to add a theme into the war but i get the following error

Code: Select all
27 [main] INFO org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@148ed35: display name [org.springframework.context.support.ClassPathXmlApplicationContext@148ed35]; startup date [Fri Apr 05 22:51:24 CEST 2013]; root of context hierarchy
81 [main] INFO org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [applicationContext-deployer.xml]
420 [main] INFO org.springframework.context.support.ClassPathXmlApplicationContext - Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@148ed35]: org.springframework.beans.factory.support.DefaultListableBeanFactory@1770daa
433 [main] INFO org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1770daa: defining beans [service,org.springframework.remoting.rmi.RmiServiceExporter#0]; root of factory hierarchy
455 [main] INFO org.mortbay.log - Logging to org.slf4j.impl.SimpleLogger(org.mortbay.log) via org.mortbay.log.Slf4jLog
Using WAR file: /var/subsonic/standalone/subsonic.war
Failed to resolve build number from WAR subsonic.war: java.util.zip.ZipException: error in opening zip file
Extracting webapp to /var/subsonic/jetty
Using WAR file: /var/subsonic/standalone/subsonic.war
491 [main] INFO org.mortbay.log - jetty-6.1.x
[GC 16448K->4225K(62848K), 0.0097670 secs]
704 [main] INFO org.mortbay.log - Started SelectChannelConnector@
Madsonic running on: http://localhost:4040/
758 [main] INFO org.springframework.remoting.rmi.RmiServiceExporter - Looking for RMI registry at port '9412'
781 [main] INFO org.springframework.remoting.rmi.RmiServiceExporter - Could not detect RMI registry - creating new one
813 [main] INFO org.springframework.remoting.rmi.RmiServiceExporter - Binding service 'SubsonicDeployerService' to RMI registry: RegistryImpl[UnicastServerRef [liveRef: [endpoint:[](local),objID:[0:0:0, 0]]]]
[GC 13082K->3594K(79296K), 0.0071830 secs]
[Full GC 3594K->2054K(79296K), 0.0298770 secs]

It seems that war failed...
Is there a special way to pack it in again?

yes: make a directory go into that directory and do a:
Code: Select all
jar -xvf subsonic.war

administer the desired changes

aferwards do a:
Code: Select all
jar -cvf subsonic.war index.html WEB-INF

you'll find a subsonic.war which you can copy over the old one

I'm doing this in a linux shell do for windows your mileage may vary :-)

Kind Regards
Guy Forssman
Posts: 24
Joined: Thu Mar 21, 2013 7:12 pm

Return to Tutorials

Who is online

Users browsing this forum: No registered users and 5 guests