How do I add a script bundle conditionally? - bundle

I have a javascript bundle that I only want to include when testing, not when the code is deployed to production.
I have added a Property called IsEnabledTestingFeatures. In the BundleConfig.cs file I access it like so:
if(Properties.Settings.Default.IsEnabledTestingFeatures) {
bundles.Add(new ScriptBundle("~/bundles/testing").Include("~/Scripts/set-date.js"));
}
This works correctly.
Now, I only want to include the bundle in my page if this property is set to true.
I have tried the following, but the compiler is complaining that it cannot find the Default namespace:
#{
if( [PROJECT NAMESPACE].Properties.Default.IsEnabledTestingFeatures)
{
#Scripts.Render("~/bundles/testing")
}
}
I tried finding how to access the Scripts.Render functionality from the Controller itself, but have been unsuccessful.
I prefer to add the bundle in the view itself, but will settle for adding it via the Controller.

The ViewBag should not be necessary...
Using appSettings from web.config you don't need to recompile for testing and it deploys easily.
<appSettings>
<add key="TestingEnabled" value="true" />
</appSettings>
View or Layout
#{
bool testing = Convert.ToBoolean(
System.Configuration.ConfigurationManager.AppSettings["TestingEnabled"]);
}
#if (testing) {
#Scripts.Render("~/bundles/testing")
}
And I would define "~/bundles/testing" in BundleConfig regardless of the testing condition unless you wish to bundle this with other scripts.
If you assigned Properties.Default.IsEnabledTestingFeatures from AppSettings then the root of your problem is how you implemented your Properties.

Until, hopefully, an alternative [read: better] solution is proposed, I have implemented it using ViewBag.
BundleConfig.cs
//if testing features are enabled (eg: "Set Date"), include the necessary scripts
if(Properties.Settings.Default.IsEnabledTestingFeatures)
{
bundles.Add(new ScriptBundle("~/bundles/testing").Include(
"~/Scripts/set-date.js"));
}
Controller
public ActionResult Index()
{
ViewBag.IsEnabledTestingFeatures = Properties.Settings.Default.IsEnabledTestingFeatures;
return View();
}
View
#if (ViewBag.IsEnabledTestingFeatures != null && ViewBag.IsEnabledTestingFeatures)
{
#Scripts.Render("~/bundles/site")
}
Some Notes:
I did not implement this via a property in the ViewModel due to this
property/feature being independent of the data being displayed. It
seemed incorrect to associate this condition with individual data
models as it is a site-wide feature.
I used application-level settings because it will be easier to configure this property on a per-environment basis due to the fact we utilize web transforms. Thus each environment can set this property as needed.

Related

Spring MVC Portlets: external pagination with displaytag needs to go to the action phase

