Tuesday, June 10, 2014

Elements.xml

Elements XML does not deploy my web parts, why.
sorry but maybe i'll translate another time. meanwhile use google translate or use this
<Module Name="WebParts" List="113" Url="_catalogs/wp"  Path="WebParts">
    <File Path="Sample.webpart" Url="Sample.webpart" />




כשאנו יוצרים ספריה, בד"כ MODULE שמה, תחתיה אנו מוסיפים פריט חדש שהוא עצמו נקרא MODULE, המיוחד לדבר זה שהוא בא עם קובץ חמוד בשם Elements.xml והוא יודע לפרוס דברים, בהנחה שחיברנו אותו לפיצר.

נתחיל מהקל אל הכבד, הקל ביותר זה STYLE LIBRARY.
אציין כי אין קשר לשם ספריית המודול לענין, כלומר יכולתי לקרא לזה רבי נחמן, מה שקובע זה הקובץ Elements.xml
בראש צריך להיות כך
<Module Name="this can be whatever name u want, its just a name" Path="this should be the name u've given to the module folder in VS " Url="this is where u want it in ur web" >
נגדים, נניח עשיתי מודול חדש וקראתי לו Na Nah Style
אני רוצה אותו בספריית סגנונות תחת RABI NACHMAN, ושמו יהיה בכלל המודול הכשר, מה שVS נותן לי זה ככה
<Module Name="Na Nah Style">
    <File Path="Na Nah Style\Sample.txt" Url="Na Nah Style/Sample.txt" />


אז אשנה את כל מה שאני רוצה וזו תהיה התוצאה
  <Module Name="the kosher module"  >
    <File Path="Na Nah Style\smily.png " Url="Style Library/Rabi Nachman/smily.png" />


עכשיו אני לא רוצה להתאמץ לרשום הכל מחדש לכל קובץ וקובץ אז אני יכול לשים תחיליות במודול עצמו וזו תהיה התוצאה
  <Module Name="the kosher module"  Path="Na Nah Style" Url="Style Library/Rabi Nachman">
    <File Path="smily.png" Url="smily.png" />
    <File Path="happyFace.png" Url="happyFace.png" />

עד כאן ספריית סגנונות.

לספריית WEBPARTS יש עוד כמה טוויקים.
ראשית המודול חייב לקבל את 2 הערכים הבאים: List="113" Url="_catalogs/wp", כלומר המינימום צריך להראות כך
  <Module Name="WebParts" List="113" Url="_catalogs/wp" >
ואז מתחילים.
אם אתם מוסיפים ישר VISUAL WEB PART  אז תתיוצר לכם ספריה קטנה עם כל מיני דברים שכוללת בין היתר Elements.xml משלו ודי סיימתם בשלב הזה. אבל לא כולם אוהבים את זה. ב2010 זה בד"כ מסיבות של "למען הסדר הטוב" (לי זה היה מצויין ד"א) וב2013 פשוט הם עשו שהASCX הוא בפועל מתרנדר בצד שרת ואז א"א לעשות copy to SP root  אלא חייבים ריבילד עם ריסייקל וזה איחסה אז חוזרים לשיטה הישנה והמקורית.

אז האפשרות הOOTB היא להוסיף רק WEBPART, ואני לא זוכר מה 2010 נותן אבל 2013 נותן שוב ספריה קטנה עם קובץ WEBPART  שיורש מCS שנמצא לידו והוא יורש כמובן מWEBPART, ושוב ולספריה הקטנה הזו יש Elements.xml משלה והכל טוב. ואכן יש לנו כמה פרוייקטים שהתנהלנו ככה והיה סבבה. אלא שזה קצת מטומטם וריבוי קבצים אם אין לנו שם על הדרך את הASCX שלנו.

ואז חוזרים לבית אבא, מוסיפים קובץ טקסט וקוראים לו myWP.webpart. ע"מ שיהיה לו ASCX הוא צריך לרשת ממשהו שמממש WEBPART ויוצר לו קונרול בפנים, נראה משהו כזה
public class SmartPart : Microsoft.SharePoint.WebPartPages.WebPart
    {
        [WebBrowsable(false)]
        [Personalizable(PersonalizationScope.Shared)]
        [WebPartStorage(Storage.Shared)]
        public string ControlPath { get; set; }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            if (string.IsNullOrEmpty(this.ControlPath) == false)
            {
                Control userControl = this.Page.LoadControl(this.ControlPath);
                this.Controls.Add(userControl);
            }
        }

        protected override void RenderWebPart(HtmlTextWriter output)
        {
            this.RenderContents(output);
 }

