=UseCache, config=ConfigProps}}.
    
allowed_methods(ReqData, State) ->
    {['HEAD', 'GET'], ReqData, State}.

resource_exists(ReqData, State) ->
    {ReqData1, State1} = check_resource(ReqData, State),
    case State1#state.fullpath of
        false -> {false, ReqData1, State1};
        redir -> {false, ReqData1, State1};
        _ -> {true, ReqData1, State1}
    end.


previously_existed(ReqData, #state{fullpath=redir} = State) ->
	{true, ReqData, State};
previously_existed(ReqData, State) ->
	{false, ReqData, State}.

moved_temporarily(ReqData, #state{fullpath=redir} = State) ->
    Location = case mochiweb_util:unquote(wrq:path(ReqData)) of 
        [] -> "/";
        [$/ | Path] -> [$/ | mochiweb_util:safe_relative_path(Path)] ++ "/"
    end,
	{{true, z_context:abs_url(Location, State#state.context)}, ReqData, State}.

content_types_provided(ReqData, State) ->
    {ReqData1, State1} = check_resource(ReqData, State),
    case State1#state.mime of
        undefined ->
            CT = z_media_identify:guess_mime(filename:basename(State1#state.fullpath, ".tpl")),
            {[{CT, provide_content}], ReqData1, State1#state{mime=CT}};
        Mime -> 
            {[{Mime, provide_content}], ReqData1, State1}
    end.

encodings_provided(ReqData, State) ->
    {ReqData1, State1} = check_resource(ReqData, State),
    Encodings = case filename:extension(State1#state.fullpath) of
        ".tpl" ->
            [{"identity", fun(Data) -> decode_data(identity, Data) end}];
        _ ->
            case State#state.mime of
                "image/"++_ ->
                    [{"identity", fun(Data) -> decode_data(identity, Data) end}];
                _ -> 
                    [{"identity", fun(Data) -> decode_data(identity, Data) end},
                     {"gzip",     fun(Data) -> decode_data(gzip, Data) end}]
            end
    end,
    EncodeData = length(Encodings) > 1,
    {Encodings, ReqData1, State1#state{encode_data=EncodeData}}.


charsets_provided(ReqData, State) ->
    case is_text(State#state.mime) of
        true -> {[{"utf-8", fun(X) -> X end}], ReqData, State};
        _ -> {no_charset, ReqData, State}
    end.
    
last_modified(ReqData, State) ->
    {ReqData1, State1} = check_resource(ReqData, State),
    case filename:extension(State1#state.fullpath) of
        ".tpl" -> 
            NowSecs = calendar:datetime_to_gregorian_seconds(calendar:universal_time()),
            {calendar:gregorian_seconds_to_datetime(NowSecs - 86400), ReqData1, State1};
        _ ->
            RD1 = wrq:set_resp_header("Cache-Control", "public, max-age="++integer_to_list(?MAX_AGE), ReqData1),
            case State#state.last_modified of
                undefined -> 
                    LMod = filelib:last_modified(State#state.fullpath),
        			[LModUTC|_] = calendar:local_time_to_universal_time_dst(LMod),
                    {LModUTC, RD1, State1#state{last_modified=LModUTC}};
                LModUTC ->
                    {LModUTC, RD1, State1}
            end
    end.

expires(ReqData, State) ->
    {ReqData1, State1} = check_resource(ReqData, State),
    MaxAge = case filename:extension(State1#state.fullpath) of
        ".tpl" -> -86400;
        _ ->?MAX_AGE
    end,
    NowSecs = calendar:datetime_to_gregorian_seconds(calendar:universal_time()),
    {calendar:gregorian_seconds_to_datetime(NowSecs + MaxAge), ReqData1, State1}.

provide_content(ReqData, State) ->
    case State#state.body of
        undefined ->
            FullPath = State#state.fullpath,
            case filename:extension(FullPath) of
                ".tpl" -> 
                    %% Render template, prevent caching
                    Context = z_context:set_reqdata(ReqData, State#state.context),
                    Context1 = z_context:ensure_all(Context),
                    Html = z_template:render(FullPath, State#state.config, Context1),
                    {Html1, Context2} = z_context:output(Html, Context1),
                    ReqData1 = z_context:get_reqdata(Context2),
                    State1 = State#state{context=Context2, use_cache=false, encode_data=false},
                    {iolist_to_binary(Html1), ReqData1, State1};
                _ -> 
                    %% Fetch file, allow caching
                    file:read_file(FullPath),
                    {ok, Data} = file:read_file(State#state.fullpath),
                    Body = case State#state.encode_data of 
                        true -> encode_data(Data);
                        false -> Data
                    end,
                    {Body, ReqData, State#state{body=Body}}
            end;
        Body ->
            {Body, ReqData, State}
    end.

    
finish_request(ReqData, State) ->
    case State#state.is_cached of
        false ->
            case State#state.body of
                undefined ->  
                    {ok, ReqData, State};
                _ ->
                    case State#state.use_cache andalso State#state.encode_data of
                        true ->
                            % Cache the served file in the depcache.  Cache it for 3600 secs.
                            Cache = #cache{
                                        path=State#state.path,
                                        fullpath=State#state.fullpath,
                                        mime=State#state.mime,
                                        last_modified=State#state.last_modified,
                                        body=State#state.body
                                    },
                            Context = z_context:new(ReqData,?MODULE),
                            z_depcache:set(cache_key(State#state.path), Cache, Context),
                            {ok, ReqData, State};
                        _ ->
                            % No cache or no gzip'ed version (file system cache is fast enough for static file serving)
                            {ok, ReqData, State}
                    end
            end;
        true ->
            {ok, ReqData, State}
    end.


%%%%%%%%%%%%%% Helper functions %%%%%%%%%%%%%%
    
cache_key(Path) ->
    {resource_static_pages, Path}.

check_resource(ReqData, #state{fullpath=undefined} = State) ->
    Context = z_context:set_noindex_header(z_context:new(ReqData,?MODULE)),
    case mochiweb_util:safe_relative_path(mochiweb_util:unquote(wrq:disp_path(ReqData))) of
        undefined ->
            {error, enoent};
        SafePath ->
            Cached = case State#state.use_cache of
                true -> z_depcache:get(cache_key(SafePath), Context);
                _    -> undefined
            end,
            case Cached of
                undefined ->
                    case find_file(State#state.root, SafePath, Context) of 
                    	{ok, FullPath} -> 
            	            case filename:basename(FullPath, ".tpl") of
            	                "index.html" ->
            	                    case last(wrq:path(ReqData)) /= $/ andalso filename:basename(SafePath) /= "index.html" of
            	                        true ->
                            	            {ReqData, State#state{path=