Monday, September 19, 2011

Permanent Redirects in ActiveCampus CMS

I recently received a request on how to handle Permanent Redirects (301 Redirects) in Datatel's Active Campus... So without further ado, here is my solution to that problem.

First thing I did was create a new Template, in my case titled Template404.aspx. Be sure to include any .NET Controls specific to your implementation...

<%@ OutputCache NoStore="true" Duration="1" VaryByParam="none" %>
<%@ Page Language="C#" AutoEventWireup="true" Inherits="ActiveCampus.Websites.Controls.CMSPage" StyleSheets="/Website Resources/css/SiteStyle.css:all|/Website Resources/css/SiteStylePrint.css:print" Async="true" %>
<%@ Register Src="/Templates/controls/404control.ascx" tagName="control404" TagPrefix="control404" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head id="Head1" runat="server">
    <title>Central Wyoming College - Page Not Found Error</title>
    <script language="javascript" src="/Media/Website%20Resources/scripts/mootools.js" type="text/javascript"></script>
    <script language="javascript" src="/Media/Website%20Resources/scripts/AC-Core.js" type="text/javascript"></script>
    <script language="javascript" src="/Media/Website%20Resources/scripts/AC-LightBox.js" type="text/javascript"></script>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<!--[if lte IE 6]>
    <link rel="stylesheet" type="text/css" href="/Media/Website%20Resources/css/SiteStyleIE6.css" />
    <![endif]-->
<link rel="icon" type="image/vnd.microsoft.icon" href="/Media/Website Resources/Favicon.ico" />
</head>
<body id="body" runat="server">
<div id="pageCt" class="search">
    <form id="form1" action="/" runat="server">
        <div id="pageCtInner">
            <div id="pageCtBG">
                <div id="zoneCt">
                    <div id="gridCt">                                            
                        <div id="zone2">
                            <div id="centerContent">
                                <control404:control404 id="control404" runat="server" />
                            </div>
                        </div>
                        <div id="zone1">
                
                        </div>
                        <div class="spacer"> </div>    
                    </div>
                    <div class="spacer"> </div>
                </div>
                <div class="spacer"> </div>
            </div>
            <div class="spacer"> </div>
            <div class="spacer"> </div>
        </div>
        <div class="spacer"> </div>
    </form>
    </div>
</body>
</html>
Next, I needed to create the .NET control that actually handles all of my redirects. Now mind, you my method is to have all redirects in a central location. This is also useful for those short hand URL's that you want to go somewhere deep into the site. Like perhaps, www.cwc.edu/library will actually take you to www.cwc.edu/resources/library. This way our library, has a short link they can advertise on their materials. Also, much easier for users to remember the shorter version, then trying to remember to add in resources. So for my example, I'm going to handle some Library Page redirections we used. To add additional, pages, you simply add additional case statements. Additionally, the last part of this script, also takes care of the case when somebody enters cwc.edu (I then want to push them automatically to the www.).

<%@ Language=VBScript %>

<%
' Permanent redirection
Dim str = Request.RawUrl.Replace("/404error.aspx?404;http://www.cwc.edu:80","")
str = str.Replace("/404error.aspx?404;http://cwc.edu:80","")
str = str.tolower
If Request.QueryString("aspxerrorpath") <> String.Empty Then
   str = Request.QueryString("aspxerrorpath").tolower
End If
'Handle Academic Program URLs
If str.indexOf("/academics/programs-of-study/") >=0 or str.indexOf("/Academics/Programs-of-Study/") >=0 Then
      Response.Status = "301 Moved Permanently"
      Response.AddHeader ("Location", "http://www.cwc.edu/academics/programs/")
