How to control where YII flashes are placed? - yii

With YII Flashes you can do this:
Yii::app()->user->setFlash('success', "Data saved!");
However, when the flash appears on the page, it appears like so:
<div id="yw1">
<div class="alert in alert-block fade alert-info"><a class="close" data-dismiss="alert">×</a>
MESSAGE
</div>
</div>
How do I control WHERE this is placed? I don't see anything in layouts/main.php that controls this, yet they display?

They won't display anywhere unless you are calling them, a good example in the Yii default app is the site/contact view:
<?php if(Yii::app()->user->hasFlash('contact')): ?>
<div class="flash-success">
<?php echo Yii::app()->user->getFlash('contact'); ?>
</div>
<?php else: ?>
...
And the flash is set using the setFlash method
Yii::app()->user->setFlash('contact','Thank you for contacting us. We will respond to you as soon as possible.');
A possibility is that there may be a check in the Controller root class (protected/components/Controller.php), where someone may have written an init() function that checks for them. This would be called on every controller/action call so it may be there.
Another possibility is that whoever created the project edited the flash method in the framework folder (or possibly extended it), you could have a look there, it is in framework/web/auth/CWebUser.php
But as Mik said, try doing a text search in your project for getFlash or even just flash

I would do a textsearch on user->getFlashes() in your views folder. You can output the messages at any place with this
<?php
foreach(Yii::app()->user->getFlashes() as $key => $message) {
echo '<div class="flash-' . $key . '">' . $message . "</div>\n";
}
?>

You, the developer, need to display flash-messages. Yii does not do that for you.
You display them in a view, as shown by Eskimo and Mik, at a location of your own choosing . Yii could never do that, because Yii does not know the layout of your view.

Related

Unable to change the echo output

I have used PhalconPHP devtools to create a project skeleton and did some testing in the indexAction(){} from the indexController.
My index controller:
class IndexController extends ControllerBase
{
public function indexAction()
{
echo "OUUUUUTPUUUUUUUUUUUUUUUT";
}
}
and index.volt looks like:
<!DOCTYPE html>
<html>
<head>
<title>Phalcon PHP Framework</title>
</head>
<body>
<?php echo $this->view->getContent(); ?>
{{ content() }}
</body>
</html>
I know this way I am getting double the content. But this is for debugging.
The output I get is:
<h1>Congratulations!</h1>
<p>You are now flying with Phalcon. Great things are about to happen!</p>
<h1>Congratulations!</h1>
<p>You are now flying with Phalcon. Great things are about to happen!</p>
I am using Chrome browser for testing, and Ubuntu server 12.04 for PhalconPHP 1.3.0.
Phalcon view uses output buffering, I'm sure that's the reason why you're not seeing the echo output, since the view has control over that. You can disable the view to print stuff directly from the controller:
public function indexAction()
{
$this->view->disable();
echo "HELLO";
}
To address the actual debugging question, I suggest to stick with Xdebug – it works perfectly fine with Phalcon and supported by most IDEs, like PhpStorm or NetBeans, and has browser extensions (Chrome, Safari, etc.) It takes awhile to get the head around the first time, but the time invested is totally worth it. Highly recommend.
I guess, this is what need:
public function testAction(){
echo 'Hello world';
$this->view->setRenderLevel(View::LEVEL_NO_RENDER); //will stop render view
}
I use it to output JSON directly from controller. :)
$this->view->setContent('OUUUUUTPUUUUUUUUUUUUUUUT');
or
echo 'OUUUUUTPUUUUUUUUUUUUUUUT';die();

yii custom error pages like 404, 403, 500

