Beste lezers,

Ik werk aan een website waarbij de inhoud aangepast wordt aan de taal van de gebruiker.
Het ophalen van de voorkeurstaal lukte me zonder al te veel problemen.
Dit gebeurt in de index pagina en wordt daarna in een sessie bewaard.
De taal van de inhoud is op dat moment deze van de gebruiker.
Men kan de taal later aanpassen d.m.v. icoontjes rechts bovenaan.
Het schrijven van de inhoud tussen de tags in de .php file met doctype declaratie is geen optie, aangezien deze dynamisch hoort te zijn.
Bijkomend probleem is dat tussen de verschillende hoofdstukken foto's komen te staan.
De URL's van deze foto's zullen in een databank worden bewaard.

Ik ben vrij nieuw in het gebruik van PHP en vraag me af hoe ik de inhoud nu het beste dynamisch inbreng.
Enkele mogelijke oplossingen:
- Fragmenten aanmaken in een .php file (nl, fr, en) en deze "includen" naargelang de taal.
- Functies schrijven met de gewenste inhoud en deze aanroepen.

Beide oplossingen zijn makkelijk te bereiken, maar ik heb zelf enige moeite met de netheid en flexibiliteit van bovenstaande oplossingen.
Ik probeer daarom gebruik te maken van XML en XSLT.

Ik maakte hiervoor een weerspiegeling van elke pagina in een XML file.
De voorlopige XPath weergave (hier moet nog flink wat aan gewerkt worden) ziet er als volgt uit:
- mijnproject/page@page_name/content@language/heading2
- mijnproject/page@page_name/content@language/content_text/content_text_rule/default
- mijnproject/page@page_name/content@language/content_text/content_text_rule/bolt
- mijnproject/page@page_name/content@language/content_text/content_text_rule/underline
- mijnproject/page@page_name/content@language/content_text/content_text_rule/superscript
- mijnproject/page@page_name/content@language/content_text/content_text_rule/link

Legende:
"/" = parent - child relatie tussen nodes in een XML file.
"@" = staat voor een attribuut van de node.

@page_name zal beslissen voor welke pagina de inhoud dient: index.php, media.php, ...
@language geeft de taal aan.

Ik hoop daarbij gebruik te kunnen maken van de XSLTProcessor Class.
Ik heb de .ini file reeds aangepast en krijg geen foutmeldingen meer bij het aanroepen van deze klasse.

Wat ik me afvraag:
Is het wel een juiste beslissing om hiervoor XML en XSLT te gebruiken?
Geeft dit geen problemen bij het gebruik van een externe .css file? Zijn er andere valkuilen die ik later zal tegenkomen?
Kan iemand me een betere, professionele aanpak aanraden? Heeft hier iemand de nodige ervaring mee en kan hij/zij me helpen?


Alvast bedankt, alle reacties worden geapprecieerd.

ps: Het is mogelijk dat deze topic al ergens anders wordt beantwoord, mijn excuses voor eventuele duplicatie van de gestelde vraag.
Beste lezers,

Omdat er nog geen reactie kwam op mijn post, hierbij een overzicht van mijn klassen en de container waar de content in terrecht komt.
In de hoop dat iemand dit leest en me kan helpen.

Ophalen voorkeurstaal:
<?php session_start() ;
include_once("../gns_class/BrowserPropertyUtil.php") ;
$BUtilInstance = MijnNamespace\BrowserPropertyUtil::getInstance() ;
$lang = $BUtilInstance -> getPreferedLanguage() ;
$page = "huidigepagina.php" ;
//$lang in een sessie zetten, deze kan later gewijzigd worden.
?>
De klasse BrowserPropertyUtil:
<?php namespace MijnNamespace ;
class BrowserPropertyUtil{
private static $BUtil ;
private function __construct(){
}
static function getInstance(){
if(!isset(self::$BUtil)){
self :: $BUtil = new BrowserPropertyUtil() ;
}
return self :: $BUtil;
}
static function getPreferedLanguage(){
return substr($_SERVER["HTTP_ACCEPT_LANGUAGE"], 0, 2) ;
}
}
?>

De container:
<div id='container_center' class='column'>
<?php include_once("../gns_class/TextGFacade.php") ;
$textG = new MijnNamespace\TextGFacade() ;
$textG -> printContent($page) ; // hier zal ook de taal als param worden
//meegegeven
?> </div>