I'm using Spring MVC portlets I need to implement one display tag with external pagination. In order to do this, I've defined my table in the JSP like this:
<portlet:actionURL var="viewListURL">
<portlet:param name='action' value='${ServletContextKeys.MY_ACTION_METHOD}'/>
</portlet:actionURL>
<display:table name="${whateverList}"
requestURI="${viewListURL}"
class="displayTagTable"
export="true"
uid="item"
pagesize="10"
partialList="true"
sort="external"
defaultsort="1"
size="${ServletContextKeys.SC_LIST_SIZE}">
...
The problem is that, when I click any button to paginate, the displaytag redirects me to the render phase instead the action phase as I want to. What am I doing wrong? Any ideas..?
Thanks a lot
EDIT: I can see in the URL that the parameter p_p_url_type=0 (render phase). it makes no sense to me, as I'm calling an action url, but maybe would be enough just change this parameter to p_p_url_type=1. But, I'm just don't know how... Any ideas?
http://localhost:8080/wsdes/user/sifo3/home?p_p_id=SifoIIIweb_WAR_sifo3economicoweb_INSTANCE_s8jH&p_p_lifecycle=1&p_p_url_type=0&p_p_state=maximized&p_p_mode=view&_SifoIIIweb_WAR_sifo3economicoweb_INSTANCE_s8jH_action=consultaJustificantes&_SifoIIIweb_WAR_sifo3economicoweb_INSTANCE_s8jH_implicitModel=true&_SifoIIIweb_WAR_sifo3economicoweb_INSTANCE_s8jH_d-49489-p=2
Been there before. I solved the problem in a different way, but while looking in DisplayTag source code I found some interesting things. For example, in PortletHref you can find this in the addParameter method:
if (PARAM_TYPE.equals(name))
{
if (TYPE_RENDER.equals(value))
{
this.setAction(false);
}
else if (TYPE_ACTION.equals(value))
{
this.setAction(true);
}
And also:
private static final String PARAM_PREFIX = "portlet:";
public static final String PARAM_TYPE = PARAM_PREFIX + "type";
public static final String TYPE_ACTION = "action";
Apparently, if you need a parameter named portlet:type with value action to make DisplayTag generate an Action URL. I haven't tested myself, so let me know if it works.
I still don't know the reason, but I fixed this issue changing the display tag for Portlets (displaytag-portlet.jar), to the standard displaytag, and deleting from the displaytag.properties file the factory.requestHelper property:
factory.requestHelper=org.displaytag.portlet.PortletRequestHelperFactory
Using the normal displaytag library, instead of the portlet one, fixed my problems.

Proper method to access Play! cache in Scala templates?

I'm running a Play! app using Scala templates. However, I can't find an elegant method to access the Cache in an elegant (or valid) way inside of html templates.
I've tried everything like:
<some html>#play.cache.Cache.get(play.session.getId() + "-account")</some html>
But no luck. Thanks for the proper way to do this!
I found the methodology buried in the old 0.9 Scala documentation. For the time being it's not super-easy but it's 3min do-able. It requires adding a parameter to the controller and template like so:
In your controller, pass session as a parameter
object Application extends Controller {
import views.Application._
def index = {
html.index(session)
}
}
At the top of your template, define the implicit variable:
#(implicit session:play.mvc.Scope.Session)
Inside the template html, access it like so:
#(play.cache.Cache.get(session.getId() + "-account"))

Is it Possible to have more than one messages file in Play framework

We have a site which will be used for two different clients. During first request the user will be asked to choose a client. Based on that text,labels and site content should be displayed.
Is it possible to have two messages file in Play framework and during session startup the messages file would be decided
As of my research we can have more than a file for each Locale, the messages will be get based on locale in the request.
No, it is not supported at the moment.
You can easily do that either in a plugin(Look at MessagesPlugin ) or even using a bootstrap job with the #onApplicationStartup annotation
// From MessagesPlugin.java
//default languange messages
VirtualFile appDM = Play.getVirtualFile("conf/messages");
if(appDM != null && appDM.exists()) {
Messages.defaults.putAll(read(appDM));
}
static Properties read(VirtualFile vf) {
if (vf != null) {
return IO.readUtf8Properties(vf.inputstream());
}
return null;
}
You can wrote you own PlayPlugin and handle implement play.PlayPlugin.getMessage(String, Object, Object...). Then you could choose the right file. The class play.i18n.Messages can be used as inspiration how to implement the method.
Solved this problem with below solution,
Created a class MessagesPlugIn which extends play.i18n.MessagesPlugin
Created a class Messages as like play.i18n.Messages
Had a static Map messaagesByClientID in Messages.java
Overridden onApplicationStart() in MessagesPlugIn
Loaded the Properties in messaagesByClientID as locales loaded in play.i18n.MessagesPlugin
Had a method get() in Messages.java, retrieve the property from messaagesByClientID based ClientId in the session. If the property is not available call get() in play.i18n.Messages
7.Created a Custom tag il8nTag and its used in HTML templates. il8nTag will invoke the methos in Messages.get().
Create your own Module based on play.api.i18n.I18nModule, but bound to your own implementation of MessagesApi, based on Play's DefaultMessagesApi (here is the part defining the files to load)
Then in your application.conf, disable Play's play.api.i18n.I18nModule and enable your own module.

Visual Studio Installer -- Change application resource

Basically, I have my application with a resource for the title of the main window in my Resources.resx file. I bind this to my main windows title
Title={Binding Title, FallbackValue='My Generic Title'}
I have 2 installers (one for each of my clients). This is how I do it right now:
Set the title particular to client A.
Compile the application.
Build the installation file for client A.
Set the title particular to client B.
Compile the application.
Build the installation file for client B.
Is there any way to set the resource to be particular to the installer project I use? Then, afterwards, change the value back to a "default" value?
I think you can do the following:
1) Create two assemblies named Resources.ClientA and Resources.ClientB. They should have exactly the same content (same classes in the same namespaces) but this content should be client-specific for corresponding clients. For example I've added following class just for illustration:
// assembly for ClientA :
namespace Resources
{
public class Class1
{
public static string Text { get { return "Client A text"; } }
}
}
// assembly for ClientB :
namespace Resources
{
public class Class1
{
public static string Text { get { return "Client B text"; } }
}
}
2) Open your main project file (csproj) and add:
<PropertyGroup>
<ClientToken>ClientA</ClientToken>
</PropertyGroup>
3) In the same file below add the reference:
<ItemGroup>
<ProjectReference Include="..\Resources.$(ClientToken)\Resources.$(ClientToken).csproj">
<Name>Resources.$(ClientToken)</Name>
</ProjectReference>
</ItemGroup>
Now by replacing the ClientToken property you can substitute client specific assemblies. You will also be able to specify this property as part of continuous integration process but probably you will need to modify your csproj file a bit so it will take this property from outside and only if it is not set then set some default value.
Also I'm not sure about easier ways to accomplish your task, probably there are some.

Dynamic LINQ context

I'm trying to figure out how to create a dynamic context, and what I mean by that is I have two databases: one for testing, and one for production. Depending on where my website is hosted, I want my context to be pointing at one of the two. So, in my web.config I have:
<add name="Testing_ChannelsEntities" connectionString="removed for brevity" providerName="System.Data.EntityClient" />
<add name="Production_ChannelsEntities" connectionString="removed for brevity" providerName="System.Data.EntityClient" />
Please don't get hung-up on the fact that I removed the connectionString for this example. Just note that I have a testing and a production connection in the web.config.
So, here is my codebehind that I would expect to create a context to the testing connectionString:
using (ChannelsEntities chEntity = new ChannelsEntities("Testing_ChannelsEntities")) {
// removed the business logic because it's not relevant at all
}
Once execution hits the using statement, I get the following error:
Format of the initialization string does not conform to specification starting at index 0.
What am I missing here? This should be easy to do.
I've done similar. Try this -
using (ChannelsEntities chEntity = new ChannelsEntities("name=Testing_ChannelsEntities")) {}
Try:
using (ChannelsEntities chEntity = new ChannelsEntities(WebConfigurationManager.ConnectionStrings["Testing_ChannelsEntities"].ConnectionString)) {
// removed the business logic because it's not relevant at all
}
We put our connection string in a root web.config. You can reference the connection string by name in your virtual diectory and it will inherit the settings from your root web.config.

Resources