Webアプリケーションの静的リソースの管理
5822 ワード
Kevin M.Gillは、彼のブログPreprocessing CSS in GrailsおよびImprove Grails Performance With Static Resourcesで、GrailsアプリケーションのCSSで静的リソース管理をどのように簡素化するかを共有しました.
Web開発では、画像などの静的リソースのパスをCSSで変更する必要があります.リソースの数が大きい場合は、大量の置換作業が必要になり、エラーが発生しやすくなります.このときGroovyの${}を思い浮かべ,CSSで${}が使用可能であれば,画像の格納場所をプロファイルやデータベースに配置して統合管理する.画像の保存経路が変更された場合は、数箇所か1箇所の位置情報を修正するだけで便利ではないでしょうか.
CSSを使用する場合、背景図などの内容を設定すると、通常は以下のような書き方になります.
あるいは、画像の位置を相対的な位置に書きます.例えば、
具体的な実装手順を見てみましょう.まず元のCSSファイルを改造し、以下のコードを参照してください.
%GrailsApp%/grails-app/taglibディレクトリの下にTagLibを作成しgroovyqを設定.staticResourceが実行する内容は、次のコードを参照してください.
%GrailsApp%/grails-app/config.groovyファイルに追加:myapp.staticresources.url = "http://localhost:8080/GrailsUI/static「静的リソースのパスを指定します. StaticResourceというControllerを追加して、CSSを読み込み、CSSファイルの${}の内容を処理します.StaticResourceControllerのすべてのコードは次のとおりです.
gspページのCSSへの参照を変更します.このコードは/staticResource/cssに基づいてStaticResourceControllerのcssという閉パケットを呼び出し、pcssはこの閉パケットで使用するfileの値です.これでいい! 静的リソースが多い場合は、StaticResourceControllerによってこれらのリソースをロードするのはメモリを消費するため、StaticResourceControllerでいくつかのCacheの制御を行うことができます.以下のcss閉パッケージのコードを参照してください.
上記のように実際に書かれているのは純粋なCSSファイルではなく、Groovy Templateファイルです.その後,groovyPagesTemplateEngineを用いて処理を行い,最終的に必要なCSSファイルを生成するという考え方からjavascript,mediaと同様の処理を行い,アプリケーションにおける静的リソース管理を簡素化する目的を達成することができる.
Web開発では、画像などの静的リソースのパスをCSSで変更する必要があります.リソースの数が大きい場合は、大量の置換作業が必要になり、エラーが発生しやすくなります.このときGroovyの${}を思い浮かべ,CSSで${}が使用可能であれば,画像の格納場所をプロファイルやデータベースに配置して統合管理する.画像の保存経路が変更された場合は、数箇所か1箇所の位置情報を修正するだけで便利ではないでしょうか.
CSSを使用する場合、背景図などの内容を設定すると、通常は以下のような書き方になります.
.some_div {
...
background: url('http://localhost:8080/GrailsUI/static/img/grails_logo.png');
...
}
あるいは、画像の位置を相対的な位置に書きます.例えば、
.some_div {
...
background: url('../static/img/grails_logo.png');
...
}
具体的な実装手順を見てみましょう.
.some_div {
...
background: url(${groovyq.staticResource(dir:"/img/",
file:"grails_logo.png")});
...
}
class StaticResourcesTagLib {
static namespace = "groovyq"
def grailsApplication
def staticResource = { attrs, body ->
def dir = (attrs.dir) ? attrs.dir : ""
def file = (attrs.file) ? attrs.file : ""
def url="${grailsApplication.config.myapp.staticresources.url}" +
"/${dir}/${file}"
out << body() << url
}
}
class StaticResourceController {
def groovyPagesTemplateEngine
def css = {
def file = params.id
def cssPath = servletContext.getRealPath("css/${file}.css")
def resourceFile = new File(cssPath)
if (!resourceFile.exists()) {
// 404: Not Found
render(text:"File Not Found",status:404)
return
}
def buffer = null
try {
buffer = processTemplate(resourceFile, params)
} catch (Exception ex) {
log.error "Failed to process template", ex
}
if (buffer != null) {
render(text:buffer, contentType:"text/css")
} else {
// 500: Internal Server Error
render(text:"Failed to process template", status:500)
}
}
def processTemplate(resourceFile, model) {
def buffer = resourceFile.getText()
def template = groovyPagesTemplateEngine.createTemplate(buffer,
"${resourceFile.getPath()}")
def writer = new StringWriter()
template.make(model).writeTo(writer)
return writer.toString()
}
}
def css = {
def file = params.id
def cssPath = servletContext.getRealPath("css/${file}.css")
def resourceFile = new File(cssPath)
if (!resourceFile.exists()) {
render(text:"File Not Found",status:404)
return
}
def ifModifiedSince = request.getHeader("If-Modified-Since")
if (ifModifiedSince) {
String[] formats = [DateUtils.PATTERN_ASCTIME,
DateUtils.PATTERN_RFC1036, DateUtils.PATTERN_RFC1123]
def dt_ifModifiedSince = DateUtils.parseDate(ifModifiedSince,
formats)
long lastMod = (long) (resourceFile.lastModified() / 1000)
long isModSince = (long) (dt_ifModifiedSince.getTime() / 1000)
if (lastMod <= isModSince) {
render (status:304)
return
}
}
def now = new Date(System.currentTimeMillis() + (2693000L * 1000))
response.setHeader("Expires", DateUtils.formatDate(now,
DateUtils.PATTERN_RFC1123))
response.setHeader("Cache-Control", "public")
response.setHeader("Vary", "Accept-Encoding")
response.addHeader("Last-Modified",
DateUtils.formatDate(new Date(resourceFile.lastModified()),
DateUtils.PATTERN_RFC1123))
def buffer = null
try {
buffer = processTemplate(resourceFile, params)
} catch (Exception ex) {
log.error "Failed to process template", ex
}
if (buffer != null) {
render (text:buffer, contentType:"text/css")
} else {
render(text:"Failed to process template", status:500)
}
}
上記のように実際に書かれているのは純粋なCSSファイルではなく、Groovy Templateファイルです.その後,groovyPagesTemplateEngineを用いて処理を行い,最終的に必要なCSSファイルを生成するという考え方からjavascript,mediaと同様の処理を行い,アプリケーションにおける静的リソース管理を簡素化する目的を達成することができる.