De klasse TextBase:
<?php namespace MijnNamespace ;
abstract class TextBase{
function __construct(){
}
abstract protected function printContent($page) ; //taal zal later
//ook meegegeven worden.
}
?>
De klasse TextGFacade:
<?php namespace MijnNamespace ;
include_once ("TextBase.php") ;
include_once("XMLParser.php");
class TextGFacade extends TextBase{
function __construct(){
parent:: __construct() ;
}
public function printContent($page)
{
$XMLParserInstance = XMLParser::GetInstance() ;
$XMLParserInstance->ParseXML_With_WrapperFile($page);
}


}
?>
De klasse XMLParser:
<?php
namespace MijnNamespace;
class XMLParser
{
private static $XMLParser ;
private function __construct(){}
public static function GetInstance()
{
if(!isset(self::$XMLParser))
{
self :: $XMLParser = new XMLParser() ;
}
return self :: $XMLParser ;
}
public static function ParseXMLWithXSL($page){
//phpinfo();
$xml = new \DOMDocument() ;
$xsl = new \DOMDocument() ;
if($page == "index.php"){
$xml -> load('XML/dexmlfile.xml') ;
$xsl -> load('XML/destylesheet.xsl') ;
}
else{
$xml-> load('../XML/dexmlfile.xml') ;
$xsl -> load('../XML/destylesheet.xsl') ;
}
$proc = new \XSLTProcessor() ;
$proc -> importStyleSheet($xsl) ;
echo $proc->transformToXML($xml) ;

}
public static function ParseXML_With_WrapperFile($page){
$file;
if($page == "index.php"){
$file = file_get_contents('XML/dexmlfile.xml') ;
}
else{
$file = file_get_contents'../XML/dexmlfile.xml') ; }
echo($file) ;
}
public static function ParseXML($language, $page, $class_heading2)
{
$xml ;
if($page == "index.php"){
$xml = simplexml_load_file("XML/dexmlfile.xml") ;
}
else{
$xml = simplexml_load_file("../XML/dexmlfile.xml") ;
}
$page_name_fromXML ;
foreach($xml->children() as $pageNode)
{
foreach($pageNode->attributes() as $attribute){
switch($attribute->getName())
{
case "page-name": $page_name_fromXML = $attribute ; break ;
default: $page_name_fromXML = "index.php"; break ;
}
if($page == $page_name_fromXML)
{
foreach($pageNode->children() as $contentNode){
foreach($contentNode->attributes() as $contentattribute){
if($contentattribute == $language){
foreach($contentNode->children() as $contentNodeChild){
self :: TextLayoutHeadings($contentNodeChild, $class_heading2) ;
foreach($contentNodeChild-> children() as $contentNodeTextRule){
foreach($contentNodeTextRule -> children() as $finalChild){
echo($finalChild."<br />") ; } }
}
}
}
}
}
}
}
}
private static function TextLayoutHeadings($node, $class)
{
switch($node->getName())
{
case "heading1" : echo("<h1>".$node."</h1>"); break ;
case "heading2" : echo("<h2 class='".$class."'>".$node."</h2>") ; break ;
case "heading3" : echo("<h3 class='custom_font_1'>".$node."</h3>") ; break;
case "heading4" : echo("<h4>".$node."</h4>") ; break ;
case "heading5" : echo("<h5>".$node."</h5>") ; break ;
case "heading6" : echo("<h6>".$node."</h6>") ; break ;
case "heading7" : echo("<h7>".$node."</h7>") ; break ;
default : echo("<h2>".$node."</h2>") ; break;
}
}
De XSD file (staat nog niet op punt:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"; targetNamespace="http://www.gns.be"; xmlns="http://www.gns.be"; elementFormDefault="qualified">
<xs:element name="gns">
<xs:complexType>
<xs:sequence>
<xs:element name="page" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="content" minOccurs="1"maxOccurs="unbounded">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:choice>
<xs:element name="content_text" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="content_text_rule" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:choice>
<xs:element name="bold" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="underline" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="subscript" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="superscript" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="link" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="default" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="application" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="heading1" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="heading2" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="heading3" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="heading4" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="heading5" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="heading6" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="heading7" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="unordered_list">
<xs:complexType>
<xs:sequence>
<xs:element name="list_item" type="xs:string" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:sequence>
<xs:attribute name="language" type="xs:string" use="required"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="page-name" type="xs:string" use="required"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

Een stukje uit de XML file:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="gns_stylesheet.xsl"?>

<gns
xmlns="http://www.gns.be";
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
xsi:schemaLocation="http://www.gns.be dexsdfilenaam.xsd">
<page page-name="index.php">
<content language="nl">
<heading2>Introductie:</heading2>
<content_text>
<content_text_rule>
<default>Tekst NL</default>
</content_text_rule>
<content_text_rule>
<default>Tekst NL.</default>
</content_text_rule>
<content_text_rule>
<default>TekstNL.</default>
</content_text_rule>
<content_text_rule>
<default>Tekst NL.</default>
</content_text_rule>
<content_text_rule></content_text_rule>
<content_text_rule>
<default>Tekst NL.</default>
</content_text_rule>
<content_text_rule>
<default>Tekst NL</default>
</content_text_rule>
<content_text_rule>
<default>Tekst NL.</default>
</content_text_rule>
<content_text_rule>
<default>Tekst NL.</default>
</content_text_rule>
<content_text_rule>
<default>Tekst NL</default>
</content_text_rule>
<content_text_rule>
<default>Tekst NL.</default>
</content_text_rule>
</content_text>
<heading2>Heading 2</heading2>
<content_text>
<content_text_rule>
<default>Tekst NL</default>
</content_text_rule>
<content_text_rule>
<default>Tekst NL.</default>
</content_text_rule>
</content_text>
<heading2>Heading 2</heading2>
<content_text>
<content_text_rule><default>Tekst NL.</default></content_text_rule>
<content_text_rule><default>Tekst NL.</default></content_text_rule>
<content_text_rule><default>Tekst NL.</default></content_text_rule>
</content_text>
<unordered_list>
<list_item>Item</list_item>
<list_item>Item</list_item>
<list_item>Item</list_item>
<list_item>Item</list_item>
</unordered_list>
<unordered_list>
<list_item>Item</list_item>
<list_item>Item</list_item>
</unordered_list>
<content_text>
<content_text_rule><default>Tekst NL</default></content_text_rule></content_text>
</page>
<page page-name="index.php">
<content language="en">
<content_text>
<content_text_rule><default>Tekst EN</default></content_text_rule>
</content_text>
<heading2>Heading 2</heading2>
<content_text>
<content_text_rule>
<default>Tekst EN.</default>
</content_text_rule>
<content_text_rule><default>Tekst ENG</default></content_text_rule>
<content_text_rule><default>Tekst ENG.</default></content_text_rule>
</page>
<page page-name="index.php">
<content language = "fr">
<content_text>
<content_text_rule><default>Tekst FR</default></content_text_rule>
</content_text>
<heading2>Heading 2</heading2>
<content_text>
<content_text_rule><default>Tekst FR</default></content_text_rule>
<content_text_rule><default></content_text>
</page>

Mijn excuses voor het eventuele ongemak bij het lezen van mijn code.
PHP is vrij nieuw voor mij, ik leer op dit moment uit het handboek PHP5.3 van Arjan Burger. Er moet nog héél wat aan refactoring gedaan worden.
Alle nuttige tips en constructieve kritiek zijn welkom.

Met vriendelijke groet,
Michael.
Beste lezers,

Ik ben op zoek naar alternatieven om deze opgave op te lossen.
Het gebruik van XML voor deze oplossing lijkt nogal omslachtig en ook te uitgebreid.
Ik heb ondertussen nog het één en ander opgezocht en ben daarbij op volgende website terrecht gekomen.
http://nitschinger.at/Handling-JSON-like-a-boss-in-PHP
Er is ook een tutorial te volgen op W3S (deze stelt echter niet veel voor).
http://www.w3schools.com/json/default.asp
Aan de hand hiervan maakte hetvolgende:

{
"gns":{
"pages":[
"page_index":{
"name":"index.php",
"contents_all_languages_index":[
"content_nl":{
"language":"nl",
"chapters":[
"chapterA":{
"title":"test title index - chapter A - nl",
"content":"test text index - chapter_A - nl"
},
"chapterB":{
"title":"test title index - chapter B - nl",
"content":"test text index - chapter_B - nl"
}
]

},
"content_fr":{
"language":"fr",
"chapters":[
"chapterA":{
"title":"test title index - chapter A - fr",
"content":"test text index - chapter_A - fr"
},
"chapterB":{
"title":"test title index - chapter B - fr",
"content":"test text index - chapter_B - fr"
}
]
},
"content_en":{
"language":"en",
"chapters":[
"chapterA":{
"title":"test title index - chapter_A - en",
"content":"test text index - chapter_A - en"
},
"chapterB":{
"title":"test title index - chapter_B - en",
"content":"test text index - chapter_B - en"
}
]
}
]
}
},
"page_uwPaginaA":{
"name":"pagina_uwPaginaA.php",
"contents_all_languages_uwPaginaA":[
"content_nl":{
"language":"nl",
"chapters":[
"chapterA":{
"title":"test title uw Pagina A - chapter_A - nl",
"content":"test text uw Pagina A - chapter_A - nl"
},
"chapterB":{
"title":"test title uw Pagina A- chapter_B - nl",
"content":"test text uw Pagina A - chapter_B -nl"
}
]
},
"content_fr":{
"language":"fr",
"chapters":[
"chapterA":{
"title":"test title uw Pagina A - chapter_A - fr",
"content":"test text uw Pagina A - chapter_A - fr"
},
"chapterB":{
"title":"test title uw Pagina A - chapter_B - fr",
"content":"test text uw Pagina A - chapter_B - fr"
}
]
},
"content_en":{
"language":"en",
"chapters":[
"chapterA":{
"title":"test title uw Pagina A - chapter_A - en",
"content":"test text uw Pagina A - chapter_A - en"
},
"chapterB":{
"title":"test title uw Pagina A - chapter_B - en",
"content":"test text uw Pagina A - chapter_B - en"
}
]
}
]
},
"page_uwPaginaB":{
"name":"pagina_uwPaginaB.php",
"contents_all_laguages_uwPaginaB":[
"content_nl":{
"language":"nl",
"chapters":[
"chapterA":{
"title":"test title uw Pagina B - chapter_A - nl",
"content":"test text uw Pagina B - chapter_A - nl"
},
"chapterB":{
"title":"test title uw Pagina B - chapter_B - nl",
"content":"test text uw Pagina B - chapter_B - nl"
}
]
},
"content_fr":{
"language":"fr",
"chapters":[
"chapterA":{
"title":"test title uw Pagina B - chapter_A - fr",
"content":"test text uw Pagina B - chapter_A - fr"
},
"chapterB":{
"title":"test title uw Pagina B - chapter_B - fr",
"content":"test text uw Pagina B - chapter_B - fr"
}
]
},
"content_en":{
"language":"en",
"chapters":[
"chapterA":{
"title":"test title uw Pagina B - chapter_A - en",
"content":"test text uw Pagina B - chapter_A - en"
},
"chapterB":{
"title":"test title uw Pagina B - chapter_B - en",
"content":"test text uw Pagina B - chapter_B - en"
}
]
}
]
}
]
}

}
Kan iemand met enige JSON ervaring me duidelijk maken of dit haalbaar zal zijn?
Is het tevens haalbaar deze met PHP code te benaderen, om de stukken die ik nodig heb er uit te halen?

