DotNetNuke How to Add alt Text to an Image

Alt text can be added to a DotNetNuke image either at the time of adding the image to the text content, or subsequently if required.

DotNetNuke manages uploaded images and documents through the File Manager.

I prefer to use the file manager to upload and manage my images and documents separately from when inserting content to the page.

With the background work done, images and documents uploaded, I can compose my content for the page, without the disruption involved in uploading an image.

While composing the page content I can click on the image icon within the editor to popup the Image Manager dialogue to make my selection.

DotNetNuke adding image alt text add media

Using the popup Image Manager navigate to and select the image which you wish to insert into your text.

DotNetNuke Adding Image Alt Text

Add further details regards the image, for example the size of the image, width or height, and the element which we are interested in the alt text.

Later on, if you decide to change the text right click on the image to select the properties option, this will open the Properties dialogue.

DotNetNuke adding image alt text image properties

Why add ALT Text to an Image? Well adding alt text to an image is good for SEO, lets visitors understand the context in which you are using the image and for those who are using a screen reader to view your website the text will be spoken.

Increase the DotNetNuke Maximum File Upload Size

I find the default limit on file upload size in DotNetNuke can be too restrictive.

The default DNN upload file size is 8Mb.

The setting is within the web.config file in the root of the DNN website file installation.

Look for the section <system.web>.

    <!-- allow large file uploads -->
    <httpRuntime useFullyQualifiedRedirectUrl="true" maxRequestLength="8192" requestLengthDiskThreshold="8192" />

Increase the value of the maxRequestLength parameter to clear the file size which is an issue. Doubling to 16M may be sufficient.

    <!-- allow large file uploads -->
    <httpRuntime shutdownTimeout="120" executionTimeout="900" useFullyQualifiedRedirectUrl="true" maxRequestLength="12288" requestLengthDiskThreshold="12288" requestValidationMode="2.0" requestPathInvalidCharacters="&lt;,&gt;,*,%,:,\,?" fcnMode="Single" />
    <httpCookies httpOnlyCookies="true" requireSSL="false" domain="" />

To edit the file download a copy from the server via FTP using Filezilla. The file can then be edited with a text editor such as notepad.

For simplicity of editing with colour discrimination of tags and parameters you may find one of the HTML editors useful. Must admit if it’s a one off then whatever editor is to hand is the best option.

At the time you are downloading this one configuration file why not take a backup of the whole website?

With an increased file size capability it will take longer to upload the files to your website. You may also wish to increase this time out.

If you are experiencing file upload restrictions on images then maybe you should reconsider the size or quality of the image which you are uploading. Larger, slow to load images, can have a detrimental effect on your website, visitors maybe become impatient leaving slow to load pages and it is considered a black mark on your SEO score.

References

http://www.dnnsoftware.com/wiki/working-with-large-files

DNN FAQ Unknown Server Tag dnn:DnnListBox

Catching up with DotNetNuke site updates I observed an error on a page with the FAQ module installed.

The website had been updated to DNN 8.0.4.

Bellow is the DNN FAQ module error

