Problems, need help? Have a tip or advice? Post it here.
10 posts Page 1 of 1
My website has a login system which I wrote in PHP and has some sections managed by couchCMS. Every webpage of my website has this code:
Code: Select all
<?php include "header.php" ?>

Pages managed by couchCMS are not an exception.
Then goes this line:
Code: Select all
<?php require_once( 'couch/cms.php' ); ?>


header.php includes tags persistent throughout all pages. It shows user's avatar and some other info, detects user languages for gettext.
Also header.php has this line:
Code: Select all
<?PHP if (isset($title)) { ?>
<title><?= _($title) ?> - Plan Z Online</title>
<?PHP } ?>

(<?= is a shorthand for <?PHP echo)
If I place couch/cms.php above header.php, the header contents will be cached by couchCMS and will not be personalized. I have got separate login system specifically and thoroughly designed for the website, and I have no intention to have couch managed logins for all of my users.

So I created a template for couchCMS-enabled zone of the website and everything was fine and dandy until I realized, that I have to put <title> tag into the <body> tag, which might break SEO.
The reason behind that is because couchCMS does its thing after all PHP is executed and my <head> tag belongs to header.php, so modifying $title does nothing.
So, now I have this line inside my <body> tag in couchCMS-enabled pages:
Code: Select all
<title><cms:show k_page_title /></title>

Of course I can use javascript to move <title> from <body> to <head>, but I think it's beyond bad idea.

So the question is, how do I move the <title> tag into <head>, while having header.php not being cached by couchCMS?

UPDATE:
Since I'm using html5 and don't care about IE6-8, I've removed <head> and <body> tags completely and the title tag is generated like this:
Code: Select all
<?PHP if (isset($title)) { ?>
<title><?= _($title) ?> - Plan Z Online</title>
<?PHP } else { ?>
<?PHP require_once( 'couch/cms.php' ); ?>
<title><cms:show k_page_title /> - <cms:show k_template_title /> - Plan Z Online</title>
<?PHP } ?>


If I move this code AFTER a <div> which shows user's avatar and some other info, my page still does not validate, because I suppose the <title> tag is expected to be set before any content set for output.
Please tell me that something still can be done without modifying CouchCMS's caching subsystem.
Hi :)

Allow me to begin with a caveat - Couch has been designed to be used with static sites.
If you try and use it with an existing PHP managed site, things might or might not work - all bets are off.

That said, it seems in your case you have managed to get it to co-exist with existing PHP code :)
From what I could gather, if you could move <?php require_once( 'couch/cms.php' ); ?> to be the very first line of the page (which, incidentally, is the only place where Couch expects it to be), things can work except that 'cache' issue that you mentioned.

Could you please elaborate on that caching point? I don't think I get it completely.
Is it the caching done by Couch when you turn on caching from couch/config.php or did you mean something else?
Please give me some concrete examples of the problem that you notice with this approach.

Also, if you could zip up the actual header file (and some of the files it calls) and get me an actual template where Couch is also used, I'll try to duplicate things on my system and see if a solution could be found.

Thanks.
Greetings!
Thank you for looking this up for me.
I've uploaded a part of my website, namely the template, header and footer.

The problematic section of the header is <div class='cblock' id="headerWrapper">, which is different for every user and for non-registered users.
Like here the amount of coins, points and new messages is reflected:
Code: Select all
            
<a href="/messages.php" title="<?= _("Личные сообщения") ?>" class="lightbutton"><img class="icon" src="/img/mail.png" /><span id="new_messages"><?= $_SESSION['new_messages'] ?></span></a>
            <a href="/balance.php" title="<?= _("Баланс") ?>" class="lightbutton"><img class="icon" src="/img/coin.png" /><span id="coins"><?= $_SESSION['coins'] ?></span></a>
            <a href="/ratings.php" title="<?= _("Очки") ?>" class="lightbutton"><img class="icon" src="/img/star.png" /><span id="points"><?= $_SESSION['points'] ?></span></a>
            <a href="/php/authorize.php?logout&from=<?= $_SERVER['REQUEST_URI']; ?>" class="lightbutton" /><img class="icon" src="/img/exit.png" /><span><?= "Выход" ?></span></a>


Now when this thing is saved into couch/cache folder on the server, then ALL OTHER USERS WILL SEE THE DATA OF THE FIRST USER, AFTER WHOM THE FILE WAS CACHED.
For example, I've uploaded a .dat file from cache and it's clear that the amount of 40 coins is cached alongside with everything else. If the user spends coins, he/she and other users will still see 40 coins on CouchCMS-enabled pages.
The possible solution would be to require couch.php AFTER <div id="headerWrapper> section, which I intended to do, but the problem is the <title> tag which should go into the beginning.
Turning the CouchCMS cache off completely is not a good solution, because otherwise the pages are completely static - it's the theoretical material for lessons, there won't even be a comments section.

Attachments

Thanks.

It is quitting time for me here. Will definitely study the problem when I get back.
That's great!

In my opinion, the best solution would be a tag, which would prevent server-side caching by CouchCMS of anything inside of it, like:
Code: Select all
<cms:nocache>
<a href="/messages.php" title="<?= _("Messages") ?>" class="lightbutton"><img class="icon" src="/img/mail.png" /><span id="new_messages"><?= $_SESSION['new_messages'] ?></span></a>
            <a href="/balance.php" title="<?= _("Balance") ?>" class="lightbutton"><img class="icon" src="/img/coin.png" /><span id="coins"><?= $_SESSION['coins'] ?></span></a>
            <a href="/ratings.php" title="<?= _("Score") ?>" class="lightbutton"><img class="icon" src="/img/star.png" /><span id="points"><?= $_SESSION['points'] ?></span></a>
