How do I stop search engine crawlers from indexing a Lemoon site? - lemoon

We've got a public site and a test site created in Lemoon 4.5.1, we'd like the test site to not be indexed at all. Is it possible and how do we do it?
We're using web deployment packages when updating the site. So if we add a robots.txt in the test site it will be overwritten everytime we deploy.
When editing a page, there is a "Meta Robots - NoIndex" setting, which probably would suit us fine, but we'd like to avoid editing every page.

I solved it by adding a Meta data key (AvoidSearchEngineIndexing) on the site. In the master page that every page uses I check if it's set or not and adjusts the content in the robots meta tag.
Code behind
protected void Page_Load(object sender, EventArgs e)
{
MetaRobotsContent = "index, follow";
object avoidSearchEngineIndexing;
if (Site.MetaData.TryGetValue("AvoidSearchEngineIndexing", out avoidSearchEngineIndexing) && ((avoidSearchEngineIndexing as bool?) ?? false))
{
MetaRobotsContent = "noindex, nofollow";
}
}
protected string MetaRobotsContent { get; set; }
Markup
<meta name="robots" content="<%= MetaRobotsContent %>

Related

asp.net core pass data from content page to layout

I'm trying to set a master layout.cshtml page that works consistently for all page except for one or two (typically login and logout). In my layout I'd like to display some elements that I want to not display for these special pages.
I've seen partial views and sections and they all seem to work "backwards" to the way I want - in this case I want the default to be 'display all the elements', but for special pages I want to be able to turn an element off.
I've seen previous code that uses PageData to pass a variable to the layout (which seemed very useful as I could slap a bool in the relevant pages and check it in the layout) but this seems to have been removed. Are there any other ways that work without involving the controller or updating every page to display the bits I want hidden on just 1 page?
There's a number of different ways you can achieve this. If you want to simply "turn off" an area of the page, the simplest approach is probably with ViewData. Something like:
_Layout.cshtml
#if (ViewData["ShowThis"] as bool? ?? true)
{
<!-- HTML here -->
}
This will cause it to default to true (show the HTML) if the ViewData key is not defined, so then in your views where you want to disable it, you'd just need to define it as false:
SomeView.cshtml
#{
ViewData["ShowThis"] = false;
}
Alternatively, you can use sections. This would give you the ability to optionally replace the HTML with something else.
_Layout.cshtml
#if (!IsSectionDefined("Foo"))
{
<!-- HTML here -->
}
else
{
#RenderSection("Foo", required: false)
}
Then, in your view, you simply define the section. If you want to display nothing, you can just define it empty:
SomeView.cshtml
#section Foo {}
Or you can can actually put something in there to replace the area with:
#section Foo
{
<!-- alternate HTML here -->
}
You can try this to pass ViewData in _Layout page in asp.net mvc
public class DynamicMenuAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
var result = filterContext.Result as ViewResult;
result.ViewData["key"] = "Hello Bangladesh";
}
}
Add Dependency Injection into Startup.cs file
services.AddMvc(
config =>
{
config.Filters.Add(new DynamicMenuAttribute());
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
Now you can you ViewData["key"] in _Layout.cshtml

How to hide jQuery tabs until authenticated and add or show them once authenticated in MVC3?

Summary
I'm currently trying to build a Web application using MVC 3 architecture and jQuery UI controls. I have been able to display tabs and navigate through them so far.
Now, I am able to get the LogOn page to display on my first tab as it is the first required action to this application.
Once authenticated, I'd like to be able to add some other tabs which allows to use use this application.
The application is about a phone book listing containing known people mailing address.
That said, the workflow of this application would be:
Authenticate upon first arrival on the site;
If the user is not yet registered, the app shall let this very user register once and for all, using the same jQuery UI tab or maybe showing a new tab for registration or else, a modal dialog box;
Once authenticated from step 1, the user has now access to the different features of the site.
For example, let's say I want to register a new user and I am this web-application administrator. I shall first authenticate against this application, and then I'll see the common tabs that any user can see, plus a special tab for creating/registering new users who'll be able to authenticate against this app. once registered successfully by the site admin.
I have already been able to display the LogOn view which I deleted the initial view created by the template to recreate as a partial view to be able to contain it within the jQuery UI tab body. This works fine.
I also have a SelectTab method within my HomeController which shall know what partial view to display depending on the value of the id it is passed in as an input parameter.
Now, when I try to navigate from the LogOn partial view on the first jQuery UI tab, that is actually the only available option yet, clicking the Register link won't let me show the Register partial view within the same tab.
Code samples
The HomeController class:
public class HomeController : Controller {
public ActionResult Index() { return View(); }
public ActionResult SelectTab(int id) {
switch (id) {
case 0: return RedirectToAction("Register", "Account");
default: return RedirectToAction("LogOn", "Account");
}
}
}
The AccountController class:
public class AccountController {
public ActionResult LogOn() { return PartialView(new LogOnModel()); }
public ActionResult Register() { return PartialView(new RegisterModel()); }
}
Both models (LogOnModel, RegisterModel) stated here are the template's default.
And my _Layout.cshtml shared view:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title</title>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/south-street/jquery-ui.css" rel="stylesheet" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js" type="text/javascript"></script>
<script>
$(window).load(function () {
$("#tabs").tabs({ select: function (event, ui) { selectTab(getSelectedTab()); } });
logIn();
});
function logIn() {
selectTab(-1);
selectTab(0);
}
function selectTab(index) {
var url = '#Url.Content("~/Home/SelectTab/")' + index;
var targetDiv = "#tab" + index;
$.get(url, null, function(result) { $(targetDiv).html(result); });
}
function getSelectedTab() { return $("#tabs").tabs("option", "selected"); }
function setSelectedTab(index) { $("#tabs").tabs("option", "selected", index); }
</script>
</head>
<body>
<div id="tabs">
<ul id="menu">
<li><span>Authenticate</span></li>
#if (Request.IsAuthenticated) {
<li><span>About</span></li>
}
</ul>
<div id="tab0"></div><div id="tab1"></div>
</div>
#RenderBody()
</body>
Development environment
I'm using:
VS2010 and .NET 4.0;
jQuery UI (see _Layout.csthml code sample for version and style template);
ASP.NET MVC3.
Question(s)
*How to render the Register partial view once one clicks the 'Register' link contained in the 'LogOn' partial view into the same tab?
Perhaps hiding the actual tab and showing another for registration would appear to be simpler? And yet, how to achieve this?*
I suggest that every other tab (except login) to be loaded via ajax. You submit the login from via ajax and on succesful response you destroy the login tab then add dynamically a new one with href set to an ajax action.
You can accomplish what you want to do, but it will require lots of jquery and ajax (I recommend to give knockoutjs a try).The server-side part is the easiest one.
I think it's also better to call the actions directly without the SelectTab switch.

MVC3 CustomError 500 Issue When Entering HTML Tags In TextFields

I implemented a default custom error page into my MVC3 web application and it seems to be working for the most part. I can enter a bad URL and my browser is redirected to a default error page without any issues. However, I am having a problem when I add an HTML tag into a text field such as <br>. This is causing a 500 error (Internal Server Error) that is not being redirected to my default error page.
In my web.config I have the following tag.
<customErrors defaultRedirect="/CustomErrors/DefaultError" mode="On">
</customErrors>
I have a controller called CustomErrors with a view called DefaultError.cshtml.
public class CustomErrorsController : Controller
{
public ActionResult DefaultError()
{
return View();
}
}
When I enter bad URL a breakpoint I enter in the CustomErrorsController's DefaultError action method. But when I enter <br> into a text field such as the log in page I am seeing flaky behavior. IE or Mozilla shows a default browser error page. The odd thing is that when I remove the customerror property from my web.config I get an ugly page with the exception being dump on it. So my custom error is somehow being referenced but not fully implemented.
Any ideas with dealing with custom errors and entering html tags in text fields?
Thanks Adriano for pointing me in the right direction. I found this example (http://stackoverflow.com/questions/6324368/asp-net-mvc-override-onexception-in-base-controller-keeps-propogating-to-applica) and ended up implementing the OnException in my base controller since the exception would not occur in my CustomErrorsController.
protected override void OnException(ExceptionContext filterContext)
{
filterContext.Result = new ViewResult
{
ViewName = "/CustomErrors/DefaultError"
};
filterContext.ExceptionHandled = true;
}

jQuery Mobile/MVC: Getting the browser URL to change with RedirectToAction

My first post...
When I use RedirectToAction the url in the browser doesn't change. How can I achieve this?
I'm switching over to ASP.NET MVC 3.0 (also using jQuery Mobile) after 10+ years using web forms. I'm about 8 weeks into it, and after several books and scouring Google for an answer, I'm coming up dry.
I have a single route defined in Global.asax:
routes.MapRoute(
"Routes",
"{controller}/{action}/{id}",
new { controller = "Shopping", action = "Index", id = UrlParameter.Optional }
I have a ShoppingController with these actions:
public ActionResult Cart() {...}
public ActionResult Products(string externalId) {...}
[HttpPost]
public ActionResult Products(List<ProductModel> productModels)
{
// do stuff
return RedirectToAction("Cart");
}
The url when I do a get and post (with the post having the RedirectToAction) is always:
/Shopping/Products?ExternalId=GenAdmin
After the post and RedirectToAction I want the url in the browser to change to:
/Shopping/Cart
I've tried Redirect, and RedirectToRoute but get the same results.
Any help would be greatly appreciated.
[Update]
I found that jQuery Mobile AJAX posts are the culprit here. If I turn off jQuery Mobile's AJAX it works.
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script type="text/javascript">
// do not handle links via ajax by default
$(document).bind("mobileinit", function () { $.mobile.ajaxEnabled = false; });
</script>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0rc2/jquery.mobile-1.0rc2.min.css" />
The ordering of the above scripts is important. I had to include the script to jQuery first, then include the script to disable jQuery Mobile's use of AJAX and then include the script to jQuery Mobile.
I'd still like to find a way to use AJAX and have the url update properly. Or at the least be able to call jQuery Mobile's "loading" message (or bake my own).
I think I've found an answer. Buried deep in the jQuery Mobile documentation, there is information about setting the data-url on the div with data-role="page". When I do this, I get the nice jQuery Mobile AJAX stuff (page loading message, page transitions) AND I get the url in the browser updated correctly.
Essentially, this is how I'm doing it...
[HttpPost]
public ActionResult Products(...)
{
// ... add products to cart
TempData["DataUrl"] = "data-url=\"/Cart\"";
return RedirectToAction("Index", "Cart");
}
Then on my layout page I have this....
<div data-role="page" data-theme="c" #TempData["DataUrl"]>
On my HttpPost actions I now set the TempData["DataUrl"] so for those pages it gets set and is populated on the layout page. "Get" actions don't set the TempData["DataUrl"] so it doesn't get populated on the layout page in those situtations.
The only thing that doesn't quite work with this, is when you right-click... view source... in the browser, the html isn't always for the page you are on, which isn't unusual for AJAX.
Not sure if it is still actual, but in my case I wrote following helper method
public static IHtmlString GetPageUrl<TModel>(this HtmlHelper<TModel> htmlHelper, ViewContext viewContext)
{
StringBuilder urlBuilder = new StringBuilder();
urlBuilder.Append("data-url='");
urlBuilder.Append(viewContext.HttpContext.Request.Url.GetComponents(UriComponents.PathAndQuery, UriFormat.UriEscaped));
urlBuilder.Append("'");
return htmlHelper.Raw(urlBuilder.ToString());
}
And then use it as follows:
<div data-role="page" data-theme="d" #Html.GetPageUrl(ViewContext) >
This way I don't need for every redirect action store a TempData. Worked for me fine both for Redirect and RedirectToAction. This would not work properly in case if you use method "View()" inside controller and return different view name, which will change UI, but will retain url.
Hope it helps
Artem
David, this was a big help to me. I just wanted to add that in my case I had to use the following format to get the Url to display in the correct form as my other url's:
TempData["DataUrl"] = "data-url=/appName/controller/action";
return RedirectToAction("action", "controller");
As a side note, I also found that when assigning the value to TempData["DataUrl"] I was able to leave out the escaped quotes and enter it exactly as above and it seems to be working fine for me. Thanks again for your help.
There is an issue on github
https://github.com/jquery/jquery-mobile/issues/1571
It has a nice solution without the need of TempData

Salesforce - Is it possible to display image file from ContentVersion to custom visualforce page?

I wrote one simple Visualforce page that let user upload an image file then
save the file to ContentVersion object.
Now I want to display the saved image in my custom visualforce page. Is it even possible?
Looks like <apex:image> cannot be used. Also <img href="{!cv.contentVersion}"...> had no luck.
The real problem is I did upload the image file successfully but what is the URL to it?
I tested with random URL outside on google and I can display the image (like /../..some.jpg"). But I can't figure out what is the absolute URL for the image file that has been uploaded to contentversion.
NOTE: This is not static resource as my users may upload image to change their user image often.
Code
public with sharing class ImageUploadTestController {
public blob file { get; set; }
public String imageFilePath { get; set; }
public ContentVersion cv { get; set; }
public ImageUploadTestController() {
cv = [select id, versionData, title, pathOnClient FROM ContentVersion limit 1];
}
//fill out the inputFile field and press go. This will upload file to the server
public PageReference go() {
ContentVersion v = new ContentVersion();
v.versionData = file;
v.title = 'some title';
v.pathOnClient ='/foo.jpeg';
insert v;
return new PageReference('/' + v.id);
}
//v.id sample
//069A00000009Ux3
}//end class
Visualforce page
<apex:page controller="ImageUploadTestController">
<apex:form >
<apex:inputFile value="{!file}" />
<apex:commandbutton action="{!go}" value="go"/>
</apex:form>
<!-- none of below works!! :( -->
{!cv.title} {!cv.pathOnClient}
<apex:image value="/069A00000009Ux3" width="220" height="55"/>
</apex:page>
I don't believe its possible to serve it from content currently The format provided by ScottW works for Documents.
The other option I've done is upload a zip file containing my images to the Static Resources which can then be referenced.
This should work:
public PageReference getContent(){
String html = ApexPages.currentPage().getParameters().get('html');
PageReference redirection = null;
redirection = new PageReference('/sfc/servlet.shepherd/version/download/' + contentVersion.Id);
redirection.setRedirect(true);
return redirection;
}
Based on my experience, "thegogz"is correct - it is not currently possible to render images directly from Content. As others have indicated, rendering from Documents and/or Static Resources does work, and IMHO using Documents is preferable because you can access the URL, binary data, etc. programmatically in Apex.
The image is shown using "/servlet/servlet.FileDownload?file=" in tag by using URL attribute.
Example : <apex:image URL="/servlet/servlet.FileDownload?file={!recordId}"/>
for more information,
visit Displaying Images in a Visual Force Page
Try <apex:image URL="/servlet/servlet.FileDownload?file={!recordId}"/>

Resources