I want to serve CSS and Javascript files from an on-disk directory (i.e. not using WAFileLibrary) and also not using Apache.
<div><br></div><div>I have JQuery CSS files that reference a large number of image files from an images subdirectory. When these files are imported into a WAFileLibrary, the image filenames are changed and of course there are no subdirectories. Changing the original css file to accommodate this is not practical as I expect to receive new ones periodically and then would have to do it all over again.</div>
<div><br></div><div>I am attracted by the easy deployment of Seaside apps when Apache is not involved and for the few files involved it doesn't seem to me that Apache is warranted, especially during development of the site.</div>
<div><br></div><div>I could find no information on the right way to do this, so I subclassed WAServerAdaptor as shown below.</div><div><br></div><div>With these modifications, If the URL received from the browser's path begins with /static, then files are served from a specified directory. Otherwise, the request is passed on (eventually) to WADispatcher as normal.</div>
<div><br></div><div>This works for me, but I have no idea as to whether there is an easier or better way or if there is a feature to allow this that I just did not find.</div><div><br></div><div>I am coming back to Smalltalk after many years and I am definitely a bit rusty, so any criticism of the code will also be greatly appreciated.</div>
<div><br></div><div>Regards,</div><div>TF</div><div><br></div><div><br></div><div><div>'From Pharo1.1 of 17 July 2010 [Latest update: #11411] on 26 October 2010 at 10:08:40 am'!</div><div>WAComancheAdaptor subclass: #TFComancheAdaptor</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>instanceVariableNames: 'staticDirectory staticPathPart'</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>classVariableNames: ''</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>poolDictionaries: ''</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>category: 'TFStuff'!</div><div><br></div><div>!TFComancheAdaptor methodsFor: 'as yet unclassified' stamp: 'TF 10/26/2010 08:58'!</div>
<div>defaultStaticDirectory</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>^ FileDirectory default pathName! !</div><div><br></div><div>!TFComancheAdaptor methodsFor: 'as yet unclassified' stamp: 'TF 10/26/2010 08:59'!</div>
<div>defaultStaticPathPart</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>^ 'static'! !</div><div><br></div><div>!TFComancheAdaptor methodsFor: 'as yet unclassified' stamp: 'TF 10/26/2010 09:55'!</div>
<div>process: aNativeRequest</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>"Serve static files from a specified directory if the URL path begins with a specified name.</div><div><span class="Apple-tab-span" style="white-space:pre">        </span></div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>The default staticDirectory is the current directory (nominally the Seaside resources directory)</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>and the default static path part is 'static'. Thus, if the client requests</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>'<a href="http://localhost:8080/static/css/xyz.css">http://localhost:8080/static/css/xyz.css</a>' and the Seaside resources directory is</div><div>
<span class="Apple-tab-span" style="white-space:pre">        </span>'/home/user1/Seaside.app/Contents/Resources', the file returned will be</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>'/home/user1/Seaside.app/Contents/Resources/static/css/xyz.css'.</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>Requests whose path does not begin with the static path part are unaffected, i.e. they are</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>processed by the WAComancheAdapter as normal."</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>| context pathParts fullFilePath method response |</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>pathParts := aNativeRequest pathParts.</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>pathParts size > 1 ifTrue: [</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>(pathParts at: 1) = self staticPathPart ifTrue: [</div>
<div><span class="Apple-tab-span" style="white-space:pre">                        </span>method := aNativeRequest method.</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>(#(#GET #POST) includes: method) ifFalse: [^nil].</div>
<div><span class="Apple-tab-span" style="white-space:pre">                        </span>fullFilePath := self staticDirectory,aNativeRequest url. </div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>(FileStream isAFileNamed: fullFilePath) ifFalse: [^nil].</div>
<div><span class="Apple-tab-span" style="white-space:pre">                        </span>^HttpResponse </div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>fromStream: (StandardFileStream readOnlyFileNamed: fullFilePath).</div>
<div><span class="Apple-tab-span" style="white-space:pre">                        </span>]<span class="Apple-tab-span" style="white-space:pre">        </span></div><div><span class="Apple-tab-span" style="white-space:pre">                </span>] .</div><div><br>
</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>^ self processResponse: (super process: aNativeRequest)</div><div>! !</div><div><br></div><div>!TFComancheAdaptor methodsFor: 'as yet unclassified' stamp: 'TF 10/26/2010 09:54'!</div>
<div>processResponse: aResponse</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>"Ensures that we get the HttpAdaptor's standard notFound error</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>return, rather than the one line of text/plain that is returned by WADispatcher."<span class="Apple-tab-span" style="white-space:pre">        </span></div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>aResponse status = #notFound</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>ifTrue: [ ^nil ]</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>ifFalse: [^aResponse]</div><div>! !</div><div><br></div><div>!TFComancheAdaptor methodsFor: 'as yet unclassified' stamp: 'TF 10/26/2010 08:52'!</div>
<div>staticDirectory</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>staticDirectory isNil ifTrue: [ staticDirectory := self defaultStaticDirectory ].</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>^ staticDirectory! !</div>
<div><br></div><div>!TFComancheAdaptor methodsFor: 'as yet unclassified' stamp: 'TF 10/26/2010 08:57'!</div><div>staticPathPart</div><div><span class="Apple-tab-span" style="white-space:pre">        </span></div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>staticPathPart isNil ifTrue: [ staticPathPart := self defaultStaticPathPart ].</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>^ staticPathPart! !</div>
</div><div><br></div>