2010-08-02 24 views
0

Je réécris un site Web qui supportera plusieurs skins. Actuellement, je prévois simplement de modifier les images et les CSS, mais le HTML sous-jacent ne changera pas. Et si l'habillage ne modifie pas une image ou un fichier CSS, il hérite de ce fichier de l'habillage de base.Création de site Web avec des habillages - Quelle est la meilleure façon de diffuser une image correcte de mon point de vue?

Dans cet esprit, voici les 3 façons j'ai pris en compte à ce jour pour servir des fichiers dépendants de la peau:

  1. Justifier les demandes de demandes spécifiques de la peau dans la vue avec une fonction de recherche, à savoir :
 
    <img src="<?php get_skin_file('/images/header.png', 'skin1'); ?>" /> 

    function get_skin_file($file, $skin) { 
     $skin_file = '/' . $skin . '/' . $file; 
     if(is_readable($skin_file)) return $skin_file; 
     return '/default/' . $file; 
    } 
  1. PHP est servir l'image

    <img src="/header.png.php?skin=skin1" />

  2. Il faut toujours chercher à charger le fichier de la peau et si elle n'existe pas, utilisez ModRewrite d'envoyer le résultat à un script de gestionnaire php:

    <img src="/skin1/header.png" />

numéro 2 est ce que je J'aimerais faire, mais je suis juste préoccupé par les implications de performance de PHP servir essentiellement chaque fichier image.

Ma base d'utilisateurs est assez petite (environ 30k utilisateurs) que je ne pense pas que ce serait vraiment un problème, mais je voudrais juste apprendre ce que les autres font dans cette situation.

Merci.

EDIT: Je ne sais pas pourquoi mon code n'est pas formaté correctement. J'ai appuyé sur le bouton de code et vérifié qu'il y a 4 espaces, mais c'est toujours moche. Désolé pour ça.

+0

Correction de la mise en forme. Je ne sais pas pourquoi il se brisait comme ça. En outre, vous n'avez pas besoin d'inclure des mots-clés ou des préfixes dans les titres des questions, c'est à cela que servent les balises. :) – Charles

Répondre

0

Je liquidée aller avec une variante de l'option 2. Je vais avoir look apache pour les modèles d'URL et si une peau remplaçable url est présent, la requête est routée vers mon script de sélection d'image de la peau.

Voici la config apache pertinente:

<Directory /var/www/website> 
    RewriteEngine on 
    RewriteBase/

    RewriteCond %{REQUEST_URI} \.select.(png|jpg|gif|txt|css)$ [NC] 
    RewriteRule ^(.*)$ index.php?mode=select&q=$1 [L,QSA] 
</Directory> 

Voici le code PHP à partir du fichier qui rend l'image:

<?php 
preg_match("%^(?P<path>.+)\.select\.(?P<ext>(jpg|gif|png|txt|css))$%", $_REQUEST['q'], $matches); 

$base = '/' . $matches['path'] . '.' . $matches['ext']; 

$file = '/skins/' . App::get('skin') . '/' . $base; 

if(is_readable($file)) { 
    header('Content-type: image/' . $matches['ext']); 
    header('Content-Transfer-Encoding: binary'); 
    header('Content-Length: ' . filesize($file)+1); 
    readfile($file); 
    exit(); 
} 
//custom file isn't available, so load the default 
$file = '/skins/default/' . $base; 
header('Content-type: image/' . $matches['ext']); 
header('Content-Transfer-Encoding: binary'); 
header('Content-Length: ' . filesize($file)+1); 
readfile($file); 
exit(); 
?> 

donc pour tout élément d'actif à mon avis qui doit être la peau -Aware, je le charge comme:

<img src="/images/header.select.png" /> 

et apache attrape et l'envoie à mon script de gestionnaire.

Merci pour votre aide à ce sujet. Les deux autres suggestions fournies par Stmpy et Charles fonctionneraient également, mais c'était la solution idéale pour moi. En bonus, je peux aussi remplacer les images en css et ce qui ne l'est pas de façon dynamique sans les fichiers css personnalisés. Mon application consistera en grande partie à simplement remplacer l'arrière-plan primaire, donc tout ce qui sera nécessaire pour mes thèmes, pour la plupart sera juste de créer un nouveau dossier de la peau et de télécharger une image de fond.

1

Ces trois options sont parfaitement valables. Personnellement, je préfère le premier, mais en utilisant un nom d'image plutôt qu'un chemin d'image. Si vos bits de contrôle de thème sont suffisamment puissants, cela peut permettre aux thèmes de définir leurs propres images contrôlables par l'utilisateur.