DotNetNuke.Services.Exceptions.ModuleLoadException: Unknown server tag 'dnn:DnnListBox'. ---> System.Web.HttpParseException: Unknown server tag 'dnn:DnnListBox'. ---> System.Web.HttpParseException: Unknown server tag 'dnn:DnnListBox'. ---> System.Web.HttpException: Unknown server tag 'dnn:DnnListBox'. at System.Web.UI.TagPrefixTagNameToTypeMapper.System.Web.UI.ITagNameToTypeMapper.GetControlType(String tagName, IDictionary attribs) at System.Web.UI.MainTagNameToTypeMapper.GetControlType(String tagName, IDictionary attribs, Boolean fAllowHtmlTags) at System.Web.UI.ControlBuilder.CreateChildBuilder(String filter, String tagName, IDictionary attribs, TemplateParser parser, ControlBuilder parentBuilder, String id, Int32 line, VirtualPath virtualPath, Type& childType, Boolean defaultProperty) at System.Web.UI.TemplateParser.ProcessBeginTag(Match match, String inputText) at System.Web.UI.TemplateParser.ParseStringInternal(String text, Encoding fileEncoding) --- End of inner exception stack trace --- at System.Web.UI.TemplateParser.ProcessException(Exception ex) at System.Web.UI.TemplateParser.ParseStringInternal(String text, Encoding fileEncoding) at System.Web.UI.TemplateParser.ParseString(String text, VirtualPath virtualPath, Encoding fileEncoding) --- End of inner exception stack trace --- at System.Web.UI.TemplateParser.ParseString(String text, VirtualPath virtualPath, Encoding fileEncoding) at System.Web.UI.TemplateParser.ParseFile(String physicalPath, VirtualPath virtualPath) at System.Web.UI.TemplateParser.ParseInternal() at System.Web.UI.TemplateParser.Parse() at System.Web.Compilation.BaseTemplateBuildProvider.get_CodeCompilerType() at System.Web.Compilation.BuildProvider.GetCompilerTypeFromBuildProvider(BuildProvider buildProvider) at System.Web.Compilation.BuildProvidersCompiler.ProcessBuildProviders() at System.Web.Compilation.BuildProvidersCompiler.PerformBuild() at System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath) at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate) at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate) at System.Web.UI.TemplateControl.LoadControl(VirtualPath virtualPath) at DotNetNuke.UI.ControlUtilities.LoadControl[T](TemplateControl containerControl, String ControlSrc) at DotNetNuke.UI.Modules.WebFormsModuleControlFactory.CreateModuleControl(TemplateControl containerControl, ModuleInfo moduleConfiguration) at DotNetNuke.UI.Modules.ModuleControlFactory.LoadModuleControl(TemplateControl containerControl, ModuleInfo moduleConfiguration) at DotNetNuke.UI.Modules.ModuleHost.LoadModuleControl() --- End of inner exception stack trace ---

I visited the DNN FAQ module on github, downloaded and installed the more recent updated version 08.04.00.

The error was gone!

 

 

Catalook Store Module Guest User Checkout

The DotNetNuke Catalook store module offers the option to complete the purchase with a guest account.

If you are running an online shop you may prefer to allow transactions to be completed without the visitor creating an account.

Forcing the website visitor to create an account as a part of an online shop payment process may lose a few potential customers. Creating an account may be one hurdle too many.

For a DNN website running the Catalook shop module the option to run using guest accounts isn’t configured within the Catalook settings.

To allow guest user check out the Catalook store on DNN requires that site settings User Account options is set to allow public user registrations.

Catalook Guest User Checkout User Account Settings

To enable public registration open the admin Site Settings page.

On this page select the User Accounts tab.

As shown in the image above from the Registration Settings section, from the user registration options select public.

With the public option selected when a visitor completes the purchase transaction on your Catalook shop module no user account registration is required.

DNN Login Link not Showing

Configuring a DNN website to show a login link. A small change to implement but where is the relevant checkbox?

Reconfiguring a DNN website to show the login link I was looking to reintroduce the login link.

The code for the skin included the references for the login/logout and user profile/register references.

Open the admin site settings page.

Whilst it may be tempting to look at the User Options the display of the login link is considered to be a security aspect.

On the admin Site Settings page open the advanced settings tab and look in the security settings section.

DNN login link not showing

Looking at this section the Hide Login Control checkbox is un ticked if the login link is to be shown.

Click on update at the bottom of the page to save changes made.

To check whether the login link was showing I viewed the website in another browser on which I hadn’t logged in.

ICSharpCode.SharpZipLib.ZipException Exists in Both

After updating a DNN website to it’s latest version I like to check the extensions page for any required updates too. Having logged into the website its an easy pass through the extensions page as a check for notified updates.

Following the update of one DNN installation, the extensions page was showing the error:

Error: is currently unavailable. DotNetNuke.Services.Exceptions.ModuleLoadException: s1\DesktopModules\Admin\Extensions\Install.ascx.cs(871): error CS0433: The type 'ICSharpCode.SharpZipLib.ZipException' exists in both '...\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\...\SharpZipLib.DLL' and '...\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\...\OnyakTech.WeatherControl.DLL' ---> System.Web.HttpCompileException: s1\DesktopModules\Admin\Extensions\Install.ascx.cs(871): error CS0433: The type 'ICSharpCode.SharpZipLib.ZipException' exists in both '...\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\...\SharpZipLib.DLL' and '...\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\...\OnyakTech.WeatherControl.DLL' at System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath) at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate) at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate) at System.Web.UI.TemplateControl.LoadControl(VirtualPath virtualPath) at DotNetNuke.UI.ControlUtilities.LoadControl[T](TemplateControl containerControl, String ControlSrc) at DotNetNuke.UI.Modules.WebFormsModuleControlFactory.CreateModuleControl(TemplateControl containerControl, ModuleInfo moduleConfiguration) at DotNetNuke.UI.Modules.ModuleControlFactory.LoadModuleControl(TemplateControl containerControl, ModuleInfo moduleConfiguration) at DotNetNuke.UI.Modules.ModuleHost.LoadModuleControl() --- End of inner exception stack trace ---

Reviewing the error shows two different files were clashing:

…\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\…\SharpZipLib.DLL

and

…\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\…\OnyakTech.WeatherControl.DLL

Conveniently the newer version of DNN highlights information about an installed extension, informing whether it has been installed throughout the portals.

Navigating to the Hosts Extensions page I checked whether the OnyakTech weather module was associated with any page. It was showing as unused. I was therefore able to uninstall it without it affecting the website content.

With the OnyakTech weather module deleted the website error was gone. All was well once more.

Creating a DNN Private Page to Share Information

Creating a DNN private page which is viewable only by members of an organisation is a great way of sharing information.

A private page on a website is viewable anywhere with an Internet connection.

Restricting access by user role allows the information to be kept away from public view.

The organisation website can be kept succinct and focused with public information, with pages available on a members only basis.

Ensure that the information made available isn’t sensitive. Whilst the content will be on pages which have restricted viewing it’s possible to inadvertently make a page public.

Information made available could be:

  • websites associated with the business
  • location information, access, parking
  • equipment operational overview

To restrict access to a page. The page is hidden from public view and given a user role which is assigned to the limited set of users.

There are three aspects to providing private information on a DotNetNuke website

  • Use roles
  • Users
  • Pages

A specific new user role is created which will be used to restrict access.

A DNN private page is created with the permissions configured to restrict viewing access to this role.

Having created the user role this can be assigned to existing users, allowing them to view the page and its contents.

Follow this sequence to create a new user role; a new user; assign the role to the user and a new page and add the private role to its permissions.

Create a new User Role

A user role is created which will be used to restrict access to some pages. Making a private address of the website for members of an organisation.

Whilst logged into the website as an administrator hover over the Admin item in the top control bar and from the first (single gear) menu list select Security Roles.

DNN creating role based pages select security roles

At the bottom of the list click on Add New Role.

DNN creating role based pages add new user role

Complete the details for the new role, including a Role name. Maybe chose a role name which will indicate its purpose.

I chose to make the role name relevant to its organisation only access, calling the role staff.

Do NOT set the role as public and likewise Auto Assignment is also not set.

Click on Update at the bottom to save the new role.

Create a new user

From the control bar at the top of the page select User Accounts.

DNN creating role based pages select user accounts

At the bottom of the table click on Add New User.

DNN creating role based pages user accounts list

Complete the fields for the new user.

DNN creating role based pages add new user

Click on the blue Add New User button at the bottom.

Assign User Role to User

To enable a user to view the private page, the restrictive staff role, previously created,  is assigned to the user.

From the list of users click on the edit pencil at the left end of the row to edit the user details.

DNN creating role based pages edit new user

Click on the Manage Roles for this User tab at the top.

DNN creating role based pages manage roles for new user

From the security role drop down list select the security role previously added.

Ignore the date period, the role is to be permanently assigned to the user. Click on Add Role to User button, to the right.

DNN creating role based pages add role to user

To finish adding the role to the user click on Close.

Creating a DNN Private Page

With the role created and assigned to the respective users this leaves the creation of the members only pages.

Navigate to one of the menus within the menu, choosing an ordinary non-admin page. I have found in the past that pages created from an admin or host page have had issues when changing their menu tree position.

I’m assuming that a new page will be added which is private, rather than converting the permissions of an existing page.Create a new page.

DNN creating role based pages select add new page

From the admin menu select Add New Page.

DNN creating role based pages select page details

