Pull to refresh

Организация пакетов с помощью css-suki

Reading time5 min
Views1.8K
Стили и соответствующие им картинки группируются в однин модуль. Для каждого модуля — отдельная директория. Ссылки к картинкам задаются относительно родительской директории. Например, для модуля «pager» создаётся одноимённая директория, в которую кладётся один или несколько css с произвольным названием (например, с тем же — «pager.css»), рядом с ним картинка «pager-current_bg.png», ссылка к которой выглядит так "../page/pager-current_bg.png". Картинка из примера задаёт фон для элемента содержащего номер текущей страницы в пэйджере. Имена картинок складываются из имени элемента (pager-current, pager-next, pager-prev..), расположения картинки (bg, top, left, top-left, icon..) и модификаторов (hover, active, selected..), разделённых между собой подчёркиванием. Сложный пример: pager-next_icon_hover.png

Группировка в модуль происходит по родству. Например, в модуле «text» могут содержаться стили для стандартных элементов гипертекста (em, strong, q..), в «form» — стили для элементов форм, в «table» — всё, что касается таблиц. Разметка выполняется как описано в статье про независимые элементы.

Бонусом от этих шаманств является высокая степень независимости визуальных модулей друг от друга, что позволяет легко переносить их между проектами и пакетами не заботясь о порядке их подключения. Некоторые модули требуют подключения вначале (например, css-reset) — их можно именовать добавляя в начале цифру (например, «0_reset»).

Как было упомянуто выше, модули собираются в пакеты — простой группировкой по директориям. Пакет конечному пользователю приходит одним файлом. Разработчик же может переключиться в режим загрузки всех css файлов по отдельности.

<link href="client/style/?name=main" type="text/css" rel="stylesheet" /><br>- компилирует пакет "main" и подключает каждый стилевой файл по отдельности<br><br><link href="client/style/?name=main&mode=compiled" type="text/css" rel="stylesheet" /><br>- то же самое, но подключает все стили одним файлом<br><br><link href="client/style/main/~/compiled.css" type="text/css" rel="stylesheet" /><br>- подключает скомпилированную цсс-ку, используется на продакшене

Для спрайтов заводится отдельный модуль. Но не стоит без крайней необходимости засовывать все картинки в один файл — лучше группировать по смыслу и форм-фактору.

Описанная файловая структура позволяет компилировать стили простым слиянием всех файлов, не ломая при этом относительные ссылки к картинкам. При запуске css-suki создаёт в указанном пакете псевдомодуль с именем "~" куда записывает index.css, compiled.css и при необходимости разбивки на страницы page=*.css. Благодаря автоматическому разбиению на страницы, в пакете может быть до 900 css-файлов даже в IE.

Чтобы создать новый модуль, вы просто создаёте директорию внутри пакета и в ней css-файл. Вам не нужно никуда дополнительно его прописывать — всё будет сделано автоматически. Перенос в другой пакет осуществляется соответствующим образом. Работа с пакетами полностью аналогична. Благодаря относительным путям вам не надо беспокоиться о том, в какой директории надо расположить стили, в "/css/", "/client/styles/" или ещё где.

А вот и собственно компилятор (пакеты нужно создавать прямо рядом с ним):

<?php # css-suki # rev: 2 # license: public domain

# входные параметры
$mode= @$_GET['mode'] or $mode'index';
if( 
$mode === 'source' highlight_file__FILE__ ) and die();
$namepreg_replace'![^\w-]+!''', @$_GET['name'] ) or $name'main';

# константы
$pageLimit30;

# подготовка файловой системы
chdir$name );
@
mkdir'~'0777true );

# составление списка файлов пакета
$filesglob"??*/*.css"GLOB_BRACE );
sort$files );
$filesCountcount$files );
if( 
$filesCount pow$pageLimit) ) print 'too many files' and die();

# компиляция в один файл
$compile= array();
foreach( 
$files as $file ):
    
$compile[]= "/* @import url( '../{$file}' ); */";
    
$compile[]= file_get_contents$file ) . "\n";
endforeach;
$compileimplode$compile"\n\n" );
file_put_contents"~/compiled.css"$compile );

# формирование индекса
if( $filesCount $pageLimit ):
    
$indexpreg_replace'!(.+)!''../$1'$files );
else:
    
$index= array();
    for( 
$page0; ( $page $pageLimit ) < $filesCount; ++$page ):
        
$index[]= "page={$page}.css";
    endfor;
endif;

# сохранение индекса на диск
$indexpreg_replace'!(.+)!''@import url( "$1" );'$index );
$indeximplode$index"\n" );
file_put_contents"~/index.css"$index );

# нарезание списка файлов на страницы и запись их на диск
if( $filesCount >= $pageLimit ):
    for( 
$page0; ( $page $pageLimit ) < $filesCount; ++$page ):
        
$pageFilesarray_slice$files$page $pageLimit$pageLimit );
        
$pageFilesimplodepreg_replace'!(.+)!''@import url( "../$1" );'$pageFiles ), "\n" );
        
file_put_contents"~/page={$page}.css"$pageFiles );
    endfor;
endif;

# браузеру отдаётся ссылка на нужный файл
switch( $mode ){
    case 
'index': case 'compiled':
        
header"Content-Type: text/css"true200 );
        echo 
"@import url( '{$name}/~/{$mode}.css' );\n";
        break;
    default:
        echo 
"wrong mode";
}

exit(); 
?>

параметры:
    mode - режим работы
    name - имя пакета

режимы работы:
    source - исходник css-suki
    index - ссылка на индексный файл подключающий все файлы, принеобходимости разбивает вывод на страницы
    compiled - ссылка на содержимое всех файлов одной простынёй
Tags:
Hubs:
+5
Comments16

Articles