동적 자바 스크립트 / CSS 생성을위한 솔루션


15

현재 컨텍스트에 의존하는 자바 스크립트 또는 CSS 코드를 생성해야한다고 가정 해 봅시다.

예를 들어, 제출시 ajax 요청을 시작하는 양식이 있고 단일 페이지에 다른 양식이 있습니다. 또는 CSS의 경우 사용자가 자신의 레이아웃을 만들고 색상을 변경하는 등의 테마를 만들려고합니다.

지금까지 내가 본 솔루션 :

  1. 문서의 헤드 섹션에 코드를 포함 시키십시오 (또는 JS의 경우 끝에)

  2. site.com?get_assets 와 같이 코드를 출력하는 특수 요청을 수행하십시오 . WP가 두 번로드되기 때문에 속도가 느립니다.

  3. 특정 시간 동안 임시 파일에 저장 한 다음로드하십시오. 공개 테마 또는 플러그인에 대해서는 매우 신뢰할 수 없습니다.

  4. Javascript 전용-매번로드되는 일반 파일에 넣어서 정적으로 만듭니다. 이 경우 코드가 모든 상황을 처리하도록해야합니다.

당신은 다른 사람을 알고 있습니까? 어느쪽으로 갈까요?


솔루션 1에서 발생한 한 가지 문제는 브라우저에서 캐싱하는 것이며 페이지를 다시로드 할 때 코드가 새로 고쳐지지 않습니다.
Aurovrata

답변:


9

전달해야하는 매개 변수의 종류에 따라 하나의 추가 옵션이 있습니다 (2a). 또한 동적으로 생성 text/css되거나 text/javascript보다 출력되는 PHP 스크립트를 생성 text/html하고 WordPress를로드하는 대신 GET 매개 변수를 사용하여 필요한 데이터를 제공 할 수 있습니다. 물론 이것은 상대적으로 적은 수의 비교적 작은 매개 변수를 전달해야하는 경우에만 작동합니다. 예를 들어 게시물의 URL이나 파일의 디렉토리 또는 이와 유사한 디렉토리 만 전달해야한다고 가정하면 다음과 같이 할 수 있습니다.

header.php에서 :

 <script type="text/javascript" src="<?php print get_stylesheet_directory_uri(); 
 ?>/fancy-js.php?foo=bar&amp;url=<?php print urlencode(get_permalink($post->ID)); ?>"></script>

fancy-js.php에서 :

 <?php
 header("Content-type: text/javascript");
 ?>
 foo = <?php print json_encode($_GET['foo']); ?>;
 url = <?php print json_encode($_GET['url']); ?>;

기타

그러나 이는 GET 매개 변수에 직접 전달 된 데이터에만 액세스 할 수있게합니다. 전달해야 할 것들의 수가 상대적으로 적고 그러한 것들의 표현이 상대적으로 작은 경우에만 작동합니다. (기본적으로 소수의 문자열 또는 숫자 값 (사용자 이름, 말 또는 디렉토리). 사용자의 모든 최근 게시물 목록 등이 아님)

이러한 옵션 중 어느 것이 가장 좋은지에 대해서는 잘 모르겠습니다. 사용 사례에 따라 다릅니다. 옵션 (1)은 단순하다는 장점이 있으며, WordPress를 두 번로드하는 성능 저하없이 필요한 워드 프레스 데이터에 명확하게 액세스 할 수 있습니다. 하지 말아야 할 강한 이유가 없다면 (예 : 스타일 시트 나 스크립트의 크기 때문에)해야 할 일이 거의 확실합니다.

한 페이지의 무게와 관련하여 문제를 일으킬 정도로 크기가 커지면 (2) 또는 (2a)를 시도해보십시오.

