Dinamik javascript / CSS oluşturma çözümleri


15

Mevcut bağlama bağlı olarak javascript veya CSS kodu oluşturmanız gerektiğini varsayalım.

Örneğin, ana sayfada, gönderildiğinde bir ajax isteği gönderen bir form ve tek sayfada farklı bir form var. Veya CSS söz konusu olduğunda, kullanıcılarının kendi düzenlerini oluşturmalarına, renklerini değiştirmelerine vb. İzin veren bir tema oluşturmak istersiniz.

Şimdiye kadar gördüğüm çözümler:

  1. Kodu belgenin baş bölümüne (veya JS olması durumunda sonuna) ekleyin

  2. Kodu çıkaran site.com?get_assets gibi özel bir istekte bulunun . Bu yavaştır çünkü WP iki kez yüklenir.

  3. Belli bir süre geçici dosyalarda saklayın ve oradan yükleyin. Herkese açık temalar veya eklentiler için çok güvenilir değil.

  4. Yalnızca Javascript - her seferinde yüklenen normal bir dosyaya koyarak statik hale getirin. Bu durumda, kodunuzun herhangi bir durumu işlemesini sağlamanız gerekir

Başkalarını tanıyor musun? Hangi yöne giderdin?


çözüm 1 ile karşılaştığım bir sorun tarayıcı tarafından önbellekleme, kod sayfa yeniden yükleme yenilenmez.
Aurovrata

Yanıtlar:


9

Ek bir seçenek, geçmeniz gereken parametrelerin türüne bağlı olarak. Diyelim (2a). Dinamik olarak oluşturulan text/cssveya text/javascriptyerine çıktı veren PHP komut dosyaları oluşturabilir text/htmlve onlara WordPress'i yüklemek yerine GET parametrelerini kullanarak ihtiyaç duydukları verileri sağlayabilirsiniz. Tabii ki bu sadece nispeten az sayıda nispeten kompakt parametre geçmeniz gerektiğinde işe yarar. Örneğin, yalnızca bir gönderinin URL'sini veya bir dosyanın dizinini veya benzerini girmeniz gerektiğini varsayalım, şöyle bir şey yapabilirsiniz:

Header.php dosyasında:

 <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 dosyasında:

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

vb.

Ancak bu yalnızca GET parametrelerinde doğrudan geçirilen verilere erişmenizi sağlar; ve yalnızca geçmeniz gereken şeylerin sayısı nispeten azsa ve bu şeylerin temsili nispeten kompaktsa işe yarayacaktır. (Temelde bir avuç dize veya sayısal değer - bir kullanıcı adı, söz veya dizin; kullanıcının son gönderilerinin veya bunun gibi bir şeyin listesi değil.)

Bu seçeneklerden hangisinin en iyisi olduğu - bilmiyorum; Bu sizin kullanım durumunuza bağlıdır. Seçenek (1), basit olmanın avantajına sahiptir ve WordPress'i iki kez yüklemenin performans isabeti olmadan, muhtemelen ihtiyacınız olabilecek herhangi bir WordPress verilerine erişmenizi sağlar. Güçlü bir nedeniniz olmadıkça (örneğin, kullanmanız gereken stil sayfasının veya komut dosyasının boyutu nedeniyle) neredeyse yapmanız gereken şeydir.

Boyut, bir sayfanızın ağırlığı açısından soruna neden olacak kadar büyük olursa, (2) veya (2a) öğesini deneyebilirsiniz.

Ya da - bu muhtemelen daha iyi bir fikirdir - betiğin veya stil sayfasının dinamik olarak kullanılan kısımlarını statik olarak belirtilebilen parçalardan ayırmayı deneyebilirsiniz. # My fancy öğesi için bir arka plan parametresi ayarlamak üzere WordPress'ten bir dizinden geçirilmesi gereken bir stil sayfanız olduğunu varsayalım. Tüm bunları ana elemana koyabilirsiniz:

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