With the page details entered click on the Permissions tab.

DNN creating role based pages select page permissions

The restrictive role is shown in the list of roles. Click on the check box to enable this page to be viewable by members of this role.

Uncheck the public role.

If you are creating a new page don’t forget to check that it has been assigned the correct permissions to restrict is viewing. Test with a browser which isn’t logged in and also preferably using an account with one of the basic access rights.

Storing information as hidden private content on a website allows access from anywhere with Internet access.

Make information available from anywhere just for members of your organisation with a DNN private page.

XML File for use with DotNetNuke Skin

DNN uses an XML file to provide the configuration settings for skins based upon HTML files.

The XML file details such options as whether the menu is vertical or horizontal

There are two methods of DotNetNuke skin creation,

  • Writing the .ascx file and associated files
  • Bundling an html file and associated components into a zip file.

The naming of the zip file will be the first half of the skin title in the admin settings skin options. The second part of the name is defined by the naming of the html file.

A zip file called MySkin.zip and an HTML file called orange.html will give an entry called MySkin – orange.

Creating a DNN skin based on an HTML file an associated XML file is bundled to add the configuration parameters.

Given below is a sample XML file. This is used to further describe the skin objects. Of particular note is the Horizontal setting for the [MENU] object. The XML file should be given the same name as its associated HTML file.

  <Object>
    <Token>[MENU]</Token>
    <Settings>
      <Setting>
        <Name>Display</Name>
        <Value>Horizontal</Value>
      </Setting>
    </Settings>
  </Object>
  <Object>
    <Token>[ACTIONS]</Token>
  </Object>
  <Object>
    <Token>[ICON]</Token>
  </Object>
  <Object>
    <Token>[LINKS]</Token>
  </Object>
  <Object>
    <Token>[TITLE]</Token>
  </Object>
  <Object>
    <Token>[VISIBILITY]</Token>
  </Object>
  <Object>
    <Token>[LOGIN]</Token>
    <Settings>
      <Setting>
        <Name>CssClass</Name>
        <Value>skinLogin</Value>
      </Setting>
    </Settings>
  </Object>
  <Object>
    <Token>[BANNER]</Token>
  </Object>
<Object>
    <Token>[BREADCRUMB]</Token>
    <Settings>
    <Setting>
      <Name>Separator</Name>
      <Value><![CDATA[ » ]]></Value>
    </Setting>
    <Setting>
      <Name>RootLevel</Name>
      <Value>0</Value>
    </Setting>
  </Settings>
  </Object>
  <Object>
    <Token>[COPYRIGHT]</Token>
    <Settings>
      <Setting>
        <Name>CssClass</Name>
        <Value>skinCopyright</Value>
      </Setting>
    </Settings>
  </Object>
  <Object>
    <Token>[CURRENTDATE]</Token>
    <Settings>
      <Setting>
        <Name>CssClass</Name>
        <Value>skinCurrentdate</Value>
      </Setting>
    </Settings>
  </Object>
  <Object>
    <Token>[DOTNETNUKE]</Token>
  </Object>
  <Object>
    <Token>[HELP]</Token>
  </Object>
  <Object>
    <Token>[HOSTNAME]</Token>
    <Settings>
      <Setting>
        <Name>CssClass</Name>
        <Value>skinhostName</Value>
      </Setting>
    </Settings>
  </Object>
  <Object>
    <Token>[LOGO]</Token>
  </Object>
  <Object>
    <Token>[PRIVACY]</Token>
    <Settings>
      <Setting>
        <Name>CssClass</Name>
        <Value>skinPrivacy</Value>
      </Setting>
    </Settings>
  </Object>
  <Object>
    <Token>[SIGNIN]</Token>
  </Object>
  <Object>
<Token>[TERMS]</Token>
<Settings>
      <Setting>
        <Name>CssClass</Name>
        <Value>skinTerms</Value>
      </Setting>
    </Settings>
  </Object>
  <Object>
    <Token>[USER]</Token>
    <Settings>
      <Setting>
<Name>CssClass</Name>
      <Value>skinUser</Value>
      </Setting>
    </Settings>
  </Object>
</Objects>

I prefer to write a DNN skin using the .ascx files, including the parameters with the controls.