또는 그렇지 않으면-아마도 더 좋은 아이디어 일 것입니다-실제로 동적 데이터를 사용하는 스크립트 부분이나 스타일 시트를 정적으로 지정할 수있는 부분과 분리하려고 시도 할 수 있습니다. # my-fancy 요소의 배경 매개 변수를 설정하기 위해 WordPress에서 디렉토리를 전달해야하는 스타일 시트가 있습니다. 이 모든 것을 head 요소에 넣을 수 있습니다.

 <style type="text/css">
 #my-fancy-element {
      background-image: url(<?php print get_stylesheet_directory_uri(); ?>images/fancy.png);
      padding: 20px;
      margin: 20px;
      font-weight: bold;
      text-transform: uppercase;
      font-size: 12pt;
      /* ... KB and KB of additional styles ... */
 }
 #another-fancy-element {
     /* ... KB and KB of additional styles ... */
 }
 /* ... KB and KB of additional styles ... */
 </style>

그러나 왜 그렇게해야합니까? 여기에는 WordPress의 데이터에 의존하는 한 줄만 있습니다. WordPress에 의존하는 행만 분리하는 것이 좋습니다.

 <style type="text/css">
 #my-fancy-element {
      background-image: url(<?php print get_stylesheet_directory_uri(); ?>images/fancy.png);
 }
 </style>

표준 링크 요소 (style.css 등)로로드하는 정적 스타일 시트에 다른 모든 것을 넣습니다.

 #my-fancy-element {
      /* background-image provided dynamically */
      padding: 20px;
      margin: 20px;
      font-weight: bold;
      text-transform: uppercase;
      font-size: 12pt;
      /* ... KB and KB of additional styles ... */
 }
 #another-fancy-element {
     /* ... KB and KB of additional styles ... */
 }
 /* ... KB and KB of additional styles ... */

그리고 계단식으로 작업을 수행하십시오.