Ama bunu neden yapmanız gerek? Burada WordPress'ten gelen verilere bağlı tek bir satır var. Yalnızca WordPress'e bağlı satırları ayırmak daha iyidir:

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

Diğer her şeyi, standart bir bağlantı öğesiyle (style.css veya başka bir şey) yüklediğiniz statik bir stil sayfasına koyun:

 #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 ... */

Ve kaskatın işi yapmasına izin ver.

Aynı şey JavaScript yapmak için de geçerlidir:

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

Bunun yerine ana öğeye böyle bir şey koyun:

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

Ve sonra geri kalanını statik bir JavaScript dosyasına bırakın, genel WordPressPostData.url ve WordPressPostData.author öğelerinden yararlanmak için my_huge_function () ve my_other_function () öğelerini yeniden yazın.

40K CSS veya 40K JS neredeyse her zaman dinamik verilere bağlı olarak <1K'ya bölünebilir ve geri kalanı statik bir harici dosyada belirtilebilir ve daha sonra kaskad (CSS için) veya global olarak erişilebilir olarak yeniden birleştirilebilir değişkenler (globaller, DOM öğeleri veya JS için tercih ettiğiniz diğer cubby-hole).


Mükemmel cevap!
scribu

2
Sadece küçük bir ekleme: JS durumunda, dinamik değişkenler eklemek için wp_localize_sciprt kullanabiliriz .
Anh Tran

6

Dinamik CSS kasası oldukça basittir.

Yalnızca, <style type="text/css"></style>etiketlerin içindeki dinamik CSS tanımlarını çıkaran bir işlev oluşturun ve ardından bu işlevi içine bağlayın wp_print_styles. Örneğin

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

Veya önceden yapılandırılmış renk şemalarınız olduğunu varsayalım; geçerli kullanıcı ayarına göre uygun stil sayfasını sıralayabilirsiniz:

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

Bu durumda, wp_enqueue_scriptsWordPress'in bir wp_enqueue_styleseylem kancası olmadığından işlevin kancalandığını unutmayın .


1
1 ile aynı). Şu anda yaptığım şey bu, ancak 40K CSS'ye sahipseniz, hantal bir html belgesi
alıyorsunuz

1
Ama bu 40K CSS bir yerlerde üretilmeli , değil mi? Ve kesinlikle # 1 ile aynı, ancak WordPress'e dinamik CSS enjekte etmenin doğru yolu . :)
Chip Bennett

2

Bunu bir süredir düşünüyordum. Sorunuz bana geri dönmemi sağlıyor. İyi bir fikir ya da değil emin değilim, bu yüzden uzmanlar bu konuda yorum istiyorum.

Ya ben php aracılığıyla javascript / css dosyası yazmak yönetici verilerini kaydederken. Kullanıcı düzeni tekrar değiştirene kadar (bir kullanıcı çok sık yapamayabilir) tek seferlik bir yazma olacaktır. Bu şekilde, kullanıcı ayarları için veritabanına kullanıcı verileri kaydederken yalnızca bir kez erişiriz.

Dosyayı yazdıktan sonra normal bir javascript / css dosyası olacak, bu yüzden tema her yüklendiğinde veritabanını çağırmak zorunda değiliz.

Cevaplanması gereken bir soru: Bir ziyaretçi php dosyayı yazarken anında siteye erişmeye çalıştığında ne olacak?

Ne düşündüğü söyle.


Bu dosyaları wp-content/uploads(WP kodundan yazılabileceği garanti edilen tek dizin) içinde oluşturursanız, bu geçerli bir yaklaşım olabilir. Bence WP Core bu tekniği bir js dosyası için kullanıyor.
scribu

Dezavantajı, gerçekten dinamik olmaması, yani tüm sayfalardaki herkes için aynı olmasıdır. Her varyasyon için yeni bir dosya oluşturmanız gerekir. Bahsettiğiniz gibi tema / eklenti seçenekleri için hala iyi bir yaklaşım.
scribu

@scribu: evet bu doğru. böyle bir şey için bir karışıklık olabilir. kullanıcılara özelleştirilmiş bir profil sayfası verir ve her birine dosya yazmak zorunda kalırsak. Ama bu görsel web koyucuya vb kullanıcı renk değiştirdiğini ve (bu soruya itibariyle) çeşitli efektler eklemek (sürükle ve bırak) yaparsanız gibi bir şey için iyi bir yaklaşım olabilir .. ve WPMU ile kombine edilebilir;)
Sisir

1

Ayrı bir dosyaya dahil etmek istemeyebileceğiniz küçük komut dosyaları için, örneğin dinamik olarak oluşturuldukları için WordPress 4.5 ve daha fazlası sunar wp_add_inline_script. Bu işlev temel olarak komut dosyasını başka bir komut dosyasına kilitler. Diyelim ki bir tema geliştiriyorsunuz ve müşterinizin seçenekler sayfasında kendi komut dosyalarını (Google Analytics veya AddThis gibi) ekleyebilmesini istiyoruz. Örnek .

Stiller için wp_add_inline_styletemelde aynı şekilde çalışır. Örneğin, tüm özelleştirici modlarınız arasında dolaşmak ve bunları adlı bir dizede toplamak için kullanırsınız $all_mods; bu, daha sonra ana stil sayfanıza şöyle eklersiniz:

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

-2

Dinamik bir JS.php dosyası oluşturun ve bu dosyaya önemli query_vars besleyin. Bu değişkenler $_GETdosyanın bağlamı belirlemesine yardımcı olur ve içinde önbellekleyebilir ve readfile()gelecekteki istekler için kullanabilirsiniz ... ne olursa olsun.

wp-load.phpWP işlevlerine erişebilmeniz için dosyanın her şeyden önce yüklendiğinden emin olun . Eklenti yerleşimi ne olursa olsun, geçerli klasöre göreceli yol kullanın (dirname(__FILE__))veya klasör yapısında inen kazı yapın wp-load.php.

Her yerden wp-load.php aramak için kodlama

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

Şerefe Scribu!

Not : Klasörlerin normal WP azalan yapısını izlemediği karmaşık yapılar için, üst eklentiler bilgileri doğrudan erişilebilir dosyalarla paylaşabilir. CSS kılan dinamik bir PHP dosyası ile gelir Bir ebeveyn eklenti / JS bir dosyaya yazabilir realpath()ait wp-load.phpve bağımsız dosya kullanabiliriz. Bu, WP kullanıcılarının% 0.1'i için bir sorun olacaktır. Klasörleri hareket ettiren ve normal yapıyı takip etmeyenlerin ne yaptıklarını bildiklerini ve muhtemelen wp-load.phpdoğrudan yüklenmesi gereken PIMP eklentilerini bence .


Şirin! Nefret edenler, lütfen açıklama ekleyiniz. Beni aydınlat. Teşekkürler;) xoxo
EarnestoDev

wp-load.phpBir tema veya eklenti dosyasından eklemek kötü bir uygulamadır , çünkü wp-contentve / veya plugins dizinler kök WP dizinine göre herhangi bir yerde olabilir. WP_CONTENT_DIR ve WP_PLUGINS_DIR öğelerini unutmayın.
scribu

1
@scribu Ve bağımsız dosya bir üst eklenti ile birlikte çalışabilir. Üst eklenti wp-load.php dosyasını bulunduğu klasörde saklayabilir ve dinamik js üreteci onu oradan okuyabilir. Basit ...
EarnestoDev

1
Evet, üst eklenti yaklaşımı işe yarayabilir. Cevabınıza yazın ve aşağı oyumu kaldıracağım. Not: Bu site İngilizcedir; Rumence konuşmaya devam ederseniz sorun yaşayabilirsiniz.
scribu

5
Tutumu kes. Manuel çekirdek yükü uygulanabilir bir tekniktir, ancak çoğu şey için iyi ilk seçimden uzaktır. Kimse çalıştırabileceğinden şüphe duymuyor. Oylar beyninizle değil cevabınızın kalitesi ile ilgilidir.
Rarst
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.