Yeoman SharePoint Generator kullanarak oluşturduğunuz WebPart projesini, kullandığınız IDE ile açınız. Folder structure olarak aşağıdaki gibi yapı karşınıza gelecektir. Şimdi adım adım ne işe yaradıklarına bir göz atalım.
Klasör Yapısı
src
- Oluşturduğumuz WebPart’lar bu klasör içerisinde saklanır
lib
- JavaScript dosyalarına derlenmiş (compile) tüm TypeScript dosyaları bu klasörde saklanır
- Paketlenip dağıtılabilen işlenmiş kodları içerir
dist
- Son dağıtılmış dosyaları içerir
- Aynı zamanda WebPart ların bundle edilmiş son halleri mevcuttur
node_modules
- Node.js tarafından indirilen modüllerini içerir (gulp, pnp, sharepoint framework [microsoft]…)
typings
- Çeşitli kütüphaneler için TypeScript definition dosyalarını içerir
- Typings ise JavaScript dosyalarının intellisense desteği sunmaktadır
SharePoint
- “gulp package solution” komutundan sonra oluşan “.spapp” paketini içerir
Proje İçerisindeki Önemli Dosyalar
config.json
Configuration dosyasıdır. Proje içerisindeki web part bilgileri,
harici referansları (jQuery vs.) ve localization için gerekli bilgilerde
dosyada saklanır.
deploy-azure-storage.json
Client-Side WebPart Azure CDN’ye dağıtırken kullanılır. Azure Storage hesabınıza ait bilgileri içerir.
package-solution.json
Bu dosya solution ait konfigürasyon bilgisini içermektedir.
gulpfile.js
Çalıştırılacak gulp task içermektedir.
package.json
Solution içerisinde yer alan library içermektedir.
tsconfig.json
TypeScript compile edilirken gerekli olan konfigürasyon bilgilerini içerir.
WebPart Class
“HelloWorldWebPart.ts” solution içerisinde yer alan “src/webparts/helloWorld” için entry point olarak belirtilen dosyadır. İlgili dosyayı açtığınızda “BaseClientSideWebPart” extend olduğunu göreceksiniz. Extend olmasından dolayı ilgili WebPart, base WebPart içerisinde yer alan property ve functionları tetiklemekte ve mirastan devrelan özellikleri kullanmamıza olanak sağlamaktadır.
BaseClientSideWebPart, web part oluşturmak için gereken en düşük functionality uygular. Bu sınıf ayrıca displayMode, web part property, web part context, web part instanceId, web part domElement ve daha fazlasını içeren read only properties validate etmekte ve erişmemize olanak sağlar.
Aşağıda yer alan “IHelloWorldWebPartProps” interface ‘in “BaseClientSideWebPart” içerisine tanımlanmaktadır.
WebPart class oluşturulmadan önce interface tanımlıyoruz, dolayısıyla web part içerisinde kullanacağımız property lerimizi önceden tanımlıyoruz.
(Extend ettiğimiz class içerisinde kullanacağımız property lerimizi belirtiyoruz.) Aynı zamanda bu kısımda belirtmiş olduğumuz property ler (“description” gibi) property pane üzerinden kullanılmaktadır.
export interface IHelloWorldWebPartProps {
description: string;
}
Web part render method
Base class içerisinde “protected abstract” olarak tanımlanmış olan “render()” methodu extend ettiğimiz web part içerisinde tetiklenmekte ve “ReactDom.render(element, this.domElement)” ile “components” içerisinde yer alan “HelloWorld.tsx” tetiklemektedir.
public render(): void {
const element: React.ReactElement<IHelloWorldProps > = React.createElement(
HelloWorld,
{
description: this.properties.description
}
);
ReactDom.render(element, this.domElement);
}
Web part property pane konfigürasyonu
Property pane alanı HelloWorldWebPart içerisine tanımlı olarak gelmekte ve “getPropertyPaneConfiguration()” ile web part ımızın alacağı parametrelerin tanımlandığı kısımdır. Burada tanımlamış olduğumuz property ise “components” içerisinde yer alan “HelloWorld.tsx” içerisinde “this.props.description” olarak kullanabilmekteyiz.
Biraz kurcalamaya başlayalım, Property pane içerisine: check box, drop-down list, ve toggle property ekleyelim.
HelloWorldWebPart.ts dosyasını açıp, en üst satırında yer alan “@microsoft/sp-webpart-base” alanını aşağıdaki kod bloğu ile güncelleyiniz.
import {
BaseClientSideWebPart,
IPropertyPaneConfiguration,
PropertyPaneTextField,
PropertyPaneCheckbox,
PropertyPaneDropdown,
PropertyPaneToggle
} from '@microsoft/sp-webpart-base';
Web part içerisine eşleme yapabilmemiz için “IHelloWorldWebPartProps” içerisine property tanımlayalım. (Aşağıdaki kod bloğu ile güncelleyiniz.)
export interface IHelloWorldWebPartProps {
description: string;
test: string;
test1: boolean;
test2: string;
test3: boolean;
}
Property pane alanında “IHelloWorldWebPartProps” içerisinde tanımladığımız property kullanabilmek için aşağıdaki gibi güncelleyiniz.
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
{
header: {
description: strings.PropertyPaneDescription
},
groups: [
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneTextField('description', {
label: 'Description'
}),
PropertyPaneTextField('test', {
label: 'Multi-line Text Field',
multiline: true
}),
PropertyPaneCheckbox('test1', {
text: 'Checkbox'
}),
PropertyPaneDropdown('test2', {
label: 'Dropdown',
options: [
{ key: '1', text: 'One' },
{ key: '2', text: 'Two' },
{ key: '3', text: 'Three' },
{ key: '4', text: 'Four' }
]
}),
PropertyPaneToggle('test3', {
label: 'Toggle',
onText: 'On',
offText: 'Off'
})
]
}
]
}
]
};
}
Gerekli işlemlerimizi yaptık ama “components” içerisinde kullanabilmek için react component içerisinde yer alan props ile eşleme yapmamız gerekmektedir. İlk olarak “components” içerisindeki “IHelloWorldProps.ts” dosyasını açınız ve aşağıdaki gibi güncelleyiniz.
export interface IHelloWorldProps {
description: string;
test: string;
test1: boolean;
test2: string;
test3: boolean;
}
Kaydettiğinizde build ederken hata alıyor olacaksınız. Bunun sebebi ise, “HelloWorldWebPart.ts” içerisinde yer alan render() methodu ile ReactDom render ettiğinden bahsetmiştik. Component içerisine tanımladığımız property nullable olmamasından dolayı ilgili property setlenmesini beklemektedir.
Aşağıdaki kod bloğu ile güncelleyiniz.
public render(): void {
const element: React.ReactElement<IHelloWorldProps> = React.createElement(
HelloWorld,
{
description: this.properties.description,
test: this.properties.test,
test1: this.properties.test1,
test2: this.properties.test2,
test3: this.properties.test3,
}
);
ReactDom.render(element, this.domElement);
}
İlgili dosyayı kaydettiğinizde build succeeded olacaktır.
Components içerisinde yer alan “HelloWorld.tsx” dosyasını açınız ve render kısmını aşağıdaki gibi güncelleyiniz.
<p className={ styles.description }>{escape(this.props.description)} {this.props.test}</p>
WebPart property default değer atamak isterseniz, “HelloWorldWebPart.manifest.json” dosyasını açınız ve aşağıdaki gibi güncellemeniz yeterli olacaktır. (terminal üzerinde web projesini durdurup, tekrardan “gulp serve” deyiniz.)
"properties": {
"description": "HelloWorld",
"test": "Multi-line text field",
"test1": true,
"test2": "2",
"test3": true
}
Web part manifest
“HelloWorldWebPart.manifest.json” dosyası, web part a ait meta data tutmaktadır (versiyon, id, display name, icon, description gibi) ve her web part içerisinde tanımlı olmalıdır.
Yaptığınız değişiklikleri tekrardan uygulamak ve doğruluğundan emin olmak için aşağıdaki komutu çalıştınız.
gulp serve
SharePoint içerisinde WebPart önizleme
SharePoint Workbench ile geliştiğimiz web part ımızı önizleyip, test edebildik fakat SharePoint içerisinden veri almamız gerektiğinde origin takılıyor olacağız ve gerçek datalar ile işlem yapamamaktayız. Microsoft bu kısım için çözüm sunmakta ve SharePoint ortamı ile web part larımızı entegre etmeyi sağlamaktadır. (SharePoint ortamında önizlemek ve test etmek için projenizi paketlemenize ve yüklemenize gerek olmamaktadır.)
Şimdi neler yapmamız gerekiyor, bir göz atalım.
Aşağıdaki url e kendi SharePoint ortamınızın adresi ile güncelleyerek tarayıcınız üzerinde açınız.
https://your-sharepoint-tenant.sharepoint.com/_layouts/workbench.aspx
SPFx developer certificate yüklü olmalıdır. Yüklü değilse durdurup “gulp trust-dev-cert” komutunu çalıştırınız. Sonrasında ise “gulp serve” ile yeniden ayağa kaldırınız.
Sonrasında Workbench ortmında yaptığımız gibi web partınızı ekleyiniz.
Fark ettiğiniz gibi yukarıdaki ekran görüntüsü ile workbench içerisindeki renkler farklıdır. Bunun nedeni ise, web part renklerini Office UI Fabric Core site üzerinde varsayılan olarak tanımlı olan site içerisinden almasından kaynaklıdır.