자바 스크립트도 마찬가지입니다.

 <script type="text/javascript">
 // Here comes a huge function that uses WordPress data:
 function my_huge_function () {
     // Do a million things ...

     jQuery('#my-fancy').append('<a href="'+<?php json_encode(get_permalink($GLOBALS['post']->ID)); ?>+'">foo</a>);

     // Do a million more things ...

     my_other_function(<?php print json_encode(get_userdata($GLOBALS['post']->post_author); ?>);
 }

 function my_other_function (user) {
     // Do a million things ...
 }
 </script>

대신 head 요소에 다음과 같은 것을 넣으십시오.

 <script type="text/javascript">
 var WordPressPostData = {
 url: <?php print json_encode(get_permalink($GLOBALS['post']->ID)); ?>,
 author: <?php print json_encode(get_userdata($GLOBALS['post']->post_author)); ?>
 }
 </script>

그런 다음 나머지는 정적 JavaScript 파일에 놓고 my_huge_function () 및 my_other_function ()을 다시 작성하여 전역 WordPressPostData.url 및 WordPressPostData.author를 사용하십시오.

CSS의 40K 또는 JS의 40K는 거의 항상 동적 데이터에 의존하는 <1K로 분할 될 수 있으며, 나머지는 정적 외부 파일에 지정되어 캐스케이드 (CSS의 경우) 또는 전역 액세스 가능한 파일을 사용하여 다시 결합 될 수 있습니다. 변수 (전역, DOM 요소 또는 JS의 다른 큐비 홀).


훌륭한 답변!
scribu

2
JS의 경우 wp_localize_sciprt 를 사용 하여 동적 변수를 추가 할 수 있습니다 .
Anh Tran

6

동적 CSS 사례는 매우 간단합니다.

<style type="text/css"></style>태그 안에 동적 CSS 정의를 출력하는 함수를 만든 다음 해당 함수를에 연결하십시오 wp_print_styles. 예 :

<?php
function mytheme_dynamic_css() {
    $options = get_option( 'mytheme_options' );
    ?>
    <style type="text/css">
    /* Dynamic H1 font family */
    h1 { font-family: <?php echo $options['h1_font_family']; ?>;
    </style>
    <?php
}
add_action( 'wp_print_styles', 'mytheme_dynamic_css' );
?>

또는 미리 구성된 색 구성표가 있다고 가정 해 봅시다. 현재 사용자 설정에 따라 적절한 스타일 시트를 큐에 넣을 수 있습니다.

<?php
function mytheme_enqueue_colorscheme_stylesheet() {
    $options = get_option( 'mytheme_options' );
    $color_scheme = $options['color_scheme'];
    wp_enqueue_style( $colorscheme, get_template_directory_uri() . '/css/' . $color_scheme . '.css' );
}
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_colorscheme_stylesheet' );
?>

이 경우 wp_enqueue_scriptsWordPress에 wp_enqueue_styles작업 후크 가 없으므로 함수 가에 연결됩니다.


1
1)과 동일합니다. 이것은 내가 지금 뭘하는지,하지만 당신은 CSS의 40K 같은 경우는 부피가 큰 HTML 문서를 얻을
onetrickpony

1
그러나 CSS의 40K는 어딘가에 출력되어야합니다 . 그리고 # 1과 동일하지만 WordPress에 동적 CSS를 삽입 하는 올바른 방법 입니다. :)
Chip Bennett

2

나는 한동안 그것을 생각하고 있었다. 귀하의 질문으로 다시 연락을 드리겠습니다. 그것이 좋은 아이디어인지 확실하지 않으므로 전문가 의견을 말하고 싶습니다.

어떤 경우에는 내가 PHP를 통해 자바 스크립트 / CSS 파일을 작성 관리자 데이터를 저장할 때. 사용자가 레이아웃을 다시 변경할 때까지 한 번 작성합니다 (너무 자주하지 않을 수 있음). 그렇게하면 사용자가 데이터를 저장할 때 한 번만 사용자 설정을 위해 데이터베이스에 액세스합니다.

파일을 작성한 후에는 일반적인 javascript / css 파일이되므로 테마가로드 될 때마다 데이터베이스를 호출 할 필요가 없습니다.

대답해야 할 한 가지 질문 : PHP가 파일을 작성할 때 방문자가 즉시 사이트에 액세스하려고하면 어떻게됩니까?

당신이 무슨 생각을하는지 제게 알려주세요.


이러한 파일 wp-content/uploads을 WP 코드에서 쓸 수있는 유일한 디렉토리 에서 생성하는 경우 실행 가능한 접근 방법이 될 수 있습니다. WP Core조차도 하나의 js 파일 에이 기술을 사용한다고 생각합니다.
scribu

단점은 실제로 동적이지 않다는 것입니다. 즉, 모든 페이지의 모든 사람에게 동일합니다. 각 변형에 대해 새 파일을 생성해야합니다. 앞서 언급했듯이 여전히 테마 / 플러그인 옵션에 대한 좋은 접근 방식입니다.
scribu

@scribu : 그렇습니다. 그것은 같은 것을 혼란스럽게 할 수 있습니다. 사용자에게 사용자 정의 된 프로파일 페이지를 제공하고 각각에 파일을 작성해야하는 경우 그러나 사용자가 색상을 변경하고 (이 질문에 따라) 다양한 효과를 추가하고 WPMU와 결합 할 수있는 시각적 웹 사이트 메이커 (드래그 앤 드롭)를하는 경우와 같은 좋은 방법 일 수 있습니다.
Sisir

1

예를 들어 스크립트가 동적으로 생성되기 때문에 별도의 파일에 포함하고 싶지 않은 작은 스크립트 조각의 경우 WordPress 4.5 및 기타 기능이 제공 wp_add_inline_script됩니다. 이 기능은 기본적으로 스크립트를 다른 스크립트에 고정시킵니다. 예를 들어, 테마를 개발 중이며 고객이 옵션 페이지를 통해 자신의 스크립트 (예 : Google Analytics 또는 AddThis)를 삽입 할 수 있기를 원한다고 가정 해 보겠습니다. .

스타일의 경우 wp_add_inline_style기본적으로 동일하게 작동합니다. 예를 들어, 모든 커 스터 마이저 모드를 반복하고라는 문자열로 모아서 $all_mods다음과 같이 메인 스타일 시트에 추가합니다.

if (!empty($all_mods)) wp_add_inline_style ('main-style', $all_mods);

-2

동적 JS.php 파일을 생성하고 중요한 query_vars를 제공하십시오. 이러한 변수 $_GET는 파일이 컨텍스트를 결정하는 데 도움이되며 캐시하고 사용할 수 있습니다readfile() 되며 향후 요청에 .

파일이 wp-load.php다른 것보다 먼저 로드 되도록해야하므로 WP 기능에 액세스 할 수 있습니다. 현재 폴더의 상대 경로를 사용 (dirname(__FILE__))하거나 폴더 구조에서 내림차순으로 내림차순으로 찾으십시오.wp-load.php플러그인 위치에 관계없이 으로 파 내십시오.

어디서나 wp-load.php를 찾는 코드

// Ensure single declaration of function!
if(!function_exists('wp_locate_loader')):
    /**
     * Locates wp-load.php looking backwards on the directory structure.
     * It start from this file's folder.
     * Returns NULL on failure or wp-load.php path if found.
     * 
     * @author EarnestoDev
     * @return string|null
     */
    function wp_locate_loader(){
        $increments = preg_split('~[\\\\/]+~', dirname(__FILE__));
        $increments_paths = array();
        foreach($increments as $increments_offset => $increments_slice){
            $increments_chunk = array_slice($increments, 0, $increments_offset + 1);
            $increments_paths[] = implode(DIRECTORY_SEPARATOR, $increments_chunk);
        }
        $increments_paths = array_reverse($increments_paths);
        foreach($increments_paths as $increments_path){
            if(is_file($wp_load = $increments_path.DIRECTORY_SEPARATOR.'wp-load.php')){
                return $wp_load;
            }
        }
        return null;
    }
endif;
// Now try to load wp-load.php and pull it in
$mt = microtime(true);
if(!is_file($wp_loader = wp_locate_loader())){
    header("{$_SERVER['SERVER_PROTOCOL']} 403 Forbidden");
    header("Status: 403 Forbidden");
    echo 'Access denied!'; // Or whatever
    die;
}
require_once($wp_loader); // Pull it in
unset($wp_loader); // Cleanup variables

건배, Scribu!

추신 : 폴더가 일반적인 WP 감소 구조를 따르지 않는 복잡한 구조의 경우 상위 플러그인은 직접 액세스 가능한 파일과 정보를 공유 할 수 있습니다. CSS를 렌더링하는 동적 PHP 파일과 함께 제공 부모 플러그인 / JS는 파일에 쓸 수 realpath()wp-load.php및 독립 실행 형 파일이 해당 사용할 수 있습니다. 이는 WP 사용자의 0.1 %에게 문제가됩니다. 폴더를 옮기고 정상적인 구조를 따르지 않는 사람들은 자신이하는 일을 알고 있으며 wp-load.php직접 로드 해야하는 PIMP 플러그인을 사용할 수 있다고 생각합니다 .


귀엽다! 증오 자, 설명을 추가하십시오. 날 깨워 줘 감사합니다;) xoxo
EarnestoDev

wp-load.php테마 또는 플러그인 파일에서 포함 하는 것은 좋지 않습니다 . wp-content및 / 또는 plugins 디렉토리는 루트 WP 디렉토리와 관련이있을 수 있습니다. WP_CONTENT_DIR 및 WP_PLUGINS_DIR을 기억하십시오.
scribu

1
@scribu 그리고 독립형 파일은 부모 플러그인과 협업 할 수 있습니다. 부모 플러그인은 wp-load.php를 위치한 폴더에 저장할 수 있으며 동적 js 생성기는 해당 폴더에서 읽을 수 있습니다. 간단한 ...
EarnestoDev

1
예, 부모 플러그인 접근 방식이 작동 할 수 있습니다. 당신의 대답에 그것을 쓰십시오. 나는 downvote를 제거 할 것입니다. 추신 :이 사이트는 영어로되어 있습니다; 루마니아어로 계속해서 의견을 남기면 문제가있을 수 있습니다.
scribu

5
태도를 자르십시오. 수동 코어로드는 실용적 기술이지만 대부분의 경우 첫 번째 좋은 선택과는 거리가 멀습니다. 아무도 당신이 그것을 작동시킬 수 있는지 의심하지 않습니다. 투표는 두뇌가 아니라 답변의 질에 관한 것입니다.
Rarst
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.