Alvast bedankt voor de reacties.

Mvg, Michael.



[size=xsmall]Toevoeging op 11/07/2013 15:46:43:[/size]

Beste lezers,

Ik heb enkele regels code geschreven om JSON te parsen, maar dit blijkt niet zo evident te zijn.
Ik krijg nu steeds dezelfde foutmelding, kan iemand me helpen?
<?php
public static function parseJSONFile(){
$text = file_get_contents("../JSON/testJSON.json") ;
$contents = utf8_encode($text) ;
$result = json_decode($contents) ;
switch (json_last_error()) {
case JSON_ERROR_NONE: echo ' - No errors'; break;
case JSON_ERROR_DEPTH: echo ' - Maximum stack depth exceeded';break;
case JSON_ERROR_STATE_MISMATCH: echo ' - Underflow or the modes mismatch';break;
case JSON_ERROR_CTRL_CHAR: echo ' - Unexpected control character found';break;
case JSON_ERROR_SYNTAX: echo ' - Syntax error, malformed JSON'; break;
case JSON_ERROR_UTF8: echo ' - Malformed UTF-8 characters, possibly incorrectly encoded'; break;
default: echo ' - Unknown error'; break;
}
}
?>
Ik krijg hiebij steeds de melding Syntax error, malformed JSON. Iemand enig idee hoe dit komt? De JSON is nogthans well-formed.