I'm trying to have separate files for all my error messages. (404, 403, 500 etc) so i can have custom designs for them. If possible i don't want the header and footer to be included in my error pages too. Right now i have this, in my SiteController.php and put error404.php into my views/site/ folder
public function actionError()
{
$error = Yii::app()->errorHandler->error;
switch($error['code'])
{
case 404:
$this->render('error404', array('error' => $error));
break;
.......
.......
}
}
i was wondering if there is a better way? or if Yii has way to handle this that i'm missing.
i read this page http://www.yiiframework.com/doc/guide/1.1/en/topics.error
and it says something about putting files into /protected/views/system but i don't quite understand Yii's documentation.
As you read Yii will look for files in /protected/views/system (after looking in themes if you have any)
You do not need to write any fresh actions all you have to do is create a folder system in the views directory and create files named errorXXX.php XXX being the error code.
The default page looks like this you modify this as you wish and save it in /protected/views/system
<body>
<h1>Error <?php echo $data['code']; ?></h1>
<h2><?php echo nl2br(CHtml::encode($data['message'])); ?></h2>
<p>
The above error occurred when the Web server was processing your request.
</p>
<p>
If you think this is a server error, please contact <?php echo $data['admin']; ?>.
</p>
<p>
Thank you.
</p>
<div class="version">
<?php echo date('Y-m-d H:i:s',$data['time']) .' '. $data['version']; ?>
</div>
</body>
You will have access to following attributes in your $data array
code: the HTTP status code (e.g. 403, 500);
type: the error type (e.g. CHttpException, PHP Error);
message: the error message;
file: the name of the PHP script file where the error occurs;
line: the line number of the code where the error occurs;
trace: the call stack of the error;
source: the context source code where the error occurs.
The alternative technique is how you created an action in SiteController,however to activate this you need to change your main config file and route errors to this action:
return array(
......
'components'=>array(
'errorHandler'=>array(
'errorAction'=>'site/error',
),
),
);
If you wish to only skin your errors then this is not necessary, if you want to do more complex stuff like on error log to a DB, send a email to the admin etc then it is good to have your own action with additional logic.

How can I use cshtml files with Durandal?