Considérons une quatrième option: n'insérez pas réellement d'images en utilisant des balises img. Au lieu de cela, utilisez divs avec des images d'arrière-plan. Cela peut fonctionner dans la majorité des cas, et laisse la définition des images entièrement à la feuille de style. Malheureusement, c'est aussi une option beaucoup plus complexe.

1

Je voudrais essayer de construire cela de sorte qu'il est modulaire et facilement adaptable pour les changements futurs. J'éviterais de placer autant que possible dans des emplacements durs dans votre code, ou au moins de le réduire à 1 emplacement. Une chose qui peut être utile est d'avoir une sorte de fichier ini ou un fichier xml qui contient des informations concernant vos images pour des skins spécifiques. De cette façon, les emplacements durs ne sont pas dans votre php ou html, ils sont juste dans un fichier de ressources qui est facilement modifiable. J'aime utiliser XML, voici un exemple de ce que vous pourriez faire.

Voici le code HTML.Ensuite, voici votre fonction, si l'image de la peau est introuvable, il tirera à partir du fichier xml par défaut.

function get_skin_image($type,$skin){ 
    $skin_xml_data = xml2array("skinFolderLocation/ " . $type . ".xml"); 
    $default_xml_data = xml2array("defaultFolderLocation/default.xml"); 
    // here is a link to the xml2array function for you to download 
    // http://www.php.net/manual/en/function.xml-parse.php#87920 
    if(isset($skin_xml_data[$skin][$type])){ 
     return $skin_xml_dat[$skin][$type]; 
    } else { 
     return $default_xml_data["default"][$type]; 
    } 
} 

Et enfin la page xml enregistré en tant que notDefault.xml

<notDefault> 
    <header>locationToHeader/header.png</header> 
    <footer>locationToFooter/footer.png</footer> 
</notDefault> 
+0

Merci pour la suggestion.J'avais envisagé cette idée, mais j'essaie d'éviter autant que possible les fichiers de configuration. Si ma logique de substitution était plus complexe et/ou si je n'avais pas de contrôle sur la création des skins, un tel fichier aurait beaucoup de sens, mais comme ma logique de substitution est si simple et que je contrôle les skins, je vérifie le système de fichiers semble être mieux adapté à mon application. – user126715

0

Pourriez-vous pas espace de noms les actifs de votre peau? Par exemple, la plupart des applications que je construis ont un répertoire inc (contenant une logique de programmation) et un répertoire tpl, qui est ensuite décomposé en répertoires séparés pour des enveloppes séparées. Si le site n'a qu'un seul skin, alors ils ne seront qu'un seul répertoire.

Par exemple:

inc/ 
    ... 
tpl/ 
    default/ 
     assets/ 
      css/ 
      images/ 
      js/ 
    alternative/ 
     assets/ 
      css/ 
      images/ 
      js/ 

Dans mon script du contrôleur, index.php, je peux écouter une variable tpl à passer par le tableau $_GET. Par exemple:

if (!isset($_SESSION['tpl'])) { 
    $tpl = "default"; 
} 
if (isset($_GET['tpl']) && is_dir('tpl/'.$_GET['tpl'])) { 
    $_SESSION['tpl'] = $_GET['tpl']; 
} 
$tpl = $_SESSION['tpl']; 

Maintenant, la valeur actuelle tpl est disponible dans mon tableau $_SESSION (je pourrais facilement changer pour utiliser des cookies à la place si je voulais la valeur de persister entre les sessions) et variables $tpl. Je peux alors obtenir des images et des chemins CSS comme ceci:

<img src="tpl/<?php echo $tpl; ?>/assets/images/heading.jpg" alt="Heading image" /> 

<link rel="stylesheet" href="tpl/<?php echo $tpl; ?>/assets/css/screen.css" type="text/css" /> 

Asset (CSS, images, JavaScript) demande pourrait alors être enveloppé dans une fonction personnalisée. Cela pourrait également gérer les cas où, par exemple, tous vos fichiers JavaScript étaient contenus dans le skin default, et vous ne vouliez pas les dupliquer dans votre skin alternative.

function get_template_file($filename, $tpl) 
{ 
    // if we're requesting a JavaScript file, serve from 'default' regardless 
    if (substr($filename, -3) == ".js") { 
     return "tpl/default/".$filename; 
    } 
    else { 
     $file = "tpl/{$tpl}/{$filename}"; 
     if (is_file($file) && is_readable($file)) { 
      return $file; 
     } 
     else { 
      $tpl = "default"; 
      return $file; // try return 'default' filepath 
     } 
    } 
}