כמובן שאנו מנצלים את ההזדמנות ומסדרים כל מיני דברים כמו ולידטורים וזה וכ"א יקח מפרוייקט קיים אבל זה הבסיס, ואז הקובץ WEBPART נראה  ככה
<?xml version="1.0" encoding="utf-8"?>
<webParts>
  <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
    <metaData>
      <type name="eWave.Sharepoint.BLL.SmartPart, eWave.Sharepoint.BLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=202fba70c233e0c3" />
      <importErrorMessage>$Resources:Iec,WebPart_ImportErrorMessage_Title;</importErrorMessage>
    </metaData>
    <data>
      <properties>
        <property name="Title" type="string">your title</property>
        <property name="Description" type="string"> your desc</property>
        <property name="ControlPath" type="string">~/_controltemplates/15/yourUC.ascx</property>
        <property name="ChromeType" type="chrometype">None</property>
      </properties>
    </data>
  </webPart>
</webParts>

שימו לב שהדגשתי את ה"15" בנתיב, זה בשביל משתמשי 2013, אם אתה ב2010 תשמיט את זה ואם אתה ב2013 אתה צריך את זה, ולשאלה למה אנא פנה לאדמו"ר התורן

כל זה בשביל לחזור ל Elements.xmlשלנו, שאנו מוסיפים לו קצבצי טקסט ונותנים להם סיומת .webpart
אבל בנתיים זה נראה ככה

<Module Name="WebParts">
    <File Path="WebParts\Sample.webpart" Url="WebParts/Sample.webpart" />
אז אנחנו צריכים לשנות לדבר הבא
  <Module Name="WebParts" List="113" Url="_catalogs/wp">
    <File Path="WebParts\Sample.webpart" Url="Sample.webpart" />
ובפועל אנחנו נקל על עצמנו וזו התוצאה הסופית הרצויה
  <Module Name="WebParts" List="113" Url="_catalogs/wp"  Path="WebParts">
    <File Path="Sample.webpart" Url="Sample.webpart" />

יש עוד 2 בחבורה (בנתיים) והם הDISPLAY TEMPLATES של החיפוש ושל התוכן, ולהם צריך טריק קטן, נתחיל עם המודול ושימו לב שאני תמיד מכניס אותם במצס DRAFT, וזכרו שחלק הURL במודול צריך להיות בדיוק כמו כאן, וגם שימו לב לפרופטרי של הפיצר שרציך אותו כך

להלן הגרסא הסופית של חיפוש

  <Module Name="Search Results Display Templates" Path="Search Results Display Templates" Url="_catalogs/masterpage/Display Templates/Search" RootWebOnly="TRUE">
    <!--Control Templates-->
    <File Url="My Blank Control.html" Type="GhostableInLibrary" Level="Draft" ReplaceContent="TRUE">
      <Property Name="FeatureId" Value="$SharePoint.Feature.Id$" Type="string"/>
    </File>
    <!--Control Templates-->

    <!--Item Templates-->
    <File Url="My Item Template.html" Type="GhostableInLibrary" Level="Draft" ReplaceContent="TRUE">
      <Property Name="FeatureId" Value="$SharePoint.Feature.Id$" Type="string"/>
    </File>
    <!--Item Templates-->
  </Module>
של התוכן

<Module Name="Content Web Parts Display Templates" Path="Content Web Parts Display Templates" Url="_catalogs/masterpage/Display Templates/Content Web Parts" RootWebOnly="TRUE">
  <!--Control Templates-->
  <File Url="My List Control.html" Type="GhostableInLibrary" Level="Draft" ReplaceContent="TRUE">
    <Property Name="FeatureId" Value="$SharePoint.Feature.Id$" Type="string"/>
  </File>
  <!--Control Templates-->
  <!--Item Templates-->
  <File Url="My Item Template.html" Type="GhostableInLibrary" Level="Draft" ReplaceContent="TRUE">
    <Property Name="FeatureId" Value="$SharePoint.Feature.Id$" Type="string"/>
  </File>
  <!--Item Templates-->
</Module>

הסיפור של החברים הללו הוא שאם נפרוס אותם רגיל הם יהיו לעולם במצב לא מפורסם ולא יתדעכנו ולמי שמעונין לדעת למה יחפש את זה בגוגל או באיזה מייל ישן שכתבתי על כך אבל הטריק הוא לפרסם אותם דרפט ולפרסם אותם עם פיצר
            SPFileCollection files = folder.Files;
            var drafts = from SPFile f in files
                         where String.Equals(f.Properties["FeatureId"] as string, featureId, StringComparison.InvariantCultureIgnoreCase) &&
                         f.Level == SPFileLevel.Draft
                         select f;

            foreach (SPFile f in drafts)
            {
                f.Publish("");
                f.Update();
            }

גיבור מי שקרא הכל, שמור בצד ליום שתיצור פרוייקט SP ולא תבין למה לא נפרסים לך הWPים.

בברכה
אריאל