I got the DurandalJS StarterKit template on VS2012... All works great...
But in some views I need to do something like that:
#if (Roles.IsUserInRole("Administrators"))
{
<p>Test</p>
}
However with durandal all my views are '.html' files... Is that possible to use '.cshtml' files to access some information like that?
Or is there any other way to do that with durandal?
Junior
I am doing it like this:
Create a generic controller for Durandal views:
public class DurandalViewController : Controller
{
//
// GET: /App/views/{viewName}.html
[HttpGet]
public ActionResult Get(string viewName)
{
return View("~/App/views/" + viewName + ".cshtml");
}
}
Register a route:
routes.MapRoute(
name: "Durandal App Views",
url: "App/views/{viewName}.html",
defaults: new { controller = "DurandalView", action = "Get" }
);
Copy Views/web.config to /App/views/web.config (so Razor views work in this location).
This lets me use the normal Durandal conventions (even the html extension for views), and put durandal views as cshtml files in their normal location without adding any more server code.
If you also have static html views, you can also place the cshtml views in a subfolder or use the normal MVC /Views folder.
I wouldn't recommend using ASP.NET MVC with Durandal.
What you are probably looking to do is use the Razor view engine (to get the benefits of a compiler, strong typing etc.) which exists independently from ASP.NET MVC. Just WebAPI for data I/O is more than enough to very efficiently create a Durandal.js application.
If you are interested in using Razor/CSHTML with Durandal and Knockout there is an open source option out there called FluentKnockoutHelpers that may be exactly what you are looking for. It offers much of the 'nice' parts of ASP.NET MVC allowing you to use the awesome abilities of Durandal and Knockout with almost no downfalls.
Source
Live demo using Durandal.js
In a nutshell it provides a bunch of features which makes doing Durandal/Knockout development just as easy as ASP.NET MVC. (You simply provide a C# type that your JavaScript model is based off of for most of the features.) You only have to write JavaScript and un-compiled markup for complicated cases which is unavoidable and no different than MVC! (Except in MVC your code would also likely end up would also be a big jQuery mess which is why you are using Durandal/Knockout in the first place!)
Features:
Painlessly generate Knockout syntax with strongly typed, fluent, lambda expression helpers similar to ASP.NET MVC
Rich intellisense and compiler support for syntax generation
Fluent syntax makes it a breeze to create custom helpers or extend whats built in
OSS alternative to ASP.NET MVC helpers: feel free to add optional features that everyone in the community can use
Painlessly provides validation based on .NET types and DataAnnotations in a few lines of code for all current/future application types and changes
Client side JavaScript object factory (based on C# types) to create new items in for example, a list, with zero headaches or server traffic
Example without FluentKnockoutHelpers
<div class="control-group">
<label for="FirstName" class="control-label">
First Name
</label>
<div class="controls">
<input type="text" data-bind="value: person.FirstName" id="FirstName" />
</div>
</div>
<div class="control-group">
<label for="LastName" class="control-label">
Last Name
</label>
<div class="controls">
<input type="text" data-bind="value: person.LastName" id="LastName" />
</div>
</div>
<h2>
Hello,
<!-- ko text: person.FirstName --><!-- /ko -->
<!-- ko text: person.LastName --><!-- /ko -->
</h2>
Provide FluentKnockoutHelpers with a .NET type and you can do this in style with Intellisense and a compiler in Razor / CSHTML
#{
var person = this.KnockoutHelperForType<Person>("person", true);
}
<div class="control-group">
#person.LabelFor(x => x.FirstName).Class("control-label")
<div class="controls">
#person.BoundTextBoxFor(x => x.FirstName)
</div>
</div>
<div class="control-group">
#person.LabelFor(x => x.LastName).Class("control-label")
<div class="controls">
#person.BoundTextBoxFor(x => x.LastName)
</div>
</div>
<h2>
Hello,
#person.BoundTextFor(x => x.FirstName)
#person.BoundTextFor(x => x.LastName)
</h2>
Take a look at the Source or Live Demo for an exhaustive overview of FluentKnockoutHelper's features in a non-trivial Durandal.js application.
Yes, you can absolutely use cshtml files with Durandal and take advantage of Razor on the server. I assume that also means you want MVC, so you can do that too and use its routing.
If you don;t want the routing then you can set the webpages.Enabled in the web.config, as the other comments suggest.
<add key="webpages:Enabled" value="true" />
I don't recommend that you use .cshtml files as views directly. You're better off placing the .cshtml files behind a controller.
For example, take the HotTowel sample, edit /App/main.js, and replace the function definition with the following:
define(['durandal/app',
'durandal/viewLocator',
'durandal/system',
'durandal/plugins/router',
'durandal/viewEngine',
'services/logger'],
function (app, viewLocator, system, router, viewEngine, logger) {
Note that we added a reference to the Durandal viewEngine. Then we need to replace
viewLocator.useConvention();
with
viewLocator.useConvention('viewmodels', '../../dynamic');
viewEngine.viewExtension = '/';
The first argument to viewLocation.useConvention sets the /Apps/viewmodels/ directory as the location for the view models js files, but for the view location, uses the URL http://example.com/dynamic/, with an extension of '/'. So that if Durandal is looking for the view named 'shell', it will reference http://example.com/dynamic/shell/ (this is because the view directory is mapped relative to the viewmodels directory, hence /App/viewmodels/../../dynamic will give you simply /dynamic).
By convention, this previous URL (http://example.com/dynamic/shell/) will be mapped to the controller DynamicController, and the action "Shell".
After this, you simply add a controller - DynamicController.cs, like this:
// will render dynamic views for Durandal
public class DynamicController : Controller
{
public ActionResult Shell()
{
return View();
}
public ActionResult Home()
{
return View();
}
public ActionResult Nav()
{
return View();
}
public ActionResult Details()
{
return View();
}
public ActionResult Sessions()
{
return View();
}
public ActionResult Footer()
{
return View();
}
}
Create .cshtml files for each of the above actions. This way you get to use controllers, server side IoC et al to generate dynamic views for your SPA.
DurandaljS is a client framework which forms mainly a solid base for single-page apps (SPA).
I assume you are using asp.net web API as your server technology. In that case, you can determine the user's role inside your API controller and based on that return data to the client. On the client you can use Knockout "if" binding in order to show / hide certain areas of your page.
What you perhaps can do is placing this code in the Index.cshtml.
Following link shows how to customize moduleid to viewid mapping
http://durandaljs.com/documentation/View-Location/
by convention durandal tries to find view url in following steps
1) Checke whether object has getView() function which returns either dom or a string ( url for the view)
2) If object does not have getView function then checks whether object has viewUrl property
3) If above two steps fails to produce url or a DOM view drundal falls to default convention
which maps moduleid xyz.js to view xyz.html using view url ( path of Views folder ) defined in main.js
so for moduleid xyz.js path of the view will be views/xyz.html
you can overwrite this default mapping behavior by overwriting convertModuleIdToViewId function.
So there are many ways you can customize your view url for specific model (.js object)
I made an extension to Durandal which gives you the ability to place an applicationContent div in your cshtml file together with the applicationHost div. In applicationContent you can now use both ASP .Net MVC syntax together with knockout bindings.
Only thing I did was put some extra code in the viewLocator.js file which looks for an applicationContent div:
locateViewForObject: function(obj, area, elementsToSearch) {
var view;
if (obj.getView) {
view = obj.getView();
if (view) {
return this.locateView(view, area, elementsToSearch);
}
}
if (obj.viewUrl) {
return this.locateView(obj.viewUrl, area, elementsToSearch);
}
view = document.getElementById('applicationContent');
if (view) {
return this.locateView(view, area, elementsToSearch);
}
var id = system.getModuleId(obj);
if (id) {
return this.locateView(this.convertModuleIdToViewId(id), area, elementsToSearch);
}
return this.locateView(this.determineFallbackViewId(obj), area, elementsToSearch);
},
Your original cshtml file can now do something like this:
<div class="row underheader" id="applicationContent">
<div class="small-5 columns">
<div class="contentbox">
#using (Html.BeginForm("Generate", "Barcode", FormMethod.Post, Attributes.Create()
.With("data-bind", "submit: generateBarcodes")))
{
<div class="row formrow">
<label for="aantalBijlagen">#Translations.Label_AantalBijlagen</label>
</div>
<div class="row">
<select name="aantalBijlagen" class="small-6 columns">
<option>0</option>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
</select>
</div>
<div class="row">
<button class="button right" type="submit" id="loginbutton"><span class="glyphicon glyphicon-cog"></span> #Translations.Action_Generate</button>
</div>
}
</div>
</div>
<div class="small-7 columns" data-bind="if: hasPdfUrl">
<div class="contentbox lastcontent">
<iframe data-bind="attr: {src: pdf_url}"></iframe>
</div>
</div>
You can find my fork of the durandal project here and a small blogpost of what and how I did this here.
I'm not very familiar with DurandalJS but because it's a client-side system, it should make no difference what technology is used on the server to generate the HTML markup. So if you use Razor CSHTML files to generate the HTML on the server, DurandalJS should work just fine with it.
If you're getting a particular error then please share that error, but I can't think of any reason why it wouldn't work.

