Custom meta tag configuration - symfony1

I have 2 tables, page and settings.
page is just a bunch of fields, such as name and slug, and has 3 other fields for meta tags (title, keywords, description) and displays a cms page.
The settings has 3 fields: default_meta_title, default_meta_keywords, default_meta_description
Now what I'm looking to do is to display the default_meta_* tags in the HTML source if the page I am on does not have the particular meta info set from the cms page.
All pages, except the homepage is managed this way, so I was thinking I'd need to add some code to the layout.php to get this to work.
So the homepage will display my default_meta_*, as I cannot set this in the cms pages table.

There are two ways to solve the problem.
First is to use sfYaml class to update view.yml with default meta tags (see documentation about view.yml). After that if specific page should use another metas you can override defaults with addMeta method of response object
Second (as ManseUK suggested) is to declare slot placing code like this into layout
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<?php include_javascripts() ?>
<?php include_stylesheets() ?>
<?php include_title() ?>
<?php if (has_slot('metas')): ?>
<?php include_slot('metas') ?>
<?php else: ?>
<?php include_component('page', 'metas') ?>
<?php endif; ?>
<link rel="shortcut icon" href="/favicon.ico" />
</head>
<body>
Default metas will be rendered via page components. On top of your template (i guess modules/page/templates/showSuccess.php) place code
<?php slot('metas') ?>
<?php if($page->hasMetas()):?>
<!-- code to render nondefault page metas -->
<?php echo $page->getMetas(); ?>
<?php else: ?>
<?php include_component('page', 'metas') ?>
<?php endif;?>
<?php end_slot() ?>
I assume that you will replace $page->hasMetas() with real code that will check if your page object has metatags.
Actually i would prefer to go further and code page components to accept parameters. Code in a template will look like
<?php slot('metas') ?>
<?php include_component('page', 'metas', array('metas'=>$page->getMetas())) ?>
<?php end_slot() ?>
Deciding which metas (default or not) should be rendered will take place in page components (i assume that you can easily retrieve defaul;t settings from your database). If no parameters were passed (see layout code) than your component should also render default metas.
I hope this will help.

You could use a slot - check for existence of the slot in the layout - if it exists then add the custom meta fields - if not add the default ones

Related

schema.org Failing to Validate Dublin Core Meta in 'meta' and 'link' elements