DNN Admin Site Settings Duplicate Key

Reapplying a DNN skin caused duplicate key error. Reviewing the portal directories revealed the caused of the error.

Wishing to make a minor change to a DotNetNuke skin I left the version number as is.

Uploading the file I confirmed the overwrite.

Following the addition of this updated skin to the DotNetNuke website. The Admin Site Settings page was giving the key error:

An item with the same key has already been added

I initially thought that this was a repeat of the duplicate database entries covered in the article Site Settings same key

Reviewing the error log (Admin Event Log) the expanded error was as shown below:

AssemblyVersion:7.3.2
PortalID:0
PortalName:---
UserID:1
UserName:---
ActiveTabID:68
ActiveTabName:Site Settings
RawURL:/Admin/Site-Settings
AbsoluteURL:/Default.aspx
AbsoluteURLReferrer:http://---/
UserAgent:Mozilla/5.0 (X11; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0 Iceweasel/39.0
DefaultDataProvider:DotNetNuke.Data.SqlDataProvider, DotNetNuke
ExceptionGUID:---
InnerException:An item with the same key has already been added.
FileName:
FileLineNumber:0
FileColumnNumber:0
Method:System.ThrowHelper.ThrowArgumentException
StackTrace:
Message:
DotNetNuke.Services.Exceptions.PageLoadException: An item with the same key has already been added. ---> System.ArgumentException: An item with the same key has already been added.
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
at DotNetNuke.Web.UI.WebControls.DnnSkinComboBox.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
--- End of inner exception stack trace ---
Source:
Server Name: ---

Still suspecting three same error i navigated to the SQL page to list the entries in the PortalSettings table. I saw no duplicate entries.

Previously I have observed an issue whereby the same skin was installed under both the _default portal and the site portal.

This was only a small installation of one portal. Looking in the directories /Portals/0 and /Portals/_default I was unable to see the same skin repeated. It had been installed to the active portal directory.

Looking further I reviewed the directory /Portals/0-System. Within this directory I was able to see the duplicate skin and container entries.

Removing the duplication of the skin and container from the/Portals/0-System directory resolved the error An item with the same key has already been added. I was then able to enter the Site Settings page.

Making a DNN Skin Responsive

I was tasked with updating an older DNN website skin to make the website responsive, for mobile viewing.

Wishing to turn an old DNN website responsive, what actions are to be considered?

Shown below is the website as it was viewed on a mobile phone.

Desktop View

Having recently created a number of responsive themes I had worked on this DNN skin ensuring that tables were re-created as floating DIVs. Ensuring that content panes would move to the correct new location and resize appropriately. Images were considered regards their size. And forms were configured to transform the side-by-side label and field input into label above input.

Shown below is the responsive version of the website, with the top navigation buttons centred and the right pane navigation moved below, allowing the content to be full width,

Responsive View

For modern compatibility I chose to set the DocType of the skin to HTML.

Whilst making the changes, I had tested using the common browsers on a desktop VM.

However, the viewed page at this point will still be a desktop view, as shown in the first image at the top of the page. The viewport needs to be configured to ensure that the correct response was shown on mobile devices.

DocType

DotNetNuke allows the DocType of individual skin options to be set by incorporating an associated DocType file. This will override the fall-back configured under host settings.

In the skin directory associate with each theme .ascx file a DocType file, eg:

home.ascx
home.css
home.doctype.xml

Within the doctype file add a single line to make the DocType definition, for example for a DocType of HTML:

<SkinDocType><![CDATA[<!DOCTYPE html>]]></SkinDocType>

Viewport

To configure the viewport a meta tag is added to the head of the website. However, DotNetNuke skins don’t directly allow access to the head section of the HTML code.

One option is to add a control which will write the relevant information to the HEAD.

The installed version of DotNetNuke was 7.4.1. I chose to use its Site Settings configuration option to add the Meta tag.

Navigate to the Advanced Settings tab, found on the Admin, Site Settings page.

Shown below is the Page Output Settings section expanded to show the HTML Page Header Tags field.

Site Settings

Add the viwport meta tag to the bottom of the list and click on update.

<meta name=”viewport” content=”width=device-width, user-scalable=yes”>

With this viewport setting in place the website could be viewed correctly on mobile devices.