Changing text beside upload field in Yii Framework

hopefully a quick question here, have not been able to find out the answer on google. Anyway I have the following File upload field.
<div class="row">
<?php echo CHtml::form('', 'post', array('enctype' => 'multipart/form-data')); ?>
<?php echo $form->labelEx($model, 'doc'); ?>
<?php echo CHtml::activeFileField($model, 'doc'); ?>
<?php echo $form->error($model, 'doc'); ?>
</div>
The question I have is how to change the default text? On the page in question the upload field comes up with "No file chosen" beside the button when the page loads. I wish to change this text, anyone tell me how? Thanks.
I quick & dirty fix is this:
<?php echo CHtml::activeFileField($model, 'type',array('style'=>'width:100px;', 'onchange' => 'this.style.width = "100%";')); ?>

Does a WordPress plugin exist that allows you to protect certain pages via a username/login?

I have 10 pages, 4 of which should be accessible by logged in users.
Is there a plugin that exists to password protect these pages? Ideally, you can login once and then subsequently view all these protected pages.
I have Googled a bit, but haven't been able to find something that lets you protect individual pages, only the entire WordPress platform.
Does something like this exist, and if there are multiple, which is the best in your experience?
Thanks
You could use a Membership Plugin. Most of them cost money. A Google search turned up a free one called MemberWing, but I haven't tried it and can't speak to how good it is.
Generally a membership plugin will handle registration and access control. If you decide that's overkill, you could focus just on content protection with a Custom Page Template. Below, I've attached a generic WordPress Page Template that will hide content from guests. It's based off of WordPress' old default theme. If the user is not logged in, it'll display a message telling them they can't access the content as a guest.
<?php
/*
Template Name: Protected Content
*/
get_header(); ?>
<div id="content" class="narrowcolumn" role="main">
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<div class="post" id="post-<?php the_ID(); ?>">
<h2><?php the_title(); ?></h2>
<div class="entry">
<?php
if(is_user_logged_in()) {
the_content('<p class="serif">Read the rest of this page »</p>');
}
else {
echo "You must be logged in to access this content!";
}
?>
<?php wp_link_pages(array('before' => '<p><strong>Pages:</strong> ', 'after' => '</p>', 'next_or_number' => 'number')); ?>
</div>
</div>
<?php endwhile; endif; ?>
<?php edit_post_link('Edit this entry.', '<p>', '</p>'); ?>
<?php comments_template(); ?>
</div>
<?php get_sidebar(); ?>
<?php get_footer(); ?>
Private posts should do what you want. You shouldn't need a plugin.