S
S
StopDesign2011-04-02 15:55:10
Nginx
StopDesign, 2011-04-02 15:55:10

Nginx, SSI and using variables

I use SSI in Nginx and love it. But there's a problem.


Given


There is a page that can be cached almost completely for an hour. You need to embed a block with a random picture in it. The page title () depends on the image.


Decision


The backend gives out a separate page /page/ and a random block /random/. A random block is cunningly cached for 30 seconds, and a page is simply cached for an hour. Next, Nginx.SSI inserts the block into the page.


Problem


I don't know how to insert the title into the page. The title text is the name of a random image. It's inserted inside the body, so the variables I set inside /random/ are not yet initialized when the title is printed.

I figured out how to get around the problem:

random.html

    <!--# set var="title" value="blah blah" -->
    <img src="bla-bla.jpg" />


page.html

    <!-- HTML comment
        <!--# include virtual="/random/?$args" wait="yes" -->
    -->
    <head>
        <title><!--# echo var="title" encoding="none" default="no title" --></title>
    </head>
    <body>
        ....
        <!--# include virtual="/random/?$args" -->
    </body>


You can see that the /random/ block is included twice in the page. This is bad, because in fact the block contains not only the image, but also a decent amount of layout, which depends on the image. All this code is duplicated on the page and eats my traffic .

Obviously, one could store the code returned by the first call in a variable and then insert the value of that variable into the page.

page.html

    <!-- HTML comment
        <!--# include virtual="/random/?$args" wait="yes" set="random_html" -->
    -->
    <head>
        <title><!--# echo var="title" encoding="none" default="no title" --></title>
    </head>
    <body>
        ....
        <!--# echo var="random_html" encoding="none" default="" -->
    </body>


But in this case (if you use the set parameter of the include directive), the values ​​of the variables set inside /random/ are not transferred to /page/ - the title is empty. I suspect this is an annoying bug. I'll write to the developer about it. True, I don’t know where exactly ...

You can put the layout in a separate variable, but there will be problems with escaping all sorts of $ and something else.

I also tried to make a replacement using sub_filter, but it apparently runs before SSI and does not see the variables there.


Attention, question


How to do all this in one include?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
D
Dmitry Dedukhin, 2011-04-02
@Demetros

Your variant with two variables in my opinion is the only possible one.
But to store large chunks of text in SSI variables, you need to use the undocumented ssi_value_length directive, which is 256 bytes by default, and this is most likely not enough to store your html code (there should be messages about this in the error log):

location /random/ {
  ...
  ssi_value_length 32k;
}

V
Vitaly Peretyatko, 2011-04-18
@viperet

there in nginx in ssi there is a parameter that allows you to assign the result of include to a variable. do this at the beginning of the page, get a variable with the image code and change it with the title. insert them where necessary in the page and it's done

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question