система шаблонов php - правильный способ загрузить поведение Javascript по умолчанию для шаблона - PullRequest
2 голосов
/ 15 февраля 2011

Положение:

  1. Система шаблонов PHP, отвечающая за создание страниц HTML.
  2. Все основные функции Javascript находятся во внешних файлах
  3. Каждый шаблон имеет несколько функций Javascript по умолчанию, которые необходимо вызывать для каждого шаблона /

Когда страница отображается, мне нужно вызвать набор функций Javascript: т.е. 1011 *

<script type="text/javascript">
     $(document).ready(function{
         API.loadThis();  // all these Javascript functions are in an external JS file
         API.loadThat();
         API.buildDateSelector("#idForSelector");
         // etc
    });
</script>

До сих пор я только что добавил это как текст к каждому из шаблонов HTML. Однако в случае Страницы, которая состоит из нескольких меньших шаблонов (каждый из которых, возможно, содержит свой собственный Javascript инициализации), тогда у меня есть несколько бит встроенного Javascript, разбросанных по всей моей веб-странице.

Мой вопрос:

  1. как мне правильно организовать все так, чтобы я мог легко "зарегистрировать" или "вызвать" некоторый Javascript по умолчанию для вызова при загрузке страницы?
  2. Или уместно ли добавлять каждый блок Javascript в каждый шаблон (как выше)?

Ответы [ 2 ]

1 голос
/ 15 февраля 2011

То, что я бы сделал, очень похоже на @Chris.Однако я бы предложил несколько небольших изменений:

  1. Добавить параметр в функцию addJS, который указывает позицию на странице.По умолчанию у вас должна быть поддержка как минимум head и foot (head поместит его в голову, foot поместит его прямо перед закрытием </body>).

    public function addJS($string, $position = 'head') {
        if (!is_array($this->js[$position])) {
            $this->js[$position] = array($string);
        } elseif (!in_array($string, $this->js[$position])) {
            $this->js[$position][] = $string;
        }
    }
    

    Затем включите токены в шаблон, чтобы указать позиции:

        {{js_head}}
    </head>
    <body>
        <!--content here-->
        {{js_foot}}
    </body>
    

    Затем при рендеринге просто сделайте что-то вроде:

    $js = $this->js;
    $positions = preg_replace_callback(
        '/{{js_(inline_)?([a-zA-Z0-9]+)}}/', 
        function ($match) use ($js) {
            if (isset($js[$match[2]])) {
                $js = implode("\n", $js[$match[2]]);
                if ($match[1] == 'inline') {
                    return $js;
                } else {
                    return '<script type="text/javascript">'.$js.'</script>';
            }
            return '';
        },
        $templateBody
    );
    

    Сейчасреальное преимущество заключается в том, что ваши шаблоны могут четко и тривиально определять свои собственные позиции для повторно используемых и часто используемых битов:

    $this->addJS('return this.form.submit();', 'submit_form');
    $html = '
        <input type="text" onblur="{{js_inline_submit_form}}" />
        <button name="submit" onclick="{{js_inline_submit_form}}" />
    ';
    

    Это может быть весьма полезным, поскольку теперь вы не дублируете вызовы JS вездев вашем коде.Кроме того, это сократит издержки, связанные с переносом каждого вывода в теги <script> (поскольку он охватывает всю позицию в тегах, а не каждый фрагмент содержимого) ...

  2. Это позволит вам затем взять все не встроенные файлы JS и скомпилировать серию файлов во время выполнения для отправки в браузер, чтобы позаботиться о кэшировании.Это добавляет преимущество, заключающееся в том, что вы можете сохранять свой JS близким к вашим представлениям (для удобства обслуживания), при этом все еще обслуживая кэшированный JS, и не нужно повторно отправлять его каждый раз ...

    public function buildJSCache($position) {
        if (!isset($this->js[$position]) || empty($this->js[$position])) {
            return '';
        }
        $file = implode($this->js[$position]);
        $name = 'js/'.md5($file) .'.js';
        if (!file_exists($name)) {
            file_put_contents($name, $file);
        }
        return $name;
    }
    

    Затем в вашемкод шаблона, просто сделайте:

    $replace = $this->buildJSCache('head');
    if ($replace) {        
        $replace = '<script type="text/javascript" src="'.$filename.'"></script>';
    }
    $template = str_replace('{{js_head}}', $replace, $template);
    

    Вы получаете двойной выигрыш в удобстве обслуживания и скорости (вы даже можете уменьшить его, если хотите).

Примечание: весь этот код является только демонстрационным, если бы вы использовали его в производстве, я бы его почистил и подумал немного дальше ...

Это, по крайней мере, мои 0,02 доллара ...

0 голосов
/ 15 февраля 2011

Есть много способов сделать это.Я предлагаю вам приобрести некоторые фреймворки с открытым исходным кодом, посмотреть, как они работают, и определиться с вашими предпочтениями.Некоторые методы считаются «наилучшей практикой», но большая часть структуры фреймворка сводится к предпочтениям разработчика.

У меня есть фреймворк, который я использую для своих собственных проектов, который похож на то, что вы описываете, каждый из меньшихШаблоны называется «компонент».Каждый компонент может добавлять любое количество javascript к себе, используя метод addJS(), аналогично для css и html.Контроллер верхнего уровня просматривает содержимое данной страницы (с точки зрения компонентов).Это дает мне возможность загружать все css, javascript и html заранее.Затем я могу вывести их в любом порядке.

Итак:

  • контроллер страницы обрабатывает запрос
    • в одном или нескольких компонентах
      • component load метод заполняет свойства класса html, javascript и css (массивы имен файлов, строки для html) для себя
      • компоненты имеют свой собственный набор шаблонов, js, css
    • выводит шаблоны для всего сайта
      • включает в себя все css компонента в заголовке страницы
    • перебирает компоненты, выводит html компонента, материал макета
    • выводит компонент JS для нижнего колонтитула

У меня есть папка components, внутри которой находятся папки для каждого компонента.В каждой папке компонента находится php-файл (обработчик этого компонента), необязательно один или несколько файлов css / js.Благодаря этому все хорошо организовано.

...