Custom Content Query WebPart
Introduction:-
When we create portal very often we use Content Query Web Part (CQWP) to display contents. If you are not using then start using it. Trust me its very nice.
As per me; There are 2 bad points in CQWP:-
1. We end up to modify existing style library xslt for adding xslt template. If we do so Microsoft will not support if require. Also if anything happens then entire site will crash.
2. Whatever field we wish to display; we need to add view fields detail in CQWP. For this we need to export, add fields in xml and again import webpart.
Therefore I have created a generic webpart which provide functionality to take custom xslt path and provide functionality to take viewfields. You can extend this webpart by providing other feature like query, paging etc..
Detail:-
1st we will setup site and then later we will discuss about implementation of CQWP.
Setup:-
1. Go to “Style Library”.
2. Create a new folder. In my example its “Cportal XSL Style Sheets”.
3. Copy all xslt from “XSL Style Sheets” to our new folder “Cportal XSL Style Sheets”.
That means we use these xslt in new custom folder; By this Custom CQWP will give OOB behavior.
Implementation:–
Now we will extent existing CQWP feature by inheriting ContentByQueryWebPart class.
There would be 2 classes.
1. CustomContentQueryWebPart: – It extent existing CQWP feature by inheriting ContentByQueryWebPart class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | using System; using System.Collections.Generic; using System.Web; using System.ComponentModel; using System.Web.UI.WebControls.WebParts; using Microsoft.SharePoint; using Microsoft.SharePoint.Publishing.WebControls; using Microsoft.SharePoint.WebPartPages; namespace Avinash { ///<summary> /// Extent existing CQWP feature by inheriting ContentByQueryWebPart class /// </summary> public class CustomPortalContentQuery : ContentByQueryWebPart { [WebBrowsable(true)] [Category("Staging Customization")] [DefaultValue("")] [Personalizable(PersonalizationScope.Shared)] [WebDisplayName("List Web Relative Url")] [WebDescription("The url of the List or Document Library")] public string ListUrl { get; set; } public override ToolPart[] GetToolParts() { List toolPart = new List(base.GetToolParts()); toolPart.Insert(0, new CustomToolPart()); return toolPart.ToArray(); } ///<summary> /// Initialize custom xslt path and set the Changed boolean to false /// Note: XSLT initialization can not be dont in CreateChildControls. /// It has to be done in OnInit /// </summary> protected override void OnInit(EventArgs e) { this.ItemXslLink = this.ServerRelativeItemXslLink; this.MainXslLink = this.ServerRelativeMainXslLink; // Workaround to get webpart title url in ContentQueryMail.xsl if (!String.IsNullOrEmpty(this.TitleUrl)) this.FeedDescription = this.TitleUrl; base.OnInit(e); } } } |
2. CustomToolPart: – It Create tool part for Custom content query webpart. This will display same webpart properties like CQWP.
However it will have extra pane named as “CPortal Settings” Where we will have option set xslt file and view fields..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | using System.Web.UI; using System.Web.UI.WebControls; namespace Avinash { /// <summary> /// Create tool part for Custom content query webpart /// This will display same webpart properties like CQWP. /// However it will have extra pane named as "CPortal Settings" /// Where we will have option set xslt file and view fields. /// </summary> public class CustomToolPart : Microsoft.SharePoint.WebPartPages.ToolPart { CustomPortalContentQuery webpart; TextBox commonViewFields; TextBox itemXslLink; TextBox conentQueryMainXslLink; Panel toolPanel; Table toolPanelTable; public CustomToolPart() { this.Title = "CPortal Settings"; } protected override void CreateChildControls() { webpart = this.WebPartToEdit as CustomPortalContentQuery; toolPanel = new Panel(); toolPanel.CssClass = "ms-ToolPartSpacing"; toolPanel.Controls.Add(GetToolPanel()); this.Controls.Add(toolPanel); base.CreateChildControls(); } public override void ApplyChanges() { try { // set xsl path webpart.ItemXslLink = itemXslLink.Text; webpart.MainXslLink = conentQueryMainXslLink.Text; webpart.CommonViewFields = commonViewFields.Text; } catch { } base.ApplyChanges(); } private Control GetToolPanel() { toolPanelTable = new Table(); toolPanelTable.CellPadding = 0; toolPanelTable.CellSpacing = 0; toolPanelTable.Style["border-collapse"] = "collapse"; toolPanelTable.Attributes.Add("width", "100%"); toolPanelTable.Rows.Add(GetItemXslLinkRow()); toolPanelTable.Rows.Add(GetSeperatorRow()); toolPanelTable.Rows.Add(GetCommonViewFieldsRow()); toolPanelTable.Rows.Add(GetSeperatorRow()); toolPanelTable.Rows.Add(GetContentQueryMainLinkRow()); return toolPanelTable; } /// <summary> /// Create row for Item XSL /// </summary> /// <returns>row for item xsl</returns> private TableRow GetItemXslLinkRow() { TableRow row = new TableRow(); TableCell cell = new TableCell(); cell.Controls.Add(new LiteralControl ("<div class="UserSectionHead"><b>Item XSL Link:</b></div>")); cell.Controls.Add(new LiteralControl ("<div class="UserSectionBody"><div class="UserControlGroup"><nobr>")); itemXslLink = new TextBox(); // set xsl path if (string.IsNullOrEmpty(webpart.ItemXslLink)) { itemXslLink.Text = this.webpart.ServerRelativeItemXslLink; } else itemXslLink.Text = this.webpart.ItemXslLink; cell.Controls.Add(itemXslLink); cell.Controls.Add(new LiteralControl("</nobr></div></div>")); row.Cells.Add(cell); return row; } /// <summary> /// Create row for Common view fields /// </summary> /// <returns>row for Common view fields</returns> private TableRow GetCommonViewFieldsRow() { TableRow row = new TableRow(); TableCell cell = new TableCell(); cell.Controls.Add(new LiteralControl ("<div class="UserSectionHead"><b>Common View Fields:</b></div>")); cell.Controls.Add(new LiteralControl ("<div class="UserSectionBody"><div class="UserControlGroup"><nobr>")); commonViewFields = new TextBox(); commonViewFields.Text = this.webpart.CommonViewFields; cell.Controls.Add(commonViewFields); cell.Controls.Add(new LiteralControl("</nobr></div></div>")); row.Cells.Add(cell); return row; } /// <summary> /// Create row for Content Query Main XSL /// </summary> /// <returns>row for Content Query Main xsl</returns> private TableRow GetContentQueryMainLinkRow() { TableRow row = new TableRow(); TableCell cell = new TableCell(); cell.Controls.Add(new LiteralControl ("<div class="UserSectionHead"><b>ContentQueryMain XSL Link:</b></div>")); cell.Controls.Add(new LiteralControl ("<div class="UserSectionBody"><div class="UserControlGroup"><nobr>")); conentQueryMainXslLink = new TextBox(); // set xsl path if (string.IsNullOrEmpty(webpart.ItemXslLink)) { conentQueryMainXslLink.Text = this.webpart.ServerRelativeMainXslLink; } else conentQueryMainXslLink.Text = this.webpart.MainXslLink; cell.Controls.Add(conentQueryMainXslLink); cell.Controls.Add(new LiteralControl("</nobr></div></div>")); row.Cells.Add(cell); return row; } /// <summary> /// Create a dotted seperator row /// </summary> /// <returns>row for dotted seperator</returns> private TableRow GetSeperatorRow() { TableRow row = new TableRow(); TableCell cell = new TableCell(); cell.Controls.Add(new LiteralControl ("<div style='width:100%' class='UserDottedLine'></div>")); row.Cells.Add(cell); return row; } } } |
Once you deploy this web part it will display webpart property like below image:-
You can see that now we have custom pane property as “CPortal Settings” where we can set xsl path and view fields. In my case the path will be like below image:-
Here viewfields you can add as per your requirement.
Hope it helps!
Thanks!
Avinash
March 14, 2012
·
Infoyen ·
10 Comments
Tags: About SharePoint Content Query Web Part, CQWP, Custom Content Query Web Part, Customizing Content Query Web Parts, Customizing the Content Query Web Part and Custom Item Styles, Extending the Content Query web part, How to: Customize the SharePoint Content By Query Web Part, How to: Display Custom Fields in a SharePoint Content By Query Web Part, MOSS, SharePoint, SharePoint: Displaying Custom Fields in Content Query Web Parts · Posted in: CQWP, MOSS, SharePoint
10 Responses
Thank, very helpful.
Thanks, very helpful.
This is interesting. Have you tried overriding the Query property and making it personalizable. I want my users to have their own query filters whilst editing and view a page in personalization mode. Do you think this possible
Hi,
You may try to use ProcessDataDelegate. See below example:-
Hi Infoyen
I can see what you are trying to do – ” Sort” could be a personalisable property. Unfortunately, my users want to set their own unique query ( involving CTs and site cols). I would therefore need to replicate the ToolPart query functionality with my own personalisable properties.
Previously, I had tried ovrriding the QueryOverride property but all this does is disable the query part of the tool part settings… I understand a few people have complained to Microsoft about this.
Hello,
I never did this part. But i think Microsoft expose 1 property called “QueryOverride”.
So get value of “QueryOverride” from web part tool pane property and set into your personalisable property.
To modify this you need to generate caml query and assign it back into “QueryOverride” property.
Please check these url:-
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.publishing.webcontrols.contentbyquerywebpart.queryoverride.aspx
Customize the Content Query Web Part by using Custom Properties
These might help you.
I got the error, Using the generic type ‘System.Collections.Generic.List’ requires 1 type arguments
Please provide more detail.
Hi, As i used your code for customizing content query webpart. In properties toolpane Properties category name is showing but controls(ItemxslLink:, common view fields:, content query main xsl Link:) are not visible..
Normally it works for me and for my other blog users…
Seems you are doing small mistake which you are not able to catch.
Review your code and check simple things. may be like-
1. Did you use => this.Controls.Add(toolPanel);
2. Did you use =>
public override ToolPart[] GetToolParts()
{
List toolPart = new List(base.GetToolParts());
toolPart.Insert(0, new CustomToolPart());
return toolPart.ToArray();
}
Rest i may not be able to guide until unless i don’t see your full code.
Let me know if you have found the solution..
Leave a Reply