Cakephp: Html helper és CSS, IE feltételes megjegyzéseivel

Sose gondoltam volna, hogy valaha szükségem lesz Internet Explorerhez külön css-t gyártanom. Mindig azt vallottam, hogy egy jól megírt weblap minden böngészőben legalább az elfogadható szintet megüti, ha nem is tökéletes. Könnyen beszéltem, hisz igen ritkán kellett nekem a megjelenéssel komolyabban foglalkoznom. Nem az a specialitásom. Most mégis belefutottam abba a problémába, hogy már mindenhol tökéletes volt a megjelenés 2 napi munka után, kivéve az Internet Explorer 7-et. Így szükségem lett volna az IE feltételes megjegyzéseire

Na most egy ideje van "szerencsém" cakephp keretrendszerben fejleszteni. Van neki egy HtmlHelper osztálya, aminek a css() metódusával lehet css linkeket elhelyezni vagy rögtön megjelenítve a html forráskódját ( ez ugye a layouts/default.ctp-ben szokott történni a <head> részben )

print $html->css('cssneve');

vagy csak jelezve a sablonban, hogy azt majd el kell helyezni a layoutban. Ekkor bekerül a $scripts_for_layout változóba, amit a layoutban kiírva megjelenik az összes íly módon felvett script vagy css link.

$html->css('cssneve', null, array('inline'=>false));

Na most az első esetben nincs semmi gond. Azt írok a metódus hívás köré, amit jólesik. Második esetben viszont vagy az egész $scripts_for_layout változót beteszem a megjegyzésbe, vagy semmit. Szóval a következőt tettem. Az app/views/helpers/ mappában létrehoztam egy html.php -t. Ebbe bemásoltam a cake/view/libs/html.php tartalmát. Így automatikusan ezt a fájlt olvassa be ugyanis a cakephp az eredeti helyett. Majd kicsit megmódosítottam a css metódust a következőképpen. Felvettem egy "ie" attribútumot alapértelmezett false értékkel. Ebben adom meg az IE verzióját. Tehát a

        function css($path, $rel = null, $options = array()) {
                $options += array('inline' => true);

részt lecseréltem a következőre:

        function css($path, $rel = null, $options = array()) {
                $options += array('inline' => true,'ie'=>false);

Viszont ügyelni kell arra is, hogy magának a generált link tag-nek is az $options tömbben lehet megadni tetszőleges attribútumokat, tehát fel kel venni kivételként az "ie" -t is az "inline" mellé. Ehhez a következő részt:

                if ($rel == 'import') {
                        $out = sprintf($this->tags['style'], $this->_parseAttributes($options, array('inline'), '', ' '), '@import url(' . $url . ');');
                } else {
                        if ($rel == null) {
                                $rel = 'stylesheet';
                        }
                        $out = sprintf($this->tags['css'], $rel, $url, $this->_parseAttributes($options, array('inline'), '', ' '));
                }

is lecseréltem erre:

                if ($rel == 'import') {
                        $out = sprintf($this->tags['style'], $this->_parseAttributes($options, array('inline','ie'), '', ' '), '@import url(' . $url . ');');
                } else {
                        if ($rel == null) {
                                $rel = 'stylesheet';
                        }
                        $out = sprintf($this->tags['css'], $rel, $url, $this->_parseAttributes($options, array('inline','ie'), '', ' '));
                }

Közvetlenül ez után pedig beszúrtam a következőt, ami már a tényleges munkát végzi:

                if ($options['ie'])
                {
                        $version = $type = "";
                        if (preg_match('~(?P<type>\D*?)(?P<version>\d.*)~',$options['ie'],$matches))
                        {
                                $type = str_replace(array('>=','<=','<','>'),array('gte','lte','lt','gt'),trim($matches['type']));
                                $version = trim($matches['version']);

                        }
                        $hack = "<!--[if %s IE %s]>\n%s\n<![endif]-->";
                        $out = sprintf($hack, $type, $version, $out);
                }

Most tehát a teljes metódusom így néz ki:

        function css($path, $rel = null, $options = array()) {
                $options += array('inline' => true,'ie'=>false);
                if (is_array($path)) {
                        $out = '';
                        foreach ($path as $i) {
                                $out .= "\n\t" . $this->css($i, $rel, $options);
                        }
                        if ($options['inline'])  {
                                return $out . "\n";
                        }
                        return;
                }

                if (strpos($path, '://') !== false) {
                        $url = $path;
                } else {
                        if ($path[0] !== '/') {
                                $path = CSS_URL . $path;
                        }

                        if (strpos($path, '?') === false) {
                                if (substr($path, -4) !== '.css') {
                                        $path .= '.css';
                                }
                        }
                        $url = $this->assetTimestamp($this->webroot($path));

                        if (Configure::read('Asset.filter.css')) {
                                $pos = strpos($url, CSS_URL);
                                if ($pos !== false) {
                                        $url = substr($url, 0, $pos) . 'ccss/' . substr($url, $pos + strlen(CSS_URL));
                                }
                        }
                }

                if ($rel == 'import') {
                        $out = sprintf($this->tags['style'], $this->_parseAttributes($options, array('inline','ie'), '', ' '), '@import url(' . $url . ');');
                } else {
                        if ($rel == null) {
                                $rel = 'stylesheet';
                        }
                        $out = sprintf($this->tags['css'], $rel, $url, $this->_parseAttributes($options, array('inline','ie'), '', ' '));
                }
                /* IE hack */
                if ($options['ie'])
                {
                        $version = $type = "";
                        if (preg_match('~(?P<type>\D*?)(?P<version>\d.*)~',$options['ie'],$matches))
                        {
                                $type = str_replace(array('>=','<=','<','>'),array('gte','lte','lt','gt'),trim($matches['type']));
                                $version = trim($matches['version']);

                        }
                        $hack = "<!--[if %s IE %s]>\n%s\n<![endif]-->";
                        $out = sprintf($hack, $type, $version, $out);
                }

                if ($options['inline']) {
                        return $out;
                } else {
                        $view =& ClassRegistry::getObject('view');
                        $view->addScript($out);
                }
        }

Használata:

//bármilyen IE verzióban
$html->css('cssneve', null, array('inline'=>false,'ie'=>true));

//csak 7-esben
$html->$html->css('cssneve', null, array('inline'=>false,'ie'=>'7'));
//vagy
$html->css('cssneve', null, array('inline'=>false,'ie'=>'=7'));

// 7-esben és annál kisebb verziókban
$html->css('cssneve', null, array('inline'=>false,'ie'=>'<=7'));

// 7-nél kisebb verziókban
$html->css('cssneve', null, array('inline'=>false,'ie'=>'<7'));

// 7-esben és annál nagyobb verziókban
$html->css('cssneve', null, array('inline'=>false,'ie'=>'>=7'));

// 7-esnél nagyobb verziókban
$html->css('cssneve', null, array('inline'=>false,'ie'=>'>7'));

Kategóriák: 
Megosztás/Mentés