else
Select Case str.tolower
   Case "/resouces/library/testingcenter/testcenterrec.aspx"
      Response.Status = "301 Moved Permanently"
      Response.AddHeader("Location","http://www.cwc.edu/resources/Library/testingcenter/testcenterrec.html")
   Case "/resources/library/testingcenter/fees.aspx"
      Response.Status = "301 Moved Permanently"
      Response.AddHeader("Location","http://www.cwc.edu/resources/Library/testingcenter/Fees.htm")
   Case "/resources/library/testingcenter/clep.aspx"
      Response.Status = "301 Moved Permanently"
      Response.AddHeader("Location","http://www.cwc.edu/resources/Library/testingcenter/Clep.htm")
   Case "/resources/library/testingcenter/default.aspx"
      Response.Status = "301 Moved Permanently"
      Response.AddHeader("Location","http://www.cwc.edu/resources/Library/testingcenter/default.htm")
   Case "/resources/library/librarydistance.aspx"
      Response.Status = "301 Moved Permanently"
      Response.AddHeader("Location","http://www.cwc.edu/resources/Library/librarydistance.htm")



   Case Else
      Response.write ("<p>Oops... This page can't be found. Please visit the <a href='http://www.cwc.edu/azindex.aspx'>Site Map</a> for a listing of pages.<br />Error Page: " & str & "<br />Also try search at the top of the website to find the page you are looking for.")
Dim strRootURL = Request.URL.ToString.Replace("http://cwc.edu/Cache/Templates/Template404.aspx?=404;","")
'Response.write("<p>URL: " & strRootURL)
if strRootURL.startswith("http://cwc.edu") Then
strRootURL = strRootURL.Replace("http://cwc.edu","http://www.cwc.edu")
Response.Redirect(strRootURL)
End If
End Select
End If
Response.End
%>
Next you'll add this template to the Website Workflow. You do that by going to Website, Right clicking the top "Website" folder and selecting Workflow Properties. Click the Template Groups Tab then select your template bundle. Now click the Templates tab in the bottom section. Goto the bottom, and click the add button to add your template. Click Ok, and exit the workflow.

Now you should be able to create a page with this template. It is not necessary to enter the template designer. Just make sure the page is published. Make sure the page loads up in your browser by pointing directly to it.

This next part, will cause a short pause and delay, so I recommend that you do it during non-peak hours. Also, create a backup of your web.config file before making any changes.

On the public website instance, open the web.config file. And search for <customerrors. Assuming you have not modified it at all, you can change it to:

<customErrors mode="On" defaultRedirect="ErrorPages/ErrorPage.aspx" />
Modify the defaultRedirect location to be the location of your error. In our case, we want users to always just think it is a page not found error, even if there is a programming error in a form. But you can also modify it to handle just 404 error types.

That should do it.

Hopefully this helps you out down the road!

Paul

Thursday, May 20, 2010

Custom Programming in ActiveCampus

So, your school uses ActiveCampus? Perhaps your school needs to list a staff directory and you want to be able to have it updated automagically instead of hand updating a content type for each user as they come and go with their employment. Well I'm hear to say that it appears to be fairly straight forward process. You can even embed the component into the CMS and your templates. Unfortunately, I haven't found a way to make it so that you can drop your custom program into a dropzone. Perhaps I'll get that figured out as well? I don't know if it's possible, but Test servers are meant to be borked and re-imaged right?!

ActiveCampus is developed in ASP.NET, so therefore, I created my app in ASP.NET as well. For my personal preference I am using C#. I created a new Web Application in Visual Studio. For my first run through, I created a test control that is basically Hello World. I created my control, and compiled the code to create an ASP.NET Assembly. I then copied the assembly into the bin directory of both the console and the public site. For my instance, I named my assembly myschool_CustomProgramming.dll.

Next up copied the code on the ASCX control into a new template under Website->Templates. I put it in a new folder called customControls. I then edited a Template to reference and use this control.

The result is that i get a functioning template that I can still add items to the drop zone in, and yet still have the capability to have my custom programming. I created a page using this template, and the result was a functioning page that uses both the ActiveCampus processes and my own assembly as well.

On a side note, I highly suggest that you put all of your custom programming into a safe and unique class structure to ensure that you cannot interfere with their programming. In my case, I just used myschool_CustomProgramming.

Right now, I'm working on building our Staff Directory and online email form so that it is embedded directly into our site.

Please note that most likely anytime you upgrade the system, you will probably need to re-add your custom components. I will be testing that in the near future when I update our test environment to the latest version from Datatel. In any case, this method allows your code to run independently of their programming. If you wished, you may be able to bring in their components and link to some of their classes, but I haven't gone down that road yet. (Might be useful for database connectivity). In the meantime, I'm just using my own custom components for accessing the database, using the same connection methodology that they have setup.