Mvg, Michael.
Waar heb je die JSON string gevonden?
Die klopt namelijk niet.

Je hebt arrays en objecten.
object-notatie: {}
array-notatie: []

Helemaal in het begin al:

"pages":[
  "page_index":{
  "name":"index.php",
...
}
]


Na het openen van een array (dus met [ ) wordt een waarde verwacht. Niet een key.

Php noemt dit een array:
<?php
$pages = array(
'page_index' => 'foo',
'name' => 'bar'
);
?>
maar zowat elke andere taal (As far as I know) noemt dit geen array, maar meestal een object.

Een array, volgens andere talen, is altijd met numerieke key. Die numerieke key begint bij 0, dan 1, dan 2, ... Er mag geen enkele key ontbreken.

Php staat dit allemaal we toe
JSON zal het niet aanvaarden.

--------
EDIT:
Michael Raets op 11/07/2013 13:23:12

...Ik krijg hiebij steeds de melding Syntax error, malformed JSON. Iemand enig idee hoe dit komt? De JSON is nogthans well-formed.


Ik geef de validator gelijk.
Hey Kris,

Ik heb deze zelf in een file geschreven met een plugin voor Eclipse.
Ik deed dit volgens de tutorial van W3S: http://www.w3schools.com/json/json_syntax.asp
Dit is hun voorbeeld van een JSON array:
{
"employees":[
{ "firstName":"John" , "lastName":"Doe" },
{ "firstName":"Anna" , "lastName":"Smith" },
{ "firstName":"Peter" , "lastName":"Jones" }
]
}

Ik heb ervaring met Java en .NET syntax, PHP en JSON zijn vrij nieuw voor me :).
Ik probeer een JSON array van "pages" te maken.
Hier zullen uiteraard representaties van pagina's in worden bijgehouden.
De page_index staat voor een object dat de index.php pagina voorstelt.
Deze heeft op zijn beurt een attribuut "name" en een JSON array "contents_all_languages" van "content" attributen.
Ik zou op deze manier de structuur willen doorlopen om zo mijn pagina's te vullen aan de hand van de voorkeurstaal.