I have Dublin Core (DC) meta data in <meta ...> and <link...> elements. Testing my html document with the validator fails to identify the dublin core meta data in my document. But when using DC tags in elemetns like <td rel="dc:date" content="2017-02-10">10 February 2017 </td> the validator identifies those meta data elements.
This validator also fails to identify DC tags in meta and link elements.
Example that does not validate but should:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head profile="http://dublincore.org/specifications/dublin-core/dc-html/2008-08-04/">
<title>Services to Government</title>
<link rel="schema.DC" href="http://example.org/terms/" />
<meta name="DC.date" content="2007-05-05" />
</head>
<body>
</body>
</html>
Is the meta data invalid or are the validators in the wrong? Is there a validator that will support <meta > and <link>?
it seems like the prefix:
#prefix dc: http://purl.org/dc/elements/1.1/ .
is not appearing the the validator results for some reason.
I have tried adding additional vocabulaires like:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head profile="http://dublincore.org/specifications/dublin-core/dc-html/2008-08-04/">
<title>Services to Government</title>
<link rel="schema.DC" href="http://example.org/terms/" />
<link rel="schema.DC" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xmlns:v="http://rdf.data-vocabulary.org/#"/>
<meta name="DC.date" content="2007-05-05" />
</head>
<body>
<td rel="dc:date" content="2017-02-10">10 February 2017</td>
</body>
</html>
Without success.
To recreate, just paste the example html into one of the validators linked above.
Those examples are written with an obviously unsupported syntax.
So the validators are not suppose to detect it, as they support common syntax, such as RDFa, JSON-LD, Microdata etc.
Here's a quote that might be relevant:
The major search engines now extract and index metadata embedded with
one of several syntaxes: HTML Microdata, of limited expressivity but
the easiest for webmasters to deploy; RDFa, a richer syntax with
better support for internationalization and multiple RDF namespaces;
and JSON-LD, an RDF-compatible variant of the popular Javascript
Object Notation (JSON). These broadly supported syntaxes effectively
obsolete a series of IETF and DCMI syntax specifications developed
prior to 2008 specifically for expressing Dublin Core™ metadata.
https://www.dublincore.org/resources/metadata-basics/
Parsing those examples would require a parser for that specific syntax (there doesn't seem to be many out there..).
So the solution might be to use some of the common serializations (JSON-LD, Microdata, RDFa)

How do I set the culture before the layout renders in symfony 1.4?

I need to display a different logo image (in layout.php) based on the country from which the site is being browsed. Setting it in the action doesn't work, as the layout is rendered before preExecute() (or any other action) is called.
How would I set the culture before the layout is rendered and then call on this variable in layout.php?
You should read the user culture section of the docs. When you setup user culture properly, you can use $sf_user->getCulture() in templates and in the layout as well.
Note: #glerendegui is right the layout is rendered after the action and even after the template.
I don't think that's true. Layout is rendered after action is called. The example is that you can change de layout in the actions.class with $this->setLayout();
Anyway, I think that you can use one slot to solve your problem.
In layout:
<?php if(!has_slot('logo_image')) { ?>
<img src="<?php ... default logo;?>" />
<?php else { include_slot('logo_image'); } ?>
then, in your action template (f.e. indexSuccess)
<?php
slot('logo_image');
?><img src="<?php .... l10n image ?>" />
<?php end_slot(); ?>

Include .js files on my Drupal site

I want to use jQueryUI Autocomplete on my Drupal site and I downloaded the .js files that are needed for it to function. Now after that, I saved my .js files on my themes folder located at /sites/all/themes/advanced/js. And in my page.tpl.php there's this code,
<head>
<?php print $head ?>
<title><?php print $head_title ?></title>
<?php print $styles ?>
<?php print $scripts ?>
<?php print phptemplate_get_scripts(); ?>
<?php if ($user->uid) print phptemplate_get_scripts_advanced(); ?>
<!--[if lt IE 7]>
<?php print phptemplate_get_ie_styles(); ?>
<![endif]-->
</head>
with the code above I'm assuming that my .js files will be included but when I reloaded the page and check the running scripts through Firebug, I could not find them. What did I miss? Thanks in advance.
Got it. I did try to put my scripts manually on my template.php and that solved it. :)

Uncaught exception 'DOMException' with message 'Not Found Error'

Bascially I'm writing a templating system for my CMS and I want to have a modular structure which involves people putting in tags like:
<module name="news" /> or <include name="anotherTemplateFile" /> which I then want to find in my php and replace with dynamic html.
Someone on here pointed me towards DOMDocument, but I've already come across a problem.
I'm trying to find all <include /> tags in my template and replace them with some simple html. Here is my template code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>CMS</title>
<include name="head" />
</head>
<body>
<include name="header" />
<include name="content" />
<include name="footer" />
</body>
</html>
And here is my PHP:
$template = new DOMDocument();
$template->load("template/template.tpl");
foreach( $template->getElementsByTagName("include") as $include ) {
$element = '<input type="text" value="'.print_r($include, true).'" />';
$output = $template->createTextNode($element);
$template->replaceChild($output, $include);
}
echo $template->saveHTML();
Now, I get the fatal error Uncaught exception 'DOMException' with message 'Not Found Error'.
I've looked this up and it seems to be that because my <include /> tags aren't necessarily DIRECT children of $template its not replacing them.
How can I replace them independently of descent?
Thank you
Tom
EDIT
Basically I had a brainwave of sorts. If I do something like this for my PHP I see its trying to do what I want it to do:
$template = new DOMDocument();
$template->load("template/template.tpl");
foreach( $template->getElementsByTagName("include") as $include ) {
$element = '<input type="text" value="'.print_r($include, true).'" />';
$output = $template->createTextNode($element);
// this line is different:
$include->parentNode->replaceChild($output, $include);
}
echo $template->saveHTML();
However it only seems to change 1 occurence in the <body> of my HTML... when I have 3. :/
This is a problem with your DOMDocument->load, try
$template->loadHTMLFile("template/template.tpl");
But you may need to give it a .html extension.
this is looking for a html or an xml file. also, whenever you are using DOMDocument with html it is a good idea to use libxml_use_internal_errors(true); before the load call.
OKAY THIS WORKS:
foreach( $template->getElementsByTagName("include") as $include ) {
if ($include->hasAttributes()) {
$includes[] = $include;
}
//var_dump($includes);
}
foreach ($includes as $include) {
$include_name = $include->getAttribute("name");
$input = $template->createElement('input');
$type = $template->createAttribute('type');
$typeval = $template->createTextNode('text');
$type->appendChild($typeval);
$input->appendChild($type);
$name = $template->createAttribute('name');
$nameval = $template->createTextNode('the_name');
$name->appendChild($nameval);
$input->appendChild($name);
$value = $template->createAttribute('value');
$valueval = $template->createTextNode($include_name);
$value->appendChild($valueval);
$input->appendChild($value);
if ($include->getAttribute("name") == "head") {
$template->getElementsByTagName('head')->item(0)->replaceChild($input,$include);
}
else {
$template->getElementsByTagName("body")->item(0)->replaceChild($input,$include);
}
}
//$template->load($nht);
echo $template->saveHTML();
However it only seems to change 1 occurence in the of my HTML... when I have 3. :/
DOM NodeLists are ‘live’: when you remove an <include> element from the document (by replacing it), it disappears from the list. Conversely if you add a new <include> into the document, it will appear in your list.
You might expect this for a NodeList that comes from an element's childNodes, but the same is true of NodeLists that are returned getElementsByTagName. It's part of the W3C DOM standard and occurs in web browsers' DOMs as well as PHP's DOMDocument.
So what you have here is a destructive iteration. Remove the first <include> (item 0 in the list) and the second <include>, previously item 1, become the new item 0. Now when you move on to the next item in the list, item 1 is what used to be item 2, causing you to only look at half the items.
PHP's foreach loop looks like it might protect you from that, but actually under the covers it's doing exactly the same as a traditional indexed for loop.
I'd try to avoid creating a new templating language for PHP; there are already so many, not to mention PHP itself. Creating one out of DOMDocument is also going to be especially slow.
eta: In general regex replace would be faster, assuming a simple match pattern that doesn't introduce loads of backtracking. However if you are wedded to an XML syntax, regex isn't very good at parsing that. But what are you attempting to do, that can't already be done with PHP?
<?php function write_header() { ?>
<p>This is the header bit!</p>
<? } ?>
<body>
...
<?php write_header(); ?>
...
</body>

$sf_response->addStyleSheet() dosen't work in SF 1.4?

Does anyone know how to add stylesheets in a template with Symfony 1.4 ?
I have tried everything I can think of, from modifying frontend/config/view.yml to modifying the template itself - bothing works.
I have seen from my searches, that other people have had the same problem. There seems to be a clash of sorts between using include_stylesheets and use_stylesheets - however this is not documented anywhere AFAIK.
Edit:
Ok I think I got it now. You should add include_stylesheets() into the head section of your layout file:
<html>
<head>
<title>This is the title</title>
<?php include_stylesheets() ?>
</head>
<body>
<!-- ... -->
Then in your template file, you use use_stylesheet() to add a particular stylesheet for this template:
<?php use_stylesheet('/path/to/stylesheet.css') ?>
From the API documentation:
include_stylesheets()
Prints <link> tags for all stylesheets configured in view.yml or added to the response object.
use_stylesheet()
Adds a stylesheet to the response object.
Same for Javascript.
According to the API documentation it should still work in 1.4, sfWebResponse still has this method:
addStylesheet ($file, $position, $options)
$file The stylesheet file
$position Position
$options Stylesheet options
Adds a stylesheet to the current web response.
At least the method exists.
What exactly is the problem? Do you get an error if you want to call that method or is the stylesheet just not added?
http://www.symfony-project.org/tutorial/1_4/en/upgrade#removal_of_the_common_filter
As of 1.4 your javascripts and stylesheets are no longer automatically injected into your head tag. Instead, you need to include the following in your layout where you'd like them to be placed:
<?php include_javascripts() ?>
<?php include_stylesheets() ?>
and just in case your post title wasn't a typo you'll want to use addStylesheet('...') off of the response:
$sf_response->addStylesheet('main');
$sf_context->getResponse()->addStylesheet('style.css')
$sf_context->getResponse()->addJavascript('script.js')

Resources