I have a very dynamic (social networking) site running smarty that I want to enable caching for.
My Structure:
index.php display()s template.tpl
template.tpl include()s indexContent.tpl
Most of the content in template.tpl is static .. such as the scripts, banner, footer.. etc. How can I cache that but not specific parts which look different to depending on whose logged in (among other factors)?
I've discovered 3 methods:
{nocache} {include='indexContent.tpl'} {nocache}
{dynamic} {include ...
Set the cache_id for each page.
Unfortunately each has a problem:
Doesn't really seem to work? Dynamic content still gets cached..
Not sure how to implement or how it's different than (1)
How to identify uniquely? Some pages have the same "name" but different content for specific members... think "myProfile.php"
Any suggestions? Thanks!!
You can use reverse proxy, like Varnish to cache the static part of the page and to include your dynamic content as Server-Side Includes (for Varnishi it is ESI). Next you will need to setup the caching rules for your static and dynamic URLs so that the static one will be cached for a long time period while the dynamic one will not be cached at all.
To make it easier to understand the whole idea here is how your page HTML code could look like:
<html>
<head>...</head>
<body>
...some static layout...
<esi:include src="/esi/indexContent.php"/>
...some another static layout...
</body>
</html>
Where /esi/indexContent.php is the script that generates the dynamic content.
For Varnish: beware of the gzipped or deflated content with ESIs as it is described in the answer here
We have the same scenario. Our entire front page is cached except for a couple of dynamic elements (news, latest forum threads) and the easiest way I found to get around this is to add in a keyword to the cached template
NEWS_BLOCK
on your logic script you then load your news template and preg_replace it with the keyword.
$news_template = $smarty->fetch('news_template.smrt');
$page_body_raw = $smarty->fetch('frontpage.smrt');
$page_body = preg_replace('/NEWS_BLOCK/', $news_template, $page_body_raw);
in 3 way u can save cache file by this name:
myprofile_id for example a persone that registered and his id is 455 in user table u can save cache file for he with this name myprofile_455
after that u can include cached file in tpl file like this:
{include file="cache/myprofile`$smarty.get.userid`.html"}
I know the question is old my i am still proposing a solution to help someone else.
I seem to get into same trouble with a social networking site i am developing. Here is the solution that worked for me
Doesn't really seem to work? Dynamic content still gets cached..
Not sure how to implement or how it's different than (1)
Just remove the static part of your page like footer and header and put them in a different tpl file. Then include the tpl file as
{include file='head.html' cache_lifetime=5000}
or conversely remove the dynamic part of your page and put it in another template and include it as
{include file='head.html' nocache}
3.How to identify uniquely? Some pages have the same "name" but different content for specific members... think "myProfile.php"
for same page with different content like a profile page, you can pass profile Id as a parameter to cache call.
$my_cache_id = $_GET['profile_id'];
$smarty->display('index.tpl', $my_cache_id);
This will ensure that same page with different parameters are not treated as same page.
Hope this helps.
Related
I'm certain I can use PHP to accomplish this task, but I'm not sure how.
What I currently have is a faux news (ha ha ho ho) site for practise here.
http://puu.sh/402Rl.png
For Browse News, I would like all html documents within a specified folder to be shown in the format I have
SAMPLE
<p class="content centeralign">
8.12.13 <!-- ARTICLE NAME -->
</p>
<hr noshade></hr>
Although it's not much, setting up a way to do this automatically would save some time.
Here is how I would imagine the logistics behind this would function ----
All HTML files will be listed in a folder
They will all have a consecutive order based on the date they were created (e.g. 1.html, 2.html, 3.html etc.
PHP would find each document and add it in the right order
A bit inside the file would define the title (meta tags?)
That seems a really bad way of doing it, but anyway.. You want to be you want to be using the directory functions. Specifically http://www.php.net/manual/en/function.readdir.php
A good idea would be to set up a MySQL system for this, but it is achieveable with PHP only.
You could get all .html files in the folder with glob, and then include them with this code:
foreach (glob("/htmlfiles/*.{htm, html}") as $filename) {
include "$filename";
}
The nice thing about this, is that it's sorted alphabetically and numerically too.
Edit: You would then use this system twice, with two folders, one for the meta tags/title, and one for the page itself. Again, not the best way to do it. You should really check out a CMS.
If you used MYSQL, you can still get all html files from the folders as you are now, but just use MYSQL to make simple basic references, such as the filename, date, category, etc. Then you don't need to use complex (and likely failing) file and directory code to determine when a file was created and which order to serve them in. The DATE in your MYSQL would be when to serve them.
To answer your meta questions, I would have a header.php file with all the meta data in for the site (doc declaration, titles, css links, etc) and then each individual file could have a variable to pass to the header when it's included.
eg
File: about.php
$PageTitle = 'About';
include_once('header.php');
<some more code>
<h1>$PageTitle</h1>
File: 1.php
$PageTitle = 'News about something';
include_once('header.php');
<some more code>
<h1>$PageTitle</h1>
File: header.php
usual code, doc declaration, head, etc
<title>$PageTitle</title>
So at the start of each file you declare what the title will be then include header.php. The title is used on the meta title (so your browser and tab etc) and the var in the file can also be used on headers (ie h1, h2) and links if needed.
you could do all this without MYSQL still, but using a database to even just reference things like date_of_creation - last_update_date - author, etc, could save you headaches, but is up to you how you want to do it and what skills you have etc.
I need one advice from you. I am working on a website, which uses PHP and HTML. As the biggest part of the header and footer code will be same for many pages, I am thinking of using PHP's include to avoid code duplication. But, each of those pages requires different stylesheets and JS files included. What do you think how could I let the other file know what scripts and stylesheet to import?
Our company does this:
The header reads the filename of the page calling it when it's included.
Then, it changes the extension to '.js' and outputs that if it exists. Same for CSS.
So if I have a page "register.php", it will auto-include "register.js" and "register.css" if they exist.
Here's what I do:
<?php include("includes/headContent.php"); ?>
<title>Page title goes here!</title>
<script src="script_only_used_on_this_page"></script>
<?php
require_once("includes/siteHeader.php");
?>
Site Content Goes Here!!
<?php
require_once("includes/siteFooter.php");
?>
Head Content includes any PHP I want included in every page, as well as the opening html and head tag, and any Javascript libraries and css stylesheets I want on every page. Site header closes the /head tag, and opens the body as well as printing out my site header and some other markup that goes on every page. Finally Site Footer closes out my template. Everything in between is my content area!
There are lots of different ways you can do templating, if you wanted to create a simple include and an echoHeader() and an echoFooter() function... just have the echoHeader function accept a parameter which you would pass your javascript and CSS lines to.
you can use MVC coding pattern
We need to display the content of one single TYPO3 page in Habari.
It would suffice to retrieve the HTML, as styling (CSS) is done separatly.
However, we only want the HTML of the content elements - not the whole, fully rendered page.
How could we achieve that?
Does TYPO3 (or one of its plugins) provide a facility for that?
This can be done via a custom Typoscript template-record in the Typo3 backend that just outputs the content without any further HTML and or tags.
Putting something like this in the 'setup':
page = PAGE
page.config.disableAllHeaderCode = 1
page.10 < styles.content.get
Then make sure in the template-record it say's that it's a root-template, and that it clears constants and setup before this template. And put this record on the top most page (aka root).
Also make sure that you included the static template of CSS Styled Content. This can be done when editing the template-record inside Typo3.
You could do this in Habari using something like this:
$url = "http://your-typo3-url/";
$output = RemoteRequest::get_contents( $url );
$output will then be the HTML contents of the page. You can then use a combination of strpos() and substr() to pull the relevant HTML content you want, eg just the <body>
You can do this in one of your theme template files, the theme's theme.php file itself or even within a plugin.
You can then use Habari's native caching to cache the content too so you don't have to retrieve the Typo3 page with every page view.
BTW, You could use typo3_webservice fro that. It uses XMLRPC protocol, and quite easy to implement with PHP.
http://typo3.org/extensions/repository/view/typo3_webservice/current/
Whenever I start a new project I find myself remaking and rethinking my self made template library. I use some influences from dom manipulation, but don't want to make too much functions so that it still loads fast.
This is how my current template system looks like:
This is a layout file:
<body>
<div id="content">
<block:content>This is a default text</block:content>
</div>
<div id="sidebar">
<widget:advertisement type="wide" />
<block:sidebar this_param="is_passed_on" />
</div>
</body>
As you can see I made 2 sort of "extra" tags that will be replaced when eventually publishing the template. I load this layout like this:
$this->template->load("layout");
I then can manipulate the block tags like this:
$this->template->content = "I'm overwriting the default text";
$this->template->content->prepend("I forgot something");
$this->template->sidebar->view("viewfile_1", array(/*data*/));
$this->template->sidebar->view("viewfile_2", array(/*data*/));
I can set text manually, I can load multiple views into 1 block, I can use a few dom-like manipulating functions like prepend, append, ...
I can even extend the template with more layout options like:
$this->template->content->extend("2columns");
This layout file might look like:
<div><block:left/></div>
<div><block:right/></div>
So that instead of the content block I now have an extra left and right block to put content in.
I have also created a widget tag that loads the specific widget class (/widgets/advertisement in this case). The optional parameters added in the tags are passed on to the views files and/or widget display function together with the direct passed data array.
In short, this is how my system now works. I haven't really found other systems like this to get inspiration from. Could you guys give me advice on anything so I can put together one decent system that I can keep using?
My approach is:
Create main layouts for each page type on a layouts/ folder (think Wordpress layouts for home, archive, single post, single page)
Create common bits of interface in a common/ folder (think header, footer, sidebar, widget_XX, widget_YY)
Use Phil Sturgeon's Template Library (or Spark!) to handle the views.
On each controller I load all the data needed for rendering in $this->data and I pass that object to the view
Hope this helps! Good luck.
If jquery is added in globally used header.php across the site then How to stop to load jquery library only for those pages of site which doesn't need actually? If we can't use more than one header.
purpose of question is to not to penalize those page with slow loading which actually don't need.
Your site shouldn't need more than one global-header, if you opt to even use headers to begin with. If it does, just include jQuery on all pages. It's a small cached file, it won't hurt the browsing experience.
By using the google-hosted version, it may be the case that many of your uses already have it cached before they even reach your site.
I have been guilty of pounding my fist into the nail while asking everyone else to move the hammer that's in the way...
Why not tackle the problem from the other end and use jQuery to optimize the first load?
If you have big pages that are already taking a while to download, why not section off the less-performant areas and use $().load() to fill those in?
The page will load quicker (better user experience) and you don't have to be adding any additional processing to pages that don't need it.
Cheers,
-jc
assuming you are loading the jQuery file from a correctly-configured webserver (or from google's CDN), it will be cached and not re-downloaded on each page. Assuming a visitor will hit at least one page on your site that needs jQuery then you really won't gain anything by trying to remove it from loading on pages that don't use any javascript features from the library.
First, use the compressed jquery for production. It's much smaller. Second, IIRC, once jquery is downloaded with the first page, it will be cached and won't need to be retrieved from your server for each subsequent request.
Otherwise, if you really need to explicitly load jquery only on those pages that need it, you would have to have some way for the body of your page to tell header.php that it doesn't need to load jquery. If header.php is loaded before "body.php" then that's pretty hard to do without some fancy output buffering or such.
If you're using a templating system like Smarty you could have a conditional in the master page template to check a $loadjquery flag that you set in body.php before sending the whole page off to be rendered. But that's complicated too.
Your question is very general, some specific would be great, maybe even a link to the site. Personally if you are using a CMS I would try to make some sort of "flag" for that page, or if you are simply loading a page and then loading the header from that page, insert a variable before you load the header and use that as your flag for loading jQuery.
An example:
If a user wants to see www.mysite.com then the following file would be loaded: www.mysite.com/index.php with the following code:
<?php $needJQuery = true;
include('header.php');
echo 'content will go here';
include('footer.php'); ?>
header.php would include something such as this:
<?php if ($needJQuery) { ?>
<script src="/jquery/jquery-min-3.2.1.js" />
etc. for all the content that you need above/below.
<?php } ?>
For the pages that don't need jQuery loaded, you would either leave $needJQuery undefined or you would do as follows:
<?php $needJQuery = false; ?>
Hope this helps,
As stated earlier, modify the header file so it'll check for the presence of flag variable and only output the jquery headers if needed.
If you don't have the ability to modify the header file, you could load it with output buffering turned on and filter the output before it heads out to the client:
<?php
ob_start();
include('header.php');
$header = ob_get_flush();
$cleanheader = some_operation_that_removes_the_jquery_script_tags($header);
echo $cleanheader
?>