Local by Volan için Özel bir eklenti oluşturma


Güncelleme: Bu yazı, uygulama Flywheel tarafından satın alınmadan ve adı “Yerel” olarak değiştirilmeden önce Pressmatic hakkında yazılmıştır. Gönderinin metnini ve kodun çoğunu bu değişikliği yansıtacak şekilde güncelledim.

Birkaç yıldan fazla bir süredir WordPress siteleri geliştiriyorsanız, MAMP'ı veya bu şekilde hareket ederseniz muhtemelen WAMP'ı duymuşsunuzdur. Hatta beş yıl veya daha uzun bir süredir bir Mac üzerinde WordPress siteleri geliştiriyorsanız, o zamanın büyük bir bölümünde MAMP'ı neredeyse kesinlikle kullanmışsınızdır. seni baştan çıkaracak başka pek bir şey olmadı.

Vagrant biraz vudu gibidir ve yeni bir VVV kurulumu kurmak yeterince kolay olsa da, MAMP'ta yeni bir ana bilgisayar oluşturmak kadar kolay değildir. DesktopServer güzel bir seçenek, WordPress'i kendiniz kurma zahmetini ortadan kaldırıyor, ancak aynı zamanda biraz basit hissettiriyor, sanki basit olma uğruna sizden biraz fazla şey saklıyormuş gibi.

Yakın zamana kadar, WordPress'i yerel olarak geliştirmek için ana seçenekleriniz bunlardı (ayrıntılı bir inceleme mi arıyorsunuz? En İyi 4 Yerel WordPress Geliştirme Ortamımıza göz atın) – hiçbiri gerçekten harika görünmüyor, hiçbiri gerçekten oluşan modern araç gibi hissetmiyor modern bir web geliştirici yığınının temeli. Clay Griffiths'i daha iyi bir şey inşa etmeye yönlendiren şeyin bu duygu olduğunu tahmin edebiliyorum, Local.

Modern Geliştirici için Modern Araçlar

Local, web geliştiricilerinin JavaScript ve HTML kullanarak yerel masaüstü uygulamaları oluşturmasına olanak tanıyan bir uygulama çerçevesi olan Electron'un üzerine inşa edilmiştir. Electron'u daha önce duyduysanız, muhtemelen kendisini “21. yüzyılın hacklenebilir metin editörü” olarak faturalandıran ana projesi Atom aracılığıyladır ve Local'in sadece “21. yüzyıl için hacklenebilir yerel geliştirme ortamı olabileceğini iddia ediyorum. ”.

Docker, Local için perde arkasındaki ağır işleri yapıyor ve bu da onu hızlı ve taşınabilir hale getiriyor. Docker ile çok uğraştıysanız, muhtemelen onun hakkında iki şey biliyorsunuzdur: çok güçlü ve çok karmaşık. Local, hem gücünden yararlanan hem de Docker kapsayıcılarını verimli bir kullanıcı arayüzünün arkasında çalıştırmanın karmaşıklığını gizleyen her iki açıdan da harika bir soyutlama olduğunu kanıtlıyor.

Local, Atom gibi açık kaynak olmasa da, geliştiricilerin WordPress'e benzer kancalar kullanarak işlevselliğini genişletmesine olanak tanıyan bir eklenti API'sine sahiptir. Kendi eklentilerinizi yazmaya başlamanız için Flywheel, MIT lisansı altında iki eklentinin yanı sıra Flywheel'in github'ına ilişkin bazı API belgelerini yayınladı.

Basit Bir Yerel Eklenti Yazma

Bunu yazdığım sırada, eklenti API belgeleri oldukça seyrek, ancak bana bunun yeterince yakında güncelleneceği söylendi. Şahsen, mümkün olduğunda belgeleri atlamayı seviyorum, bu yüzden bize GitHub'da kullanıma sunduğum örnek eklentilerden birinin soyulmuş bir versiyonuyla başlayacağım.

Başlarken

Başlamak için depoyu klonlayacağız:

 git clone [email protected]:JRGould/simple-pressmatic-addon.git my-pressmatic-addon && cd my-pressmatic-addon

NPM bağımlılıklarını yükleyin ve derleme komut dosyasını çalıştırın.

 npm install npm run-script build

Bu, lib dizinini oluşturacak ve src/renderer.js dosyasını ES2015'e aktaracak ve lib kopyalayacaktır.

