0

FreeMarker を使用して、たまたまシンボリック リンクを含む CMS パスからのテンプレートをレンダリングしようとしています (Linux で)。CMS コードは、テンプレートへのパスを処理します。たとえば、次のパスです。

/var/cms/live/display/main.html

本当に指しています:

/var/cms/trunk/127/display/main.html

/var/cms/liveはベースディレクトリで、/display/main.htmlはパスです。

私の場合、liveはシンボリック リンクです。この場合は へのリンクtrunk/127です。参考までに: トランクは SVN ブランチです。当社の CMS システムが CMS ファイルの新しいリリースを (たとえば) としてダウンロードするとtrunk-128.zip、それを に展開しtrunk/128、シンボリック リンクを (アトミックに) に変更しtrunk/128ます。偉大な。

問題は、FreeMarker がtrunk/127パスをキャッシュしているように見えることです。/var/cms/live/display/main.htmlファイルが更新されたことを認識せず、trunk/127ツリーが削除されると 500 エラーが生成されます。

500 Unable to load template: /display/main.html

FreeMarker に適切なパスをキャッシュさせるにはどうすればよいですか?

4

1 に答える 1

2

FileTemplateLoader問題は FreeMarker のクラスにあることが判明しました。baseDir.getCanonicalFile(...)コンストラクターに渡された base-directory で呼び出しを行います。アプリケーションが起動すると、ベース ディレクトリはによって/var/cms/live実際のパスに解決されるため、シンボリック リンクへの今後の変更は無視されます。/var/cms/trunk/127/getCanonicalFile(...)

コンストラクターでこれを行うため、LocalFileTemplateLoader以下にリストされている独自のものを作成する必要がありました。

これは、 の基本的なスプリング ロードの実装にすぎませんTemplateLoader。次に、FreeMarker 構成を構築するときに、テンプレート ローダーを設定します。

 Configuration config = new Configuration();
 LocalTemplateLoader loader = new LocalTemplateLoader();
 // this is designed for spring
 loader.setBaseDir("/var/cms/live");
 config.setTemplateLoader(loader);
 ...

これが私たちのLocalFileTemplateLoaderコードです。 ペーストビンの完全なクラス:

public class LocalFileTemplateLoader implements TemplateLoader {

    public File baseDir;

    @Override
    public Object findTemplateSource(String name) {
        File source = new File(baseDir, name);
        if (source.isFile()) {
            return source;
        } else {
            return null;
        }
    }

    @Override
    public long getLastModified(Object templateSource) {
        if (templateSource instanceof File) {
            return new Long(((File) templateSource).lastModified());
        } else {
            throw new IllegalArgumentException("templateSource is an unknown type: " + templateSource.getClass());
        }
    }

    @Override
    public Reader getReader(Object templateSource, String encoding) throws IOException {
        if (templateSource instanceof File) {
            return new InputStreamReader(new FileInputStream((File) templateSource), encoding);
        } else {
            throw new IllegalArgumentException("templateSource is an unknown type: " + templateSource.getClass());
        }
    }

    @Override
    public void closeTemplateSource(Object templateSource) {
        // noop
    }

    @Required
    public void setBaseDir(File baseDir) {
        this.baseDir = baseDir;
        // it may not exist yet because CMS is going to download and create it
    }
}
于 2013-06-10T22:03:48.703 に答える