Posts From November, 2008

mojoPortal 2.6

mojoPortal 2.6

Today, we're pleased to announce the release of mojoPortal 2.6. We had planned on releasing this version much sooner but we kept adding features! In the future, we're planning on releasing about once per month. Larger features will take more time but our community shouldn't wait for smaller enhancements.

With this release, we're introducing SuperFlexi and the Blog Post List modules. We also have a lot of enhancements and new features for existing modules. Finally, we've made some improvements to Framework and we're releasing a new free skin called "Scout", which can be downloaded from the mojoSkins project.

Where to Get It?

Head over to our GitHub Releases Page.

SuperFlexi

The SuperFlexi module is intended to serve as an easy templating system that works as a go-between for front-end developers and users. Developers can easily create "Solutions" that determine, to a large extent, the module's uses; controlling both what kind of input users can store in the database and what markup is created on the page. Users can then simply select a "Solution" in the module settings, and create their content with straightforward easily-understood forms, which will then be rendered as determined by the developers defined markup.

SuperFlexi aims to give end users much easier control over their content, even when that content might normally be quite complicated (as in the case of sliders, tables, structured or gridded HTML, and many other things). Possible uses for SuperFlexi are virtually limitless and we're really excited to be adding it as a core module in mojoPortal 2.6.

With mojoPortal 2.6, we're including 8 solutions; Accordion, Banner Slider, Icon Blocks, Image Blocks, Personnel List, Quick Links, Social Media Links, and Tabs. Each of these is demonstrated on the mojoPortal Demo Site. Please note, SuperFlexi does not currently support SQLite and PGSQL. We should have support for those database platforms in a couple of weeks.

To learn more about SuperFlexi, check out the documentation. We've also created a new Forum, just for SuperFlexi.

Blog Post List Module

So, for a very long time, the official guidance for showing a list of blog posts on pages other than the page your blog is on was to use the Feed Manager to consume your blog's RSS Feed. This meant that the Feed Manager had to make an http(s) connection back to your site, consume the feed, cache the feed contents in the database, and then query the database for the cached contents. Granted, the connection and subsequent caching only happened on a set interval but it was very unnecessary. We decided to cut out the middle-man (Feed Manager) and create a module which connects directly to a chosen Blog module and displays the posts. We went a step further by creating a Razor View Engine for this new module. Yes, you read that right, Razor. You can create Razor views to control the display of this new module.

To learn more about the Blog Post List module, head over to the documentation.

Blog Updates

We spent some time on the Blog and besides the wonderful new Razor-enabled Blog Post List, we have added Post Featured Image, Blog Featured Post, and automatic Meta Content creation for Facebook, Twitter, and Schema.org.

Post Featured Image

You can now easily add a featured image to each of your blog posts. This image will be used in the meta elements added to the page for Facebook, Twitter, and other social media outlets. The image is also treated a bit special by the Blog in that it is shown at the top of posts. More on the Post Featured Image.

Featured Post

This feature allows you to set a single post in your blog as "Featured". That post will always be at the top of the post list, even when using the Blog Post List module. More on the Blog Featured Post.

Automatic Meta Content Creation