</cms:nocache>


Upon looking into CouchCMS code I can assumpt that instead of splitting the cached document into chunks it might be easier to explicitly note which exact part of the document would be handled by CouchCMS, so that it does not cache header and footer.
Hi,

Ok, so I studied your code quite carefully.
To begin with, I'll have to say that you are trying to use Couch in a very unique manner :)

By moving <?PHP require_once( 'couch/cms.php' ); ?> down the template (instead of the usual top of the file) you are effectively dividing the code in two portions - the PHP code above the statement always gets executed (and hence is always dynamic) while the code managed by Couch (i.e. that falls after the statement) gets cached after the first run.

I haven't seen anyone do that before :)

Anyway, you have already seen the problem with this approach. The output cached by Couch is nothing more than a static HTML file. Couch simply reads that and outputs it verbatim. So we cannot put any kind of dynamic values in it e.g. the title you mentioned.

By the way, speaking of the title, if I am not wrong it is only one of the several things that are getting affected by the caching. For example, the Couch managed code has several lines e.g.
<a href="/messages.php" title="<?= _("Личные сообщения") ?>" ..
<a href="/balance.php" title="<?= _("Баланс") ?>"

where the _() is meant to dynamically translate the strings. But, I think, because of the cache these values will always remain what the first visitor got.

So, in my opinion, the best way to handle this issue is to forgo the caching part of Couch. Use Couch without caching on and things should be fine.

In any case, unless your site is getting some serious amount of traffic, not using Couch cache should not have a whale of a difference in the site's performance. Couch's demands are pretty frugal and you can use it dynamically.

Hope it helps.
The main reason I chose Couch because it allowed me to separate CMS-powered content from non-CMS content.
Is it technically possible to make a tag, which would separate caching content from non-caching content? I've already achieved that, but non-caching content also cannot be used by Couch.
The only thing which stops me from going further with my Couch-powered development is the <title> tag, which should go into the <head> section, but still be managed by Couch.
I'm terribly sorry, @eklipse2009, but as I already said mixing existing PHP code with Couch is a tricky thing. I think what you want would need modifying Couch's core code that handles caching (couch/header.php).

I apologize but I won't be able to help you with that. Couch's source is open, though, and you are welcome to tweak away as much as you want.

Thanks.
Thank your for the hint!
I've modified couch/header.php and my own header.php, here's how:

In my header.php I've wrapped the dynamic area with a pseudo-tag:

Code: Select all
<!--no-cache-->
<?PHP include('no-cache-section.php'); ?>
<!--no-cache-->


the 'no-cache-section.php' contains those dynamic lines:
Code: Select all
<?PHP if (isset($_SESSION['user_id'])) { ?>
<a href="/profile.php" id="avatarWrapper"><img src="<?= $_SESSION['avatar'] ?>" id="smallAvatar"/></a>
<div id="upperPanel">
   <a href="/messages.php" title="<?= _("Личные сообщения") ?>" class="lightbutton"><img class="icon" src="/img/mail.png" /><span id="new_messages"><?= $_SESSION['new_messages'] ?></span></a>
   <a href="/balance.php" title="<?= _("Баланс") ?>" class="lightbutton"><img class="icon" src="/img/coin.png" /><span id="coins"><?= $_SESSION['coins'] ?></span></a>
   <a href="/ratings.php" title="<?= _("Очки") ?>" class="lightbutton"><img class="icon" src="/img/star.png" /><span id="points"><?= $_SESSION['points'] ?></span></a>
   <a href="/php/authorize.php?logout&from=<?= $_SERVER['REQUEST_URI']; ?>" class="lightbutton" /><img class="icon" src="/img/exit.png" /><span><?= "Выход" ?></span></a>
</div>
<?php } else { ?>
<div id="upperPanel">
   <a href="/login.php?from=<?= isset($_GET['from']) ? $_GET['from'] : $_SERVER['REQUEST_URI']; ?>" class="lightbutton"><span><?= _("Вход") ?></span></a>
   <a href="/newuser.php" class="lightbutton"><span><?= _("Регистрация") ?></span></a>
</div>
<?PHP } ?>


Then here is how it's handled in couch/header.php (line 100 and further):
Code: Select all
                        $pg = @unserialize( file_get_contents($k_cache_file) );
                        if( $pg ){
                            if( $pg['redirect_url'] ) {
                                header( "Location: ".$pg['redirect_url'], TRUE, 301 );
                                die();
                            } else {
                                $html = $pg['cached_html'];
                                $mime_type = $pg['mime_type'];
                                $res_404 = $pg['res_404'];
                                if( strlen(trim($html)) ){
                                    if( $res_404 ){
                                        header('HTTP/1.1 404 Not Found');
                                        header('Status: 404 Not Found');
                                    }
                                    header( $mime_type );
//MY MODIFICATION BEGINS HERE
                                    $html_array = explode('<!--no-cache-->', $html);
                                    echo $html_array[0];
                                    include(K_COUCH_DIR.'../no-cache-section.php');
                                    echo $html_array[2];
//MY MODIFICATION ENDS HERE
                                    echo 'Cached copy: ' . k_timer_stop();
                                    flush();


Of course this will not work if <!--no-cache--> section is not present, but for now this quick fix is more than enough for the current website.

This will save 30ms of server time and 20 MySQL queries with every request, so I think this tiny modification is pretty much worth it.
Thank you for sharing your solution with us.
I'll definitely study it closely to see if we can incorporate the idea in the core.

Thanks.
10 posts Page 1 of 1
cron