So far this is just a proof of concept. Hopefully by mid-June I'll have something in production to show everyone.

Paul

Friday, April 4, 2008

Using mod rewrite in Apache

In a previous post I discussed URL rewriting in .NET. I was recently asked for advice on rewriting URLs in an Apache environment. So below is my answer to that question.

In the .htaccess file we do the following:
RewriteEngine On
#if query sting exists, then append to var2
RewriteCond %{HTTP_HOST} ^myschool\.edu$ [NC] RewriteRule ^(.*)$ http://www.myschool.edu/$1
RewriteCond %{QUERY_STRING} ^(.*)
RewriteRule ^(.*)((.(htm|php))|\/)$ pages.php?var1=$1&%1 [L] RewriteRule ^$ home.htm [L]
[R=301,L]

(Entries preceded by # are commented lines of code.)
The first line, RewriteCond is checking to see if the URL is http://myschool.edu/<restofdomain>. In that case we change it to http://www.myschool.edu/<rest of domain>. The R states that this is a forced redirection (thus is updates the URL's browser to display www.myschool.edu instead of just myschool.edu. 301 is the code, meaning permanent redirection. L means last command, stop executing. (When this occurs, it will restart the Rewrite condition upon load.)
The next rewriteCond command is to ensure any pre-existing Query Strings are passed on.
The next Rewrite rule, checks to see if the page includes a .htm, .php, or a forward slash (/).
If so we rewrite the URL as described. The [L] signifies that last command.
Lastly, if it's not that, then that means it's just www.myschool.edu in which case we modify it to be www.myschool.edu/home.htm

Basically we are rewriting the URL behind the scenes to the appropriate page. Here is an example
http://www.myschool.edu/Current-Students.htm is rewritten to http://www.myschool.edu/pages.php?var1=Current-Students
From there, our pages.php code retrieves the appropriate page from our CMS (home-grown in our case) and builds the page based on its settings. (Currently our pages are always built dynamically instead of dynamically.)
However, in the browser it still appears as the original URL.
For more information on mod_rewrite click here.

Thursday, November 8, 2007

Using the NWS Web Service to get forecast

My wife, as many of you know, works for the National Weather Service here in Riverton. So when it came time to redesign our company's website, I decided that I was going to show the forecast from them using their Web Service. For the most part this is a very simple task, except for one small modification that has to be done to the Reference.vb File.

So First of all, Create a Web Application.

Verify that the following Assemblies are included:
  • System.Web.Services
  • System.XML
Right click on the References folder, and click "Add Web Reference"

Enter the URL: http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl

Now normally, you can simply start using the WebService at this point. However, for this one, you need to do some custom editing the Reference Map associated with the Web Service. Under the Project menu, click the button for Show All Files.

Then navigate to the Reference.vb file.


Add the following method after the existing New() Routine:

Protected Overrides Function GetWebRequest(ByVal uri AsUri) As
System.Net.WebRequest

Dim webRequest As System.Net.HttpWebRequest =
MyBase
.GetWebRequest(uri)

webRequest.KeepAlive =

False


Return
webRequest

End Function

Ok now, it is time to edit
the WebForm1.aspx.vb file. For simplicity sake, import the following items:


Imports System.Xml


Imports System.Xml.Xsl


Imports System.Text


Imports System.Configuration


Imports System.IO



Optionally you may also imports the gov.weather.www Namespace.

Now, Lets declare the variables we're going to use.


Dim ndfdXML As New
gov.weather.www.ndfdXML


Dim result As
String


Ok, phew that was easy. Now to retrieve the forecast information, we will use the NDFDgenByDay function which uses the following parameters:



latitude As Decimal


longitude As Decimal

startDate As Date

numDays As String

format As gov.weather.www.formatType

For my case, I'm going to give you the forecast for Riverton, Wyoming, for the next 3 days. So the code will appear as such.


result = ndfdXML.NDFDgenByDay(43.1806, -108.926, Now, 3, gov.weather.www.formatType.Item12hourly)

From here, you can do as you wish to display the data you are looking for. Shortly, I will add a new post that explains how to take this data, then using XSL, transform it into reader friendly HTML Code complete with the NWS images displayed for weather conditions.