Artık eklentiyi doğrudan Local'in addons klasörüne bağlayabiliriz:

 ln -s "$(pwd)" ~/Library/Application\ Support/Local\ by\ Flywheel/addons/

Yerel'i yeniden başlatabilir ve eklentinizi Ayarlar > Eklentiler'e gidip uygun şekilde "Yerel için Eklenti" adlı kutuyu işaretleyerek etkinleştirebilirsiniz.

eklentiyi etkinleştirme

Yerel, yeniden başlatmanızı ister ve ne zaman Chrome Geliştirici Araçları gibi göründüğünü görmelisiniz.

geliştirme araçları açık

Bu, Chrome Geliştirici Araçları'na benziyor, çünkü öyle! Daha önce bahsettiğim gibi Local, uygulamanın ön ucunu oluşturmak ve çalıştırmak için Chromium kullanan Electron üzerine kuruludur. Şimdiye kadar, eklentimizin yaptığı bu kadar, geliştirme araçlarını açar ve window nesnesine reload() adlı bir işlev ekler; bu, sizi Yerel'den çıkıp manuel olarak yeniden çalıştırmaya zorlamadan uygulamayı yeniden yükleyecektir. Bu, geliştirme sırasında bize birkaç döngü kazandırmalıdır. Devam edin ve geliştirici araçları konsoluna reload() yazıp enter tuşuna basarak bunu deneyin.

Kancaları Kullanmak

Artık eklentimiz çalıştığına ve değişikliklerimizi test etmek için uygulamayı hızla yeniden yükleyebildiğimize göre, bazı özel işlevler ekleyip ekleyemeyeceğimizi görelim. Referans için Yerel İstatistikler Eklentisini kullanarak, siteInfoMoreMenu filtresini kullanarak o eklentinin renderer.js dosyasında yapılan her sitenin “Diğer” menüsünün altına bir menü öğesi ekleyerek başlayacağız. Bu, WordPress'teki kancaları anımsatan herhangi bir deneyimli WordPress geliştiricisine tanıdık gelmelidir.

Aşağıdaki kodu kendi oluşturucumuza ekleyerek “Eklentiler” adlı bir menü öğesi eklemek için siteInfoMoreMenu filtresini kullanacağız renderer.js:

 hooks.addFilter( 'siteInfoMoreMenu', function( menu, site ) { menu.push( { label: 'Plugins', enabled: !this.context.router.isActive(`/site-info/${site.id}/my-component`), click: () => { context.events.send('goToRoute', `/site-info/${site.id}/my-component`); } } ); return menu; } );

Şimdi renderer.js dosyasını kaydedin, babel'e işini yapması için bir dakika verin ve ardından reload() . Artık bir siteye tıklayabilir ve “Diğer” menüsünü genişletebilirsiniz ve listeye “Eklentiler” eklendiğini görmelisiniz.

eklenen eklentiler menü öğesi

“Eklentiler”i tıklarsanız, my-component yolu olmadığından konsolda bir uyarı görmelisiniz ve reload() Yerel şimdi uyarı ve boş bir ekran alırsınız, bu nedenle muhtemelen çıkmak iyi bir fikirdir Yerel ve yeniden başlatın.

Bileşen Oluşturma

