2010-08-02 48 views
0

我正在重写一个支持多个皮肤的网站。目前,我只是计划允许修改图像和CSS,但底层HTML不会更改。如果皮肤不修改图像或CSS文件,它会从基础皮肤继承该文件。用皮肤创建网站 - 根据我的观点,提供正确图像的最佳方式是什么?

考虑到这一点,这里有3种方式,到目前为止,我认为是服务了皮肤相关文件:

  1. 总结视图中的所有肌肤专用的处理请求的查找功能,即:
 
    <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; 
    } 
  • 的PHP服务于图像

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

  • 总是尝试加载皮肤文件,如果它不存在,使用ModRewrite将结果发送到PHP处理程序脚本:

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

  • 2号是我我喜欢这样做,但我只关心让PHP基本上为每个图像文件提供服务的性能影响。

    我的用户库足够小(约3万用户),我不认为这确实是一个问题,但我也想知道其他人在这种情况下做了什么。

    谢谢。

    编辑:我不知道为什么我的代码格式不正确。我点击代码按钮并检查它是4个空格,但它仍然很难看。对于那个很抱歉。

    +0

    修复了您的格式。不知道为什么它会像那样突破。此外,您不需要在问题标题中包含关键字或前缀,这就是标签的用途。 :) – Charles 2010-08-02 18:31:02

    回答

    0

    我结束了与选项我有阿帕奇找URL模式2的变化去,如果皮肤更换url存在,请求被路由到我的皮肤图像选择脚本。

    下面是相关Apache的配置:

    <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> 
    

    下面是该文件的PHP代码,呈现的图像:

    <?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(); 
    ?> 
    

    所以在我看来,需要是皮肤的任何资产意识到,我加载它像:

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

    和Apache捕获它并将其发送到我的处理程序脚本。

    感谢您的帮助。另外两个建议提供了stmpy和Charles也会工作,但这对我来说是理想的解决方案。作为这样做的好处,我也可以在css中替换图像,并且在没有自定义css文件的情况下动态地替换图像。我的应用程序主要由主要背景替换组成,所以对于我的主题来说,所有这些都是必需的,但大部分只是创建一个新的外观文件夹并上传一个背景图像。

    1

    所有这三个都是完全有效的选项。我个人更喜欢第一个,尽管使用图像名称而不是图像路径。如果你的主题控制位足够强大,这可以允许主题定义他们自己的额外的用户可控图像。

    考虑第四种选择:不要使用img标签实际插入图像。相反,使用div与背景图像。这可以适用于大多数情况,并将图像完全定义到样式表。不幸的是,这也是一个更复杂的选择。

    1

    我会尝试建立这样的模块化,并容易适应未来的变化。我会尽可能地避免在代码中放置较硬的位置,或者至少将其最小化到一个位置。

    有一件值得关注的事情是有一些ini文件或一个xml文件,其中包含有关特定皮肤的图片的信息。这样,硬性位置不在您的php或html中,它们只是在一个易于更改的资源文件中。

    我喜欢用xml,所以这里是你可以做的一个例子。

    这里是html。

    <?php $skin = "notDefault"; ?> 
    <img src="<?php get_skin_image("header",$skin) ?>" /> 
    <img src="<?php get_skin_image("footer",$skin) ?>" /> 
    

    那么这里将是你的函数,如果皮肤图像不被发现就会把它从默认的XML文件。

    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]; 
        } 
    } 
    

    最后的XML页面保存为notDefault.xml

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

    感谢您的建议。我考虑过这个想法,但是我尽量避免配置文件。如果我的替换逻辑更加复杂,并且/或者我无法控制创建皮肤,那么类似这样的XML文件会很有意义,但是由于我的替换逻辑非常简单,我可以控制皮肤,检查文件系统似乎更适合我的应用程序。 – user126715 2010-08-02 19:49:12

    0

    你不能命名空间你的皮肤的资产?例如,我构建的大多数应用程序都有一个inc目录(包含编程逻辑)和tpl目录,然后将其分解为单独的皮肤的单独目录。如果该网站只有一个皮肤,那么它们只会是一个目录。

    例如:

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

    以我控制器脚本,index.php,我可以侦听一个tpl变量经由$_GET阵列传递。例如:现在

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

    ,当前tpl值是我$_SESSION阵列可用的(我可以很容易地改变这种使用cookie,而不是如果我想价值会话之间持续存在)和$tpl变量。然后我就可以得到图像和CSS路径是这样的:

    <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" /> 
    

    资产(CSS,图片,JavaScript)的要求然后可以在自定义功能包。这也可以处理所有JavaScript文件都包含在default皮肤中的情况,并且您不希望在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 
         } 
        } 
    } 
    
    相关问题