Skip to content

Commit

Permalink
Changes
Browse files Browse the repository at this point in the history
- Add semantic.validation.min.js for consistency
- Add tests for Semantic UI overrides per jjwilliams42/generator-aspnet-semanticui#9 and jjwilliams42/generator-aspnet-semanticui#6
- Add <% namespace %> to _Layout.cshtml (missing)
- Remove title from MenuLinkTagHelper rendering per jjwilliams42/generator-aspnet-semanticui#5
- Remove commented out code and extra call to $('.class').checkbox() in Login.cshtml
- Remove commented out code in various cshtml files
- Merged in functionality to use Semantic OR Bootstrap libraries using yo menu selection or command line argument
  • Loading branch information
Josh Williams committed Mar 5, 2016
1 parent e2fde21 commit 5bb4742
Show file tree
Hide file tree
Showing 53 changed files with 1,963 additions and 14 deletions.
39 changes: 36 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# generator-aspnet

[![Join the chat at https://gitter.im/jackjwilliams/generator-aspnet-semanticui](https://badges.gitter.im/jackjwilliams/generator-aspnet-semanticui.svg)](https://gitter.im/jackjwilliams/generator-aspnet-semanticui?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

[![Build Status](https://travis-ci.org/OmniSharp/generator-aspnet.svg?branch=master)](https://travis-ci.org/OmniSharp/generator-aspnet)
![Version](https://img.shields.io/npm/v/generator-aspnet.svg)
![Downloads per month](https://img.shields.io/npm/dm/generator-aspnet.svg)

Yeoman generator for ASP.NET 5 projects
Yeoman generator for ASP.NET 5 projects with Semantic UI

[![](https://cloud.githubusercontent.com/assets/14539/10418056/b72ae284-7050-11e5-99db-5a0cda8f0ac1.gif)](https://github.com/OmniSharp/generator-aspnet 'ASP.NET 5 Generator')

Expand Down Expand Up @@ -50,7 +52,7 @@ The [Docker](https://www.docker.com/) support with `Dockerfile` configuration fi

The project type and application name can be specified as optional command line arguments:

yo aspnet [projecttype [applicationname]]
yo aspnet [projecttype [applicationname] [uiframework]]

The valid project types are:

Expand All @@ -63,7 +65,38 @@ The valid project types are:
- `classlib` for Class Library
- `unittest` Unit Test project

> Example: `yo aspnet webbasic "my test app"` will create a "Web Application Basic" project called "my test app"
The valid UI framework types are:

- `bootstrap` for Bootstrap (this is the default and does not have to be specified explicitly)
- `semantic` for Semantic UI

> Example: `yo aspnet webbasic "my semantic app" semantic` will create a "Web Application Basic" project called "my semantic app" using the Semantic UI framework.
> Example: `yo aspnet webbasic "my bootstrap app"` OR `yo aspnet webbasic "my bootstrap app" bootstrap` will create a "Web Application Basic" project called "my bootstrap app" using the Bootstrap framework.
## Additional UI Framework Notes

## Semantic UI

### CSS / JS
This generator uses the Semantic UI bower package. By default it includes the entire Semantic UI .css or .min.css
depending on the environment. You can read the Semantic UI documentation [here](http://semantic-ui.com/introduction/build-tools.html) to learn how to use just the components you need.

### Validation
In order for Semantic UI validation to play nicely with the jQuery unobtrusive validation, a helper has been added to
hook into the validation calls and update the fields. This module simply highlights the field, and displays a
validation summary.

For a form to be validated, add the `validate-me` class. To display the error messages use:

`<div asp-validation-summary="ValidationSummary.All" class="ui error message"></div>`

semantic.validation.js is where the magic happens. Upon error (highlight), find the nearest field element and add the error class.
When the error is cleared (unhighlight), remove the error class from the nearest field element.

### MenuLinkTagHelper
To assist with menu highlighting depending on the route, a MenuLinkTagHelper class has been included.


## Related yeoman generators

Expand Down
42 changes: 39 additions & 3 deletions app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ var AspnetGenerator = yeoman.generators.Base.extend({
defaults: false,
desc: 'Use the Grunt JavaScript task runner instead of Gulp in web projects.'
});

this.argument('type', { type: String, required: false, desc: 'the project type to create' });
this.argument('applicationName', { type: String, required: false, desc: 'the name of the application' });
this.argument('ui', {type: String, required: false, defaults: 'bootstrap', desc: 'the ui library to use (bootstrap OR semantic)'});
},


Expand Down Expand Up @@ -78,11 +79,32 @@ var AspnetGenerator = yeoman.generators.Base.extend({
value: 'unittest'
}
]
}];
},
{
type: 'list',
name: 'ui',
message: 'Which UI framework would you like to use?',
default: 'bootstrap',
choices: [
{
name: 'Bootstrap (3.3.5)',
value: 'bootstrap'
},
{
name: 'Semantic UI (2.1.8)',
value: 'semantic'
}
],
when: function (answers){
return answers.type === 'web' || answers.type === 'webbasic';
}

}
];

this.prompt(prompts, function (props) {
this.type = props.type;

this.ui = props.ui;
done();
}.bind(this));
}
Expand All @@ -94,6 +116,7 @@ var AspnetGenerator = yeoman.generators.Base.extend({
this.templatedata.guid = guid.v4();
this.templatedata.grunt = this.options.grunt || false;
this.templatedata.coreclr = this.options.coreclr || false;
this.templatedata.ui = this.ui;
},

askForName: function() {
Expand Down Expand Up @@ -210,9 +233,16 @@ var AspnetGenerator = yeoman.generators.Base.extend({
this.fs.copyTpl(this.templatePath('ViewModels/**/*'), this.applicationName + '/ViewModels', this.templatedata);
// Views
this.fs.copyTpl(this.templatePath('Views/**/*'), this.applicationName + '/Views', this.templatedata);

// wwwroot
// wwwroot - the content in the wwwroot does not include any direct references or imports
// So again it is copied 1-to-1 - but tests cover list of all files
this.fs.copy(this.templatePath('wwwroot/**/*'), this.applicationName + '/wwwroot');

// UI Component Overrides
// If the developer has placed anything in overrides/ui-module/project-type/**/* then use it
this.fs.copyTpl(this.templatePath('/../../overrides/' + this.ui + '/' + this.type + '/**/*'), this.applicationName + '/', this.templatedata);

break;
case 'webbasic':
this.sourceRoot(path.join(__dirname, '../templates/projects/' + this.type));
Expand All @@ -236,9 +266,15 @@ var AspnetGenerator = yeoman.generators.Base.extend({
this.fs.copyTpl(this.templatePath('Controllers/HomeController.cs'), this.applicationName + '/Controllers/HomeController.cs', this.templatedata);
// Views
this.fs.copyTpl(this.templatePath('Views/**/*'), this.applicationName + '/Views', this.templatedata);

// wwwroot - the content in the wwwroot does not include any direct references or imports
// So again it is copied 1-to-1 - but tests cover list of all files
this.fs.copy(this.templatePath('wwwroot/**/*'), this.applicationName + '/wwwroot');

// UI Component Overrides
// If the developer has placed anything in overrides/ui-module/project-type/**/* then use it
this.fs.copyTpl(this.templatePath('/../../overrides/' + this.ui + '/' + this.type + '/**/*'), this.applicationName + '/', this.templatedata);

break;
case 'nancy':
this.sourceRoot(path.join(__dirname, '../templates/projects/' + this.type));
Expand Down
63 changes: 63 additions & 0 deletions templates/overrides/semantic/web/TagHelpers/MenuLinkTagHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Html.Abstractions;
using Microsoft.AspNet.Mvc.TagHelpers;
using Microsoft.AspNet.Mvc.ViewFeatures;
using Microsoft.AspNet.Razor.TagHelpers;
using Microsoft.Extensions.WebEncoders;

namespace <%= namespace %>.TagHelpers
{
[HtmlTargetElement("menulink", Attributes = "controller-name, action-name, menu-text")]
public class MenuLinkTagHelper : TagHelper
{
public string ControllerName { get; set; }
public string ActionName { get; set; }
public string MenuText { get; set; }

[ViewContext]
public ViewContext ViewContext { get; set; }

public IUrlHelper _UrlHelper { get; set; }

public MenuLinkTagHelper(IUrlHelper urlHelper)
{
_UrlHelper = urlHelper;
}

public override void Process(TagHelperContext context, TagHelperOutput output)
{
string menuUrl = _UrlHelper.Action(ActionName, ControllerName);

output.TagName = "";

var a = new TagBuilder("a");

a.MergeAttribute("href", $"{menuUrl}");
a.MergeAttribute("class", "item");

a.InnerHtml.Append(MenuText);

var routeData = ViewContext.RouteData.Values;
var currentController = routeData["controller"];
var currentAction = routeData["action"];

if (String.Equals(ActionName, currentAction as string, StringComparison.OrdinalIgnoreCase)
&& String.Equals(ControllerName, currentController as string, StringComparison.OrdinalIgnoreCase))
{
a.AddCssClass("active");
a.AddCssClass("blue");
}

output.Content.SetContent(a);

}
}
}
10 changes: 10 additions & 0 deletions templates/overrides/semantic/web/Views/Account/ConfirmEmail.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@{
ViewData["Title"] = "Confirm Email";
}

<h2 class="ui header">@ViewData["Title"]</h2>
<div>
<p>
Thank you for confirming your email. Please <a asp-controller="Account" asp-action="Login">Click here to Log in</a>.
</p>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
@model ExternalLoginConfirmationViewModel
@{
ViewData["Title"] = "Register";
}

<h2 class="ui header">@ViewData["Title"]</h2>
<h3 class="ui sub header">Associate your @ViewData["LoginProvider"] account</h3>

<form asp-controller="Account" asp-action="ExternalLoginConfirmation" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="ui small form validate-me" role="form">


<p class="content">
You've successfully authenticated with <strong>@ViewData["LoginProvider"]</strong>.
Please enter a user name for this site below and click the Register button to finish
logging in.
</p>
<div class="six wide field">
<div class="ui left icon input">
<i class="user icon"></i>
<input asp-for="Email" placeholder="Email address"/>
<div asp-validation-for="LoginModel.Email"></div>
</div>
</div>
<br/>
<input type="submit" class="ui large blue submit button" value="Register" />
<br />

<div asp-validation-summary="ValidationSummary.All" class="ui error message"></div>

</form>

@section Scripts {
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@{
ViewData["Title"] = "Login Failure";
}

<h2 class="ui header">@ViewData["Title"]</h2>
<h3 class="ui sub header">Unsuccessful login with service.</h3>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@model ForgotPasswordViewModel
@{
ViewData["Title"] = "Forgot your password?";
}

<h2 class="ui header">@ViewData["Title"]</h2>
<p>
For more information on how to enable reset password please see this <a href="http://go.microsoft.com/fwlink/?LinkID=532713">article</a>.
</p>

@section Scripts {
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@{
ViewData["Title"] = "Forgot Password Confirmation";
}

<h2 class="ui header">@ViewData["Title"]</h2>
<p>
Please check your email to reset your password.
</p>
5 changes: 5 additions & 0 deletions templates/overrides/semantic/web/Views/Account/Info.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@{
ViewBag.Title = "Info";
}
<h2>@ViewBag.Title.</h2>
<h3>@ViewBag.Message</h3>
6 changes: 6 additions & 0 deletions templates/overrides/semantic/web/Views/Account/Lockout.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@{
ViewData["Title"] = "Locked out";
}

<h1 class="ui header red">Locked out</h1>
<h2 class="ui sub header red">This account has been locked out, please try again later.</h2>
82 changes: 82 additions & 0 deletions templates/overrides/semantic/web/Views/Account/Login.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
@using System.Collections.Generic
@using Microsoft.AspNet.Http
@using Microsoft.AspNet.Http.Authentication
@model LoginViewModel
@inject SignInManager<ApplicationUser> SignInManager

@{
ViewData["Title"] = "Log in";
}

<div class="ui two column middle aligned very relaxed stackable grid" style="position:relative">
<div class="column">
<div class="ui form">
<h3 class="ui header centered">Local Account Log In</h3>

<form asp-controller="Account" asp-action="Login" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="ui large form validate-me" role="form" id="loginForm">
<div class="field">
<div class="ui left icon input">
<i class="user icon"></i>
<input asp-for="Email" placeholder="Email address"/>
<div asp-validation-for="LoginModel.Email"></div>
</div>
</div>
<div class="field">
<div class="ui left icon input">
<i class="lock icon"></i>
<input asp-for="Password" placeholder="Password"/>
</div>
</div>
<div class="field">
<div class="ui checkbox">
<input asp-for="RememberMe" type="checkbox" tabindex="0" class="hidden"/>
<label>Remember Me</label>
</div>
</div>
<input type="submit" class="ui large blue submit button" value="Login"/>
<br/>
<br/>
Forgot your password? Click <a asp-action="ForgotPassword" asp-controller="Account">here</a>.
<div asp-validation-summary="ValidationSummary.All" class="ui error message"></div>

</form>
</div>

</div>
<div class="ui vertical divider">
OR
</div>
<div class="center aligned column">
<h3 class="ui header centered">Use Another Service to Log In</h3>
@{
var loginProviders = SignInManager.GetExternalAuthenticationSchemes().ToList();
if (loginProviders.Count == 0)
{
<div>
<p>
There are no external authentication services configured. See <a href="http://go.microsoft.com/fwlink/?LinkID=532715">this article</a>
for details on setting up this ASP.NET application to support logging in via external services.
</p>
</div>
}
else
{
<form asp-controller="Account" asp-action="ExternalLogin" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal" role="form">
<div>
<p>
@foreach (var provider in loginProviders)
{

<button type="submit" class="ui @provider.AuthenticationScheme.ToLower() button" name="provider" value="@provider.AuthenticationScheme" title="Log in using your @provider.DisplayName account"><i class="@provider.AuthenticationScheme.ToLower() icon"></i> @provider.AuthenticationScheme</button>
}
</p>
</div>
</form>
}
}
</div>
</div>

@section Scripts {
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}
Loading

0 comments on commit 5bb4742

Please sign in to comment.