Özel bir bileşen oluşturarak yeni menü öğemizi gidecek bir yere verelim. src/ içinde MyComponent.js adlı yeni bir dosya oluşturarak başlayacağız ve aşağıdaki ortak tablo ile başlayacağız:

 /* src/MyComponent.js */ module.exports = function( context ) { const Component = context.React.Component const React = context.React const $ = context.jQuery return class SiteInfoStats extends Component { constructor( props ) { super( props ) // init class vars } componentDidMount() { // set up } componentWillUnmount() { // tear down } render() { return ( <div style={{ display: 'flex', flexDirection: 'column', flex: 1, padding: '0 5%' }}> <h3>Active Plugins</h3> </div> ); } } }

React konusunda çok bilgili değilim, bu yüzden sabredin ve herhangi bir iyileştirmeniz varsa lütfen yorumlarda bana bildirin, ancak bu, "Eklentiler" sayfamızı oluşturmak ve ihtiyaç duyabileceğimiz herhangi bir kurulum ve sökme işlemi yapmak için yeterli olacaktır. daha sonra yapmak için.

Şimdi sadece “Eklentiler” menü öğesini tıkladığımızda bu bileşenin görünmesini sağlamamız gerekiyor. Bunu, renderer.js bu bileşene routesSiteInfo içerik kancasıyla şöyle bir rota ekleyerek yapabiliriz:

 // Require component const MyComponent = require('./MyComponent')(context) // Get router handle const Router = context.ReactRouter // Add Route hooks.addContent( 'routesSiteInfo', () => { return <Router.Route key="site-info-my-component" path="/site-info/:siteID/my-component" component={ MyComponent }/> } );

Şimdi reload() , bir siteye tıklayabilir ve "Diğer" menüsünden "Eklentiler"i seçebilirsiniz. Bu noktada “Aktif Eklentiler” başlıklı boş bir ekranla karşılaşmalısınız.

eklentiler ekranı

Bir Şey Yapmasını Sağla…

Şimdiye kadar bu oldukça işe yaramaz, bu yüzden eklentimize bir şeyler yaptırabilecek miyiz bakalım. Bir kez daha rehberlik için Yerel İstatistikler Eklentisine bakacağız. Öyleyse, bir sitenin kapsayıcısında bir komutu nasıl çalıştırabileceğimizi ve çıktıyı nasıl alabileceğimizi görmek için SiteInfoStats.js bileşenine bir göz atalım.

Hâlâ MyComponent.js çalışıyoruz, öncelikle dosyanın en üstünde child_process modülünü zorunlu kılmak isteyeceğiz:

 const childProcess = require ('child_process' )

Bu, birazdan ekleyeceğimiz bir terminal komutu çalıştırmamıza izin verecek, ancak görünümde biraz daha fazla içerik ayarlayalım. İlk önce, kurucu yöntemine aşağıdakini ekleyerek bileşenimizin state bir content özelliği ekleyeceğiz:

 this.state = { content: null }

Ardından, oluşturma yöntemimizde “Aktif Eklentiler” başlığının altına { this.state.content } ekleyerek bu içeriği görüntüleyeceğiz:

 render() { return ( <div style={{ display: 'flex', flexDirection: 'column', flex: 1, padding: '0 5%' }}> <h3>Active Plugins</h3> { this.state.content } </div> ); }

Şimdi componentDidMount eklentinin çalışıp çalışmadığını anlayabiliriz. Değilse, state.content “Makine çalışmıyor!” diyecek şekilde ayarlayacağız. ve eğer öyleyse, birazdan oluşturacağımız getPluginList() adlı bir yöntemi çağıracağız.

 componentDidMount() { if ( 'running' === this.props.siteStatus ) { this.getPluginList(); } else { this.setState( { content: ( <p>Machine not running!</p> ) } ) } }

Şimdi getPluginList() yöntemini oluşturabiliriz. Orada yapacağımız ilk şey, state.content “yükleniyor…” şeklinde ayarlamak ve ardından mevcut site için docker konteynerinde wp plugin list çalıştıracak bir komut oluşturacağız:

 getPluginList() { this.setState( { content: <p>loading...</p> } ) // get site object using siteID let site = this.props.sites[ this.props.params.siteID ] // construct command using bundled docker binary to execute 'wp plugin list' inside container let command = `${context.environment.dockerPath} exec ${site.container} wp plugin list --path=/app/public --field=name --status=active --allow-root` }

Bu komutun sizi korkutmasına izin vermeyin, esasen docker exec [container id] wp plugin list... . Sondaki ekstra argümanlar, komutu docker exec çalıştırırken burada varsayılan olan kök kullanıcı olarak çalıştırmamıza ve wp plugin list yalnızca etkin eklentilerin adlarını döndürmesine neden olan kısıtlamalar belirlememize izin verir.

Şimdi sadece, ChildProcess sabitimizde bir tutamacımız olan ChildProcess child_process modülünü kullanarak komutu yürütmemiz gerekiyor. Arka planda olayları izlememiz gereken bir süreç oluşturmak yerine çıktıyı beklememize neden olacak ChildProcess.exec() 'i kullanacağız. Ayrıca, docker exec doğru docker ortamında çalışmasını sağlayacak env seçeneği olarak exec context.environment.dockerEnv ileteceğiz. İşte nasıl görüneceği:

 // execute command in docker env and run callback when it returns childProcess.exec( command, { env: context.environment.dockerEnv }, (error, stdout, stderr) => { // Display error message if there's an issue if (error) { this.setState( { content: ( <p>Error retrieving active plugin list: <pre>{stderr}</pre></p> ) } ) } else { // Display active plugins list this.setState( { content: <pre>{ stdout }</pre> } ) } } );

Yukarıdaki snippet'te, komutun bir hata döndürüp döndürmediğini kontrol eden ve ya hatayı ya da stdout değişkenini yazdıran son argüman olarak bir geri çağrı gönderiyoruz (bunu çalıştırırsanız ekranınıza ne yazdırılır) bir terminalden komut). Artık refresh() , çalışan bir siteye tıklayın ve “Aktif Eklentiler” başlığı altında aktif eklentilerin bir listesini görmelisiniz.

aktif eklentiler listesi

Çalışan çok sayıda siteniz varsa, loading... eklenti listesini görüntülemeye geçiş birkaç saniye sürebilir. Ayrıca, konsolda herhangi bir hata görürseniz, farklı bir eklentiden veya Yerel'in farklı bir bölümünden gelmiş olabileceğinden, kodumuzla ilgili olduklarından emin olmak için iki kez kontrol edin. Eklentimizde her şey yolunda gibi görünse de, sitelerin çalışmaması nedeniyle ara sıra uyarıların ortaya çıktığını fark ettim.

İşleri toparlamak için biraz biçimlendirme ve görüntülenecek eklenti yoksa bir mesaj ekledim. İşte getPluginList() yönteminin tamamı:

 getPluginList() { this.setState( { content: <p>loading...</p> } ) // get site object using siteID let site = this.props.sites[ this.props.params.siteID ] // construct command using bundled docker binary to execute 'wp plugin list' inside container let command = `${context.environment.dockerPath} exec ${site.container} wp plugin list --path=/app/public --field=name --status=active --allow-root` // execute command in docker env and run callback when it returns childProcess.exec( command, { env: context.environment.dockerEnv }, (error, stdout, stderr) => { // Display error message if there's an issue if (error) { this.setState( { content: <p>Error retrieving active plugin list: <pre>{stderr}</pre></p> } ) } else { // split list into array let plugins = stdout.trim().split( "\n" ) // Only create unordered list if there are plugins to list if ( plugins.length && plugins[0].length > 1 ) { this.setState( { content: <ul>{ plugins.map( (item) => <li key={ plugins.indexOf(item) }>{ item }</li> ) }</ul> } ) } else { this.setState( { content: <p>No active plugins.</p> } ) } } } ); }

Ve geliştirici araçları penceresini renderer.js göstermek için satırları kaldırdıktan sonra nihai ürün şu şekilde görünüyor:

nihai ürün

Toplama

Bugün oluşturduğumuz eklentinin Local'e yalnızca marjinal fayda sağladığını ve haklı olduğunuzu iddia edebilirsiniz, ancak heyecan verici olan şey, zaten güçlü bir geliştirme aracına herhangi bir şey ekleyebildiğimizdir. Genişletilebilir uygulamalar olasılığı, hem geliştiriciler hem de kullanıcılar için heyecan verici. Local by Flywheel, bize bu heyecan verici geleceği ilk gösterenlerden biri ve Electron platformu kullanılarak oluşturulan ve bu tür bir genişletilebilirliğe izin veren daha fazla uygulama görmeyi umuyorum.

Copyright statement: Unless otherwise noted, this article is Collected from the Internet, please keep the source of the article when reprinting.

Check Also

Divi's Theme Builder ile Özel Global Başlık Nasıl Oluşturulur

Artık Tema Oluşturucu burada olduğuna göre, web sitenizi A'dan Z'ye kurmanıza yardımcı olacak yeni eğitimlere dalmak için sabırsızlanıyoruz. Buna Divi'nin yerleşik seçeneğini kullanarak özel başlıklar oluşturma da dahildir. Bu eğitimde Divi's Theme Builder'ı kullanarak global bir başlık oluşturmaya odaklanacağız. Bu sayfaya veya gönderiye farklı bir başlık atamadıysanız, web sitenizin her yerinde genel bir başlık görünecektir.

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir