Displaying User Profile photos in other places (with a little help)

Today I ran into a problem I didn't imagine still existed (in DNN v.7.2). I was using Ventrian Property Agent and I needed to display the profile photo of the user who made the submission inside the module's View Item template. I was surprised that neither Property Agent supported that, nor was there another way to get the user's profile image at a decent size inside the module's templates.


I'm sure that even if you aren't using this specific module, you've also ran into this issue one way or another. There is no decent built-in way to display a user's profile image outside of the user profile page itself.


In my case, there is a token Ventrian Property Agent users named [USERID] that provides the id of the user who has created the current entry. With only this in hand, I had to find a way to use it to get a decent profile picture.


First option would be to use the standard DNN /profilepic.ashx image handler, but this one returns distorted, grainy images of max 64x64 pixels. Using it like this: <img src="/profilepic.ashx?userid=[USERID]"> would give me a crappy image, but at least an image.


Two minutes before I was ready to give up, I ran into this gem: http://bbimagehandler.codeplex.com/ - this is a generic image handler that does a lot of things - resizing, watermarks, etc. but one interesting feature is that it can render DNN user profile images - in any dimension given, and with awesome quality compared to DNN's own profilepic.ashx.


Give it a try if you're facing the same problem. Have in mind that in order for DNN Profile Pictures to work, you'll HAVE to specify the "db" parameter as mentioned in the documentation. By specifying this parameter, it is implied that you have already updated your web.config file with this key:


<add key ="BBDatabase" value="Connectionstring=SiteSqlServer;table=MyImages;ImageField=ImageData;idField=ImageID" />


The trick is that you only need the first part if you only need BBImageHandler to handle profile images, since it already knows what tables and fields to use. So you can use this version:


<add key ="BBDatabase" value ="Connectionstring=SiteSqlServer;" />


Where "SiteSqlServer" is your connection string's name (in case you have renamed it from the default name DNN gives it).


This way, it is only enough to know the user id whose profile image you need to show - In my case, as I said above, I had the [USERID] token, so my code was as follows:


<img src="/bbimagehandler.ashx?db=BBDatabase&userid=[USERID]&portalid=0&width=300">


And voila! A profile image with a 300px width inside a Property Agent Template! (I'm thinking of even using it inside the user profile page itself).


Until next time!



Customizing DNN 7 Search and Search Results

DNN 7 has introduced a new, Lucene-powered indexing and search results retrieval mechanism. This means that all techniques you knew are not in effect any more. No more SQL queries and/or tables, data get returned in JSON format and rendered via Javascript. For more details, please read this post on DNNSofware.com


This adds a whole lot of new functionality but also a lot of limitations in the way Search Results are presented. Actually, there never was a straightforward way to customize Search Results, but until now you could just edit SearchResults.ascx and its corresponding code-behind file and have your desired result.


Things are still ugly regarding customization. The default Search Results layout includes a link guiding you to advanced search concepts, an "Advanced" form that asks you to provide various information such as where you want to search (categorized by module type) and so forth.


This doesn't always make sense to end users, and some elements have to be removed in specific scenarios. Users don't always want advanced search options, nor do they need to know what type of modules your site contains. In some cases they don't give a damn about the author, or the last modified date too. But there's no immediate way to configure what will be displayed and what will be not.


Moreover, until now you could face the problem of default module titles (which users usually leave as is because they are using containers that didn't include the module title) by tweaking the way module titles were inserted in the SearchItem table (see this older post for more). Since no SQL tables are used any more, you're left with ugly "Text/HTML" and other default titles in Search Results. The JSON returned for each search result item just contains a title that is often made of a concatenation of the tab's name and the module's title (or, in the case of grouped results, just the module's title).


Moreover, having a module with a BLANK title is no longer an option since modules with blank titles are not indexed(!). For more info, see my question here: http://www.dnnsoftware.com/answers/cid/420779


So le't see how we can address all of the above with some modifications on specific files. Be warned that what I'm saying here applies to version 7.1 and may or may not be in effect for future DNN versions, as well as that those changes are not upgrade-proof, meaning that if you upgrade your site to a higher DNN version you may lose them. But, it's better than nothing. :)


Be sure to get a backup of all the files you are going to modify in case something goes wrong!


Let's start.


Hiding the "advanced" link

File: dnn.SearchResult.js

Location: DesktopModules\Admin\SearchResults


Go to line 343, you will see a call to the DnnSearchBox like the following

      dnn.searchResult.searchInput = $('#dnnSearchResult_dnnSearchBox').dnnSearchBox({
           id: 'dnnSearchResult_dnnSearchBox',
           filterText: dnn.searchResult.defaultSettings.advancedText,
           showAdvanced: true,
           advancedId: 'dnnSearchResultAdvancedForm',



Locate this line:

showAdvanced: true,


And change it to

showAdvanced: false,


This is an option that you can't access via the module settings and it hides the "advanced" link. Unfortunately, the form that would pop up will still be visible at the bottom of the page so you have to take an extra step:


File: SearchResults.ascx

Location: DesktopModules\Admin\SearchResults


Go to around line 55 and you'll see a DIV element surrounding the elements of the Advanced form, like the following:

<div id="dnnSearchResultAdvancedForm" class="dnnForm">
    <div class="dnnFormItem">
        <dnn:Label ID="lblAdvancedTags" runat="server" ResourceKey="lblAdvancedTags" />
        <input type="text" id="advancedTagsCtrl" />
    <div class="dnnFormItem">


Add a style="display:none;" attribute to the outer div to hide the whole form.


If you need the advanced form but do not need to show specific controls, you can just skip the steps above, go at this point and just add a style="display:none;" attribute to any of the DIVs nested inside to hide the specific control you don't need (e.g. Scope)


Hide Advanced Tips link


File: dnn.SearchResult.js

Location: DesktopModules\Admin\SearchResults


Go to line 359 (it's empty), just above this piece of code:

$('a.dnnSearchResultAdvancedTip').on('click', function () {
            return false;

And insert the following line:



Alternatively, you can achieve the same result by adding a style="display:none;" attribute at the A tag in SearchResults.ascx, line 6:

<a href="javascript:void(0)" class="dnnSearchResultAdvancedTip"><%= LinkAdvancedTipText %></a>


Hide Results by Page / Sort section


File: SearchResults.ascx

Location: DesktopModules\Admin\SearchResults


Go to line 13 and add a style="display:none;" attribute to the outer DIV element there (first element in code snippet below):

<div class="dnnSearchResultPanel">
    <div class="dnnRight">
        <ul class="dnnSearchResultSortOptions">
            <li class="active"><a href="#byRelevance"><%= RelevanceText %></a></li>
            <li><a href="#byDate"><%= DateText %></a></li>...


If you hide this section but you need to specify a different sort order and/or results per page setting, you can alter the Javascript call at the same file, line 116 onwards, by altering the sortOption and pageSize initial values:

$(function () {
        if(typeof dnn != 'undefined' && dnn.searchResult){
            dnn.searchResult.moduleId = <%= ModuleId %>;
            dnn.searchResult.queryOptions = {
                searchTerm: '<%= SearchTerm %>',
                sortOption: 0,
                pageIndex: 1,
                pageSize: 15

sortOption can be 0 for date, 1 for relevance.

pageSize can be anything you need.


Hide various elements on Search Results


Well, some people don't like the "last updated" information. Others don't like the "author" info. So let's see how we get rid of anything we don't need:


File: dnn.SearchResult.js

Location: DesktopModules\Admin\SearchResults


Start from about line 112,where you'll see code like this:

markup += '<div class="dnnSearchResultItem-Others">';
        markup += '<span>' + dnn.searchResult.defaultSettings.lastModifiedText + ' </span>';
        markup += data.DisplayModifiedTime;
        markup += '</div>';

        markup += '<div class="dnnSearchResultItem-Others">';
        markup += '<span>' + dnn.searchResult.defaultSettings.sourceText + ' </span>';

Comment lines 112 to 115 to get rid of the "last updated" text

Comment lines 117 to 119 to get rid of the "source" text and link

Comment lines 121 to 123 to get rid of author info

Comment lines 126 to 135 to get rid of 'tags" info


Hide default HTML module titles (if any)


As mentioned earlier, you may not want module titles to appear in search results, but they do, even if your container doesn't display the module's title. The most common is "Text/HTML" and we'll see how to get rid of it in Search Results.


File: dnn.SearchResult.js

Location: DesktopModules\Admin\SearchResults


Scroll down to the bottom of the file and append this function at the end:

function fixTitle (s) {
    if (s=='Text/HTML') {
        return ('...');
    var s1;
    var s2;
    s2=s.substring(s.indexOf('>')+2, s.length);
    if (s2=='Text/HTML' || s2==s1) {
        return (s1);
        return (s);

This function accepts a search result item title and first checks if the title is "Text/HTML". If so, it returns three dots ("...") instead. You will find this in grouped results, where the module title is displayed on its own.


If the title does not belong to a group subset, it'll be in the format "xxx > yyy" where xxx is the page's name and yyy is the module's title. The code breaks the string in its two parts and checks if the second part is equal to "Text/HTML". If so, it returns only the first part (the page's name). Also, if both parts are the same it once more returns the first part. Useful when a module has the same title as the page and you don't want to see this in search results.


This is not the best possible solution, but it's a decent workaround, provided that you don't have the character ">" anywhere in your module titles or page names. I know it can get better, but this is only to demonstrate how you can do it.


In order to put our function into effect, we have to go to line 107:

markup += '<a href="' + data.DocumentUrl + '"' + dnn.searchResult.defaultSettings.linkTarget + '>' + data.Title + '</a></div>';

and replace data.Title with fixTitle(data.Title):

markup += '<a href="' + data.DocumentUrl + '"' + dnn.searchResult.defaultSettings.linkTarget + '>' + fixTitle(data.Title) + '</a></div>';

Hide subsets (grouped results)

If, for some reason, you don't want to have any grouped results then you can comment out the code that is generating them. Be adviced that the result that was supposed to be grouped won't display a description underneath, just the title and link.


File: dnn.SearchResult.js

Location: DesktopModules\Admin\SearchResults


Go to line 159 and comment the code there until line 161:

// render subsets
                   for (var j = 0; j < result.Results.length; j++) {
                       markup += '<div class="dnnSearchResultItem-Subset">' + dnn.searchResult.renderResult(result.Results[j]) + '</div>';


Finally, if you tamper with the way search results are rendered, you may not want to have auto-search (search-as-you-type) get in your way by rendering everything in a different way (e.g. using default text/html module titles). There is no option for disabling it, but we can always hack the code a little more:


File: SearchSkinObjectPreview.js

Location: Resources\search


Go to line 137 and comment out this piece of code (until line 155):

throttle = setTimeout(function() {
                         var service = $.dnnSF ? $.dnnSF(-1) : null;
                         var url = makeUrl(val, service);
                         if (url) {
                                 url: url,
                                 beforeSend: service ? service.setModuleHeaders : null,
                                 success: function(result) {
                                     if (result)
                                 error: function() {
                                 type: 'GET',
                                 dataType: 'json',
                                 contentType: "application/json"
                     }, self.settings.delayTriggerAutoSearch);

This will prevent the Search skin object from auto-searching.


Well, that's all! Even if line numbers change with an upgrade, you have a reference point on what to seek in code. I know this is not the prettiest or the most accurate and bullet-proof solution in the world, but until DNN Corp. decides to add more configuration settings to its Search subsystem, it will have to do. In the meantime, you can vote for my relevant suggestion in Community Voice here:



Oh, and please feel free to suggest any other improvements / hacks to Search and Search Results! I know I didn't cover the whole range of possible modifications, but these are, IMHO, the most common ones.


Until next time!

Related Posts with Thumbnails

Recent Comments

Free DotNetNuke Stuff

Free DotNet Videos

  © Blogger template The Professional Template by Ourblogtemplates.com 2008

Back to TOP