Sharing posts on social media is a lot easier now because the special meta content markup that is necessary for sites like Twitter and Facebook to show correct titles and post images is now automatically added when you create a post. You can even edit the meta content that is created by editing the post and clicking the "Page Meta Data" tab (we're gonna change that to "Post Meta Data" in the next release).

Other Blog Updates

  • Added Display Settings for the Blog module to allow for easier skinning via CSS classes
  • Updated to actually move the blog navigation in markup instead of changing places with CSS * floats for easier styling
  • Cleaned up a lot of the default markup
  • Panels with no child elements will no longer be rendered
  • Added option to include comment body in comment notifications
  • Added SkinID="Blog" to CommentsWidget
  • Removed "Feed Links". These were links to old MSN, Yahoo and other defunct feed managers.
  • Added option to allow Post Title to be used as Page Heading when the PageHeading (or PageTitle) control is used in the layout.master for the skin

ASP.NET 4.6.2

mojoPortal now requires ASP.NET 4.6.2, which was released in August of 2016. Most hosting providers already support 4.6.2 so you should be fine upgrading your site. If your host doesn't support it and you purchase a hosting plan with i7MEDIA, we'll move your site for free.

TLS 1.2

mojoPortal will now enforce using TLS 1.2 for outgoing connections. This is important for connections to payment processors like Authorize.Net, WorldPay and PayPal.

Site Settings

The Site Settings page has a lot of options for configuring your site. We're actually working on moving more stuff from the web.config to the UI so it'll be easier to configure your site. Knowing that we are going to be adding even more to Site Settings, we implemented a few changes and reorganized some things to make using the Site Settings page easier. In the future, we plan on breaking this single page up into several smaller and more task oriented pages. In this release, you'll notice the following:

  • "Site Title" field moved to the General tab
  • "New Site" link removed (to add another site, go to Administration > Site List)
  • Skin options grouped on the General tab
  • Content Editor options grouped on the General tab
  • Registration options grouped on the Security > Main tab
  • User Account options grouped on the Security > Main tab
  • "Avatar System" option moved to User Account group under Security > Main tab
  • Password options grouped on the Security > Main tab
  • Security > OpenID tab renamed to "3rd Party Auth"
  • OpenID options grouped on the 3rd Party Auth tab
  • Windows Live options grouped on the 3rd Party Auth tab
  • "Host Name Mapping" and "Folder Name Mapping" moved to a single tab called "Site Mappings".
  • "SMTP Settings" tab renamed to "Mail Settings"
  • "Mail Settings" tab is always visible with information on how to enable the fields there. New sites will, by default, use this area for SMTP settings. You can enable this on your site by following the instructions here.
  • "Default Email From Address" and "Default Email From Alias" moved to "Mail Settings" tab
  • Reordered Recaptcha Site/Secret keys to match order on Recaptcha site
  • Added several contextual notes throughout the Site Settings page

Change Log

This change log isn't exhaustive because a lot of changes are already listed above. If we didn't list it above, it should be listed below.

Core

  • Updated mojoPortal to ASP.NET 4.6.2 and C# 7
  • Updated mojoPortal source code to use latest NuGet package management
  • Added RazorBridge method to allow use of MVC Razor Templating in Web Forms controls
  • Added MVC HTML Helper for internal Avatar and Gravatar use in Razor templates
  • Added Link control for inside/outside markup of the link
  • Added AutoEscapeStringForCsv method for exporting data in CSV format
  • Updated Gravatar in Forums to link to mojo user profile by default
  • Fixed File Manager/Page Picker for folder sites and sites running in a virtual directory
  • Moved First Name and Last Name fields to the General tab in the User Profile.
  • Added option to include comment body in notifications
  • Added ExportDynamicListToCSV method to ExportHelper
  • Added ImportHelper with GetDynamicListFromCSV method
  • Removed calls to jQueryFileTree and removed from ClientScripts
  • Removed calls to jQueryLayout
  • Removed call to greybox from Contact Form
  • Fixed possible XSS bug in help dialog
  • Removed WebStore from core (will be available as a separate download from the AddOn store)
  • Cleaned up user.config.sample file
  • Standardized on "Login" instead of "Sign In" (both were used before now)
  • Added Security Protocol information to "Security Advisor" (Administration > Security Advisor)
  • Added CombinePath method to DiskFileSystem file system provider.
  • Added FolderVirtualPath property to WebFile
  • Added NameProperty and ContentProperty to ContentMeta. This allows for creation of meta elements with custom names <meta property="foo" value="bar" /> instead of only allowing for <meta name="foo" content="bar" />

Skinning

  • Added FormGroupPanel control for settingrows to control their classes
  • Updated Site Settings page to use new FormGroupPanel control
  • Updated the Layout.Master.cs to expose SiteSettings (siteSettings), PageSettings (currentPage), isCmsPage and isMobileDevice to the Layout.Master for richer skinning functionality (Check out the layout.master in the Nature theme)
  • Updated CSSHander to allow for "https://" and non-http-specified ("//my-domain.com/") url calls
  • Updated Avatar.cs with new ExtraCssClass property
  • Cleaned up markup of CommentsWidget
  • Added themeable properties to CommentsWidget to help with skinning
  • Added themeable display settings for Contact Form
  • Cleaned up markup of the RelatedNewsletterSetting control
  • Cleaned up markup of HTMLCompare feature (used by version history)
  • Fixed Inline Editing in HTML Module for selecting files/images
  • Fixed CSSHandler for HTTPS URL calls
  • Fixed missing CKEditor Image2 Alignment Classes
  • Added InsideTopMarkup to replace LiteralExtraTopContent in BasePanel
  • Added InsideBottomMarkup to replace LiteralExtraBottomContent in BasePanel
  • Removed the .LESS CSS Utility from the Administration area. We recommend using a tool like Prepros for LESS management.

Silverlight + Google Gears = Awesome! at least in Firefox

I spent most of the week prototyping some things in Silverlight. I figured during the holiday week most people out there goofed off on their jobs a lot this week, so rather than work on my roadmap priorities, I decided to have some fun and play with Silverlight.

Some of you who have followed my blog for a while may remember some posts I made in the past about my plans for Site Office as a second plug in model for mojoPortal more geared to line of business apps that need a consistent look and feel rather than the web site kind of look, they need to look like applications. I originally protyped the UI using Dojo and then later re-did it with ExtJs. You can see the ExtJs version if you login to this site (or http://demo.mojoportal.com using admin@admin.com and password admin), then click the Site Office link at the top. You'll see the drag resizable panes that give the idea of where I wanted to go with Site Office as a UI for LOB applications. This prototype has just been sitting there without much attention because of other priorities and also partly because my enthusiasm for ExtJs disappeared when they changed the license from LGPL to GPL. Anyway, even back then I implemented a google gears query tool. Its really the only functioning app in the old Site Office prototype, you can find it by clicking the My Stuff in the left accordian menu in Site Office and then click SQL. For those who don't know, google gears is a client side SQL database built on SQLite and having this database available opens a lot of possibilities in web development for very rich and responsive applications.

Well, now my plan is to scrap the old ExtJs based Site Office prototype and build a better one with Silverlight. I've already got the Google Gears Query Tool re-implemented in Silverlight as shown below:

silverlight google gears query tool ascreenshot

I wrote a nice managed code wrapper around the javscript calls for gears. The only problem is, it doesn't work well in IE 7 for some reason, it works great in Firefox. I've sent an email off to Scott Guthrie at Microsoft in hopes of some help looking into the problem, but for now you can try it out online at http://demo.mojoportal.com/Index.aspx, you can see that I've got the basic layout of Site Office again implemented in Silverlight with the drag re-sizable panes. I plan to build a plug in model that allows you to plugin your own Silverlight applets and let the framework provide stuff thats common across applications. If I can get google gears working well across browsers with Silverlight its really going to be sweet. The code for this is in my svn sandbox and will probably land in trunk sometime next week.

Now using the managed gears wrapper can be seen in this client side business/data class, it looks very much like a server side class but its a client side object populated from a client side database in a very similar fashion to what it would look like in server side code. Notice the parametrized queries to prevent sql injection attacks. This class represents a saved query but it could represent anything.

using System;


namespace mojoPortal.Silverlight.Helpers.Gears
{
   
    public class SavedQuery
    {
        public SavedQuery()
        {}

        private int id = -1;
        private string name = string.Empty;
        private string query = string.Empty;

        public int Id
        {
            get { return id; }
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public string Query
        {
            get { return query; }
            set { query = value; }
        }

        public void Save(GearsDb gearsDb)
        {
            if (id == -1) { Create(gearsDb); return; }

            Update(gearsDb);
        }

        private void Create(GearsDb gearsDb)
        {
            if (gearsDb == null) { return; }

            string sqlCommand = "insert into savedqueries (name, query) values (?, ?)";
            object[] parameters = new object[2];
            parameters.SetValue(name, 0);
            parameters.SetValue(query, 1);
            gearsDb.Execute(sqlCommand, parameters);
            id = gearsDb.LastInsertRowId();

        }

        private bool Update(GearsDb gearsDb)
        {
            if (gearsDb == null) { return false; }

            string sqlCommand = "update savedqueries set name = ?, query = ? where id = ?";
            object[] parameters = new object[3];
            parameters.SetValue(name, 0);
            parameters.SetValue(query, 1);
            parameters.SetValue(id, 2);
            gearsDb.Execute(sqlCommand, parameters);
            int rowsAffected = gearsDb.RowsAffected();
            return (rowsAffected > 0);
        }

        public static SavedQuery GetQuery(GearsDb gearsDb, int id)
        {
            if (gearsDb == null) { return null; }
            string sqlCommand = "select * from savedqueries where id = ?";
            object[] parameters = new object[1];
            parameters.SetValue(id, 0);
            GearsResultSet rs = new GearsResultSet(gearsDb.Execute(sqlCommand, parameters));

            SavedQuery query = null;
            if (rs.IsValidRow())
            {
                query = new SavedQuery();
                query.id = Convert.ToInt32(rs.GetFieldValue("id"));
                query.name = rs.GetFieldValue("name").ToString();
                query.query = rs.GetFieldValue("query").ToString();
            }
            rs.Close();

            return query;
        }

        public static SavedQuery GetQuery(GearsDb gearsDb, string name)
        {
            if (gearsDb == null) { return null; }

            string sqlCommand = "select * from savedqueries where name = ?";
            object[] parameters = new object[1];
            parameters.SetValue(name, 0);
            GearsResultSet rs = new GearsResultSet(gearsDb.Execute(sqlCommand, parameters));

            SavedQuery query = null;
            if (rs.IsValidRow())
            {
                query = new SavedQuery();
                query.id = Convert.ToInt32(rs.GetFieldValue("id"));
                query.name = rs.GetFieldValue("name").ToString();
                query.query = rs.GetFieldValue("query").ToString();
            }
            rs.Close();

            return query;
        }

        public static bool Delete(GearsDb gearsDb, int id)
        {
            if (gearsDb == null) { return false; }
            string sqlCommand = "delete from savedqueries where id = ?";
            object[] parameters = new object[1];
            parameters.SetValue(id, 0);
            gearsDb.Execute(sqlCommand, parameters);
            int rowsAffected = gearsDb.RowsAffected();
            return (rowsAffected > 0);

        }

    }
}

Update 2008-12-23

I have narrowed down the problem with IE and use of Google Gears in Silverlight. All the Gears functionality works except for 2 methods. The 2 methods broken in IE are GearsResultSet.GetFieldName(int fieldIndex) and GearsResultSet.GetFieldValue(int fieldIndex). I can get the field value if I know the field name ahead of time using GearsResultSet.GetFieldValue(string fieldName), so for most applications I should still be able to use Gears even in IE because my field names will be known ahead of time. Unfortunately for the query tool we have no way of knowing what fields will be in the result of ad hoc queries. So the query tool will only be useful in Firefox, but for other features I should be able to use gears without any trouble and this is very good news. I also have got a few web services talking to Silverlight, so I'm able to authenticate and get user roles. These services are actually built into the framework so I didn't have to implement them. I am working on some RESTful web services using the WCF REST Starter Kit.
 

Gravatar Joe Audette is the founder of the mojoPortal project and was the primary developer until February 2017.

mojoPortal 2.2.7.9 Released

I'm happy to announce the release of mojoPortal 2.2.7.9, available now on our download page.

New Related Sites Mode

mojoPortal has for a long time had the multiple sites feature which enables you to host multiple sites on a single installation using a single database. The feature was carefully designed to keep the sites and users completely independent so that each site is isolated from the others from a security perspective. But for some scenarios its desirable to host multiple sites but use the same users and roles in all of them. For example, maybe you want to have different versions of your site for different languages bu you want the same users in all of the sites. Or maybe a university wants to create separate sites for different departments but they want the students to have the same sign in credentials in all of them. This is now possible with simple configuration settings as indicated in the documentation. Multiple sites can be configured either based on host names or by folders beneath the root site. With the folder based sites, since they share a common cookie, once the user is signed into any of the sites he is signed into all of them.

New 301 Redirect Manager

When you create pages in mojoPortal, the page gets a friendly url based on its title, like /fun-stuff.aspx would be the url for a page named Fun Stuff. Now if you change the name of the page later it will get a different url, so for example if I change the name to Really Fun Stuff, its going to get a new url /really-fun-stuff.aspx.

Now from an SEO (Search Engine Optimisation) point of view, its not a good idea to be changing your urls willy nilly. If someone bookmarked your old url you don't want it to be broken, or if its already popular in search results, you don't want it to be a broken link. So ideally, you need to have the old page do a 301 redirect to the new page. The 301 status code tells the browser that the page moved permanently. Now mojoPortal will create the 301 redirect for you automatically when you re-name a page or blog post. However, its still not a great idea to be renaming your pages frequently, you should avoid it generally but if you need to its ok to do it. You can also see the 301 redirect mappings and manually manage them from Administration Menu > Advanced Tools > 301 Redirect Manager. You need to be very careful with this feature, you do not want to create circular redirects where 2 urls redirect to each other.

This is the last Release Targeting ASP.NET 2.0

This release as previous ones targets the 2.0 ASP.NET runtime. I requested feedback in my previous post about changing to target the 3.5 ASP.NET runtime and everyone who responded was in favor. I've already changed it in my svn sandbox and will change it in trunk soon. I find that on a machine with VS 2005 I am still able to build and run the solution as long as .NET 3.5 is installed. Using the Mono 2.0 release I could still get it working if I swaped out the Web.config so it used 2.0 version of System.Web.Extensions. Using the latest Mono built from svn I see that the Mono version of System.Web.Extensions has changed to 3.5, but I'm getting an error running it and will have to investigate further.

So the next release will target .NET 3.5. If someone needs a 2.0 build it will be possible for them to change the build target back to 2.0 (in Visual Studio 2008) and rebuild, because I'm not really planning to use 3.5 specific features in the core projects for a while yet. I just need to use the 3.5 version of ScriptManager to support features like Silverlight that I will use in external projects. Just like our other features, the external projects will copy the needed files up to the main Web project so it can work at runtime. This allows us to move forward and take advantage of new things in 3.5 while keeping general compatibility with Mono and 2.0 .NET. Changing the target to 3.5 NET on the core projects only changes the Web.config file and the .csproj file

I'm very excited to start working with Silverlight 2 and RESTful web services using the REST toolkit. I'm just beginning to do exploratory prototyping now but I'm seeing some very cool possibilities.

Gravatar Joe Audette is the founder of the mojoPortal project and was the primary developer until February 2017.

mojoPortal 2.2.7.8 Released

I'm happy to announce the release of mojoPortal 2.2.7.8, available now on the download page.

Important Upgrade Notes

We added a feature to combine and minify the CSS files in the skins. Those using custom skins should modify their skins as described here after upgrading.

This release also contains Oomph, as described in my previous post.

We have a new Croatian language translation thanks to Slaven Brumec.

Other than the above and a few bug fixes and feature tweaks as discussed in the forums since the last release, the main focus of this release is changes to make developers happy as discussed below.

Source Code Project Re-Organization

All of the content features like Blog, forum, Gallery, Maps, etc, have been moved out of the core mojoPortal projects into the mojoPortal.Features.* projects. This makes it possible to build and package a leaner version of mojoPortal without any features except Html Content. I will still continue to make the official mojoPortal releases with all the features, I have no plans to package separate mojoPortal lite packages myself, but the idea is that developers can package their own application with mojoPortal without having to include all the features we have. If you work with the mojoportal-core.sln Visual Studio Solution, it will build without any of the extra features and you can package it with UnLeashIt. If you build the mojoportal-complete.sln solution, post build events will copy the extra features up to the core Web project, so you don't want to do that if you plan to package without those features. Once they are copied up to the Web project UnLeashIt will include them, so you need to keep it clean by not building that solution if you want to package without those features.

As a result of this, features are now basically self contained within folders, like the Blog is in the siteroot/Blog folder and forums are in the siteroot/Forums folder and so on. For backward compatibility I created pages with the old names that will do a 301 redirect to the new pages. I also was careful to make sure friendly urls for existing blog posts would continue to work correctly.

The only thing site owners need to change is if they previously submitted a blog site map to google using siteroot/BlogSiteMap.ashx, you need to change that to siteroot/Blog/BlogSiteMap.ashx

When Should We Target .NET 3.5?

I'd like to gather input and opinions about when we should change the target platform to .NET 3.5. I'm eager to start playing with Silverlight in mojoPortal and it seems to need the 3.5 versions of ScriptManager to host the <asp:Silverlight control

The issues I see are:

  • We need to be careful to keep compatibility with Mono. I think we can move forward with using .NET 3.5 on Windows and continue to build for .NET 2.0 for the MonoDevelop solution. We really won't add non-supported features in the core projects but we need to be able to specify 3.5 settings in Web.config of the core Web project. We already maintain a different Web.config file for Mono packages so this should not be a problem. We can put 3.5 functionality like Silverlight into separate projects and use post build events to deploy them into the main web for runtime as we do with most features. So these projects can be left out of the MonoDevelop Solution until they are supported. In summary I think we can workaround all issues relating to Mono and should be able to move forward while still maintaining Mono compatibility.
  • Hosting - This is the issue I'm not entirely sure of and would appreciate any input. If the next release of mojoPortal for Windows targets the 3.5 runtime is that available at your hosting or will it pose a barrier to upgrade? It seems like most of the big name hosts have .NET 3.5, they don't like to be left behind by the competition.
  • Visual Studio 2005 Issues? - As far as I know VS 2005 can target 3.5 without problems except maybe for Windows Workflow development and it doesn't have some of the built in project templates for 3.5 .NET projects. We already maintain separate VS 2005 solution files so we could leave out any projects if they don't work.

UPDATE:

Forgot to mention that I updated the project road map yesterday.

Gravatar Joe Audette is the founder of the mojoPortal project and was the primary developer until February 2017.

mojoPortal Gets A Little Microformat Oomph

Just integrated Oomph, a javascript Microformat Overlay into mojoPortal. You can watch the PDC presentation about Oomph from this page https://sessions.microsoftpdc.com/public/timeline.aspx, click Day 3 then click Oomph and you can see the video links at the bottom.

Microformats are a way of marking up information in html using some agreed upon conventions that add semantic meaning to the markup. For example hcard, is a format for marking up contact information. What Oomph does is recognize the hcards and hcalendar items in your page and creates a javascript widget in the top left of the page that gives you some neat options for adding contact to your Yahoo Contacts, adding events to your googe calendar, showing event and contact locations on a map using Virtual Earth, etc. Pretty neat stuff. You can see it in action on our consulting list, where I've marked up the content using hcard format. The list view feature of our Event Calendar Pro add on product also renders in hcalendar format so events can show up in the oomph widget. I've shrunk my browser window down a bit to make a screen shot of the widget below but for best impressions try it yourself.

oomph screen shot

Other Developments

I always like to dogfood new features here on mojoPortal.com to work out any issues, so this site is runnning the very latest code from my sandbox.

At the moment I'm also testing some performance optimizations that I just integrated into mojoPortal. As we start to do more ajaxy javascript things in mojoPortal we find ourselves adding a lot of links to javascript files which adds additional http requests to our page. So I've integrated some work by Omar Al Zabir, that he has made available in the very cool Dropthings project. This combines most of our javascript files into one request and moves the javascript to the bottom of the page to improve performance.

A similar issue exists for css files in the skin. We like to organize css into separate files based on logical things from a development perspective, but from a performance perspective we'd like to have only one link to an external css file. I implemented a solution for css files based on some of the techniques I learned from Omar's work. It combines all the css files and minifies them as well using Michael Ash's C# implementation of the YUI Compressor. So far it seems to be working great and I haven't noticed any side effects or problems.

These new feature is only in my sandbox at the moment but will be in svn trunk within a few days.

UPDATE 2008-11-03

Just discovered that moving the javascript to the bottom broke usage of NeatHtml in the forums. Luckily I have Web.config setting to disable the javascript combiner so I have fixed it on this site while I investigate a solution. There is an option that Omar implemented to add a "pin" attribute to any script that you don't want to combine or move to the bottom. The problem is I don't believe that is a valid attribute and it will break xhtml validation to use it, so I will have to find another solution.

UPDATE 2008-11-04

I managed to get a solution to pin some scripts without breaking xhtml validation, so now on this site I'm testing combined scripts again and so far so good.

Gravatar Joe Audette is the founder of the mojoPortal project and was the primary developer until February 2017.