Kan ik dit anders oplossen? Hoe kan ik dit best volgens jou?

Bedankt voor je reactie.

Mvg, Michael.

Die string die je daar post, klopt inderdaad wel.
employees is een array van objecten. Dat mag wel.

<?php
$employees = array(
new User('John', 'Doe'), // stel dus dat Class User die waarden dan op de juiste plaats zet ...
new User('Anna', 'Smith'),
...
);
?>

Je merkt dat $employees een array is omdat je $employees[0], $employees[1], ... kan aanspreken.
Je kan niet $employees['john'] aanspreken; en zo hoort het.

Bij jouw string klopt dit niet voor 'pages' (en misschien nog andere fouten).
Je moet die herschrijven, op zo'n manier dat je duidelijk maakt wat een object is en wat een array is.

-----

EDIT:
Ik zou bv. dit verwachten

"pages":[
  {"name":"index.php", "contents_all_languages_index": [...]},
  {"name":"pagina_uwPaginaA.php", "contents_all_languages_index": [...]},
  ...
]
Hey Kris,

Nogmaals bedankt voor uw hulp.

Kan ik dan bvb dit doen?
"pages":[
{"name":"index.php",[
{"content":{"language":"nl", "content_text_nl":"de tekst in nl"}},
{"content":{"language":"fr", "content_text_fr":"de tekst in fr"}}
],
{"name":"paginaA.php",[
{"content":{"language":"nl", "content_text_nl":"de tekst in nl"}},
{"content":{"language":"fr", "content_text_fr":"de tekst in fr"}}
],
]}

Had je reply nog niet gelezen, maar denk dat ik een idee heb in welke richting ik moet zoeken.
Bedankt voor al je hulp, wellicht kan ik deze later nog gebruiken ;).
Mvg, Michael.

Reageren