Silverstripe allowed_action translation in url address - internationalization

I want to know how to make allowed_actions match i18n language of the site. All modules that I saw not offer that option.
Case of usage : I make a Form page submission module and I would like to translate the submited page url 'finished' (English, EN) with another language like mine 'termine' (French, FR).
Url://exemple/contactpage/finished
To
Url://exemple/contactpage/termine
Thanks for suggestions!

class SimpleContactPage_Controller extends Page_Controller {
private static $allowed_actions = array(
'finished'
);
public function finished() {
...
}
public function init() {
parent::init();
$translatedAction = _t('SimpleContactPage.CONTROLLER', 'finished');
$urlHandlers = $this->config()->url_handlers;
$translatedUrlHandlers = array(
$translatedAction => 'finished',
);
Config::inst()->update(
$this->class,
'url_handlers',
$translatedUrlHandlers + $urlHandlers
);
}
}
Thanks to that link that I found ->
Author : Janne Klouman

Related

how to add tag on webapi for swagger ui

i am learning asp.net webapi. now i add swagger to my asp.net project.
I noticed that there is a tag filter. but how to add tag to my API action?
When you Generate new Controller for Example EmployeeController
and Your routes like this (Example):
Get => /api/Employee/
post => /api/Employee/
put => /api/Employee/{id}
Delete => /api/Employee/{id}
your Tag is Employee
You can see in this Link
or you can Add Your Custom Document Filter as below:
public class OrderTagsDocumentFilter: IDocumentFilter {
public void Apply(OpenApiDocument swaggerDoc,
DocumentFilterContext context) {
swaggerDoc.Tags = swaggerDoc.Tags.OrderBy(x =>
x.Name).ToList();
}
}
And add it to your StartUp Class Like Below:
services.AddSwaggerGen(c => {
c.SwaggerDoc("v1", new OpenApiInfo {
Title = "Shoppy.WebApi", Version = "v1"
});
c.EnableAnnotations();
c.DocumentFilter<OrderTagsDocumentFilter>();
});
Using an OpenApiTag attribute on a controller or an action method does the trick.
[HttpGet(Name = "GetWeatherForecast")]
[OpenApiTag("Temparature")]
public IEnumerable<WeatherForecast> Get()
{
....
}

.Include() Not Pulling Additional Resource

I have a JS file making an AJAX request to a controller. The code below works without the .Include() method but when I add it, the app runs but it doesn't populate my code. I tried running in debug mode but I'm not getting clear answers.
JS file
$(function () {
$.ajax({
type: "GET",
url: "https://localhost:5001/api/SortData/All",
contentType: "application/json; charset=utf-8",
dataType: "json"
}).done(response => {
// For each element in the response, add the submission card
$(response).each(index => {
// Formatting the submission date to be legible
var date = getFormattedDate(response[index].submitDate);
// Adding each submission card to the dashboard
$(".proposals").append(` ...some html...`)}});
API
[Route("api/[controller]/[action]")]
public class SortDataController : ControllerBase
{
[HttpGet, ActionName("All")]
public IQueryable<Proposals> GetAllProposals()
{
return _context.Proposals.Include(p => p.DeveloperName.Name);
}
}
Proposals Model
public class Proposals
{
public Proposals()
{
// Adding values to fields automatically. These fields are not on the form for users to see and update.
SubmitDate = DateTime.Now;
StatusId = 14;
AssignedTo = "johnDoe";
}
// other properties
[NotMapped]
public Users DeveloperName { get; set; }
// a few more properties
}
Users Model
public partial class Users
{
// other properties
public string Name { get; set; }
//some more properties
public IList<Proposals> Proposals { get; set; }
}
The Include is for the Navigation property only, so instead of using Include(p => p.DeveloperName.Name) try to use Include(p => p.DeveloperName) which will also contains Name when you retrieve data.
return _context.Proposals.Include(p => p.DeveloperName);
If you only would like a few specific fields,you need to select them explicitly. Something like this would work:
_context.Proposals.Include(p => p.DeveloperName)
.Select(p => new Proposals
{
StatusId = p.StatusId ,
// etc... The fields you need from Proposals go here
DeveloperName = new Users
{
Name = p.Category.Name
}
}
OK, I figured out Blue's Clues.
Turns out, I had to add
.AddJsonOptions(options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
to the end of services.AddMvc() in my StartUp. Apparently, there was some looping issue that this code prevents.
I also updated my API Controller to...
[Route("api/SortData")]
public class SortDataController : Controller
{
[HttpGet("All")]
public IActionResult GetAllProposals()
{
return Ok(_context.Proposals.Include(p => p.DeveloperName).Include(p => p.Status).ToList());
}
}
From there, I was able to see the JSON response in the XHR and add it accordingly to my JS file.

How to share ShowViewModel class in ViewModel

I am developing a Xamarin mobile app using MVVM Cross. There are two ViewModels which are doing same thing i.e. showing a dialog using the code below:
var register = await UserDialogHelper.RaiseNotRegisteredAsync (UserDialogs);
if (register) {
ShowViewModel<WebViewModel> (new
{
url = Urls.RegisterPage,
title = "Register",
});
}
I tried moving this code to static class but unable to resolve ShowViewModel. Can anyone suggest how to resolve ShowViewModel in non-viewmodel class?
When you have methods or properties to share between the same viewmoels. You can just implement a base viewmodel. And the other ones just inherit from this base viewmodel. Like following example:
public abstract class MyBaseViewModel : MvxViewModel
{
public void MyMethod()
{
// Your code
var register = await UserDialogHelper.RaiseNotRegisteredAsync (UserDialogs);
if (register) {
ShowViewModel<WebViewModel> (new
{
url = Urls.RegisterPage,
title = "Register",
});
}
}
}
And then your viewmodels look like this:
public class MyFirstViewModel : MyBaseViewModel
{
}
Inside this MyFirstViewModel you can call the base method MyMethod. And so on...
Edit
If you want to navigate from outside a view/viewmodel: Look at this answer from Stuart or the answer here from #SergioZgz
ShowViewModel comes from MvxNavigatingObject if your class doesn't inherited it you cannot use it.
You could something like this in a class than is not a MvxViewModel:
var viewDispatcher = Mvx.Resolve<IMvxViewDispatcher>();
viewDispatcher.ShowViewModel(new MvxViewModelRequest(
vmtype,
parameterBundle,
presentationBundle,
requestedBy));
But I think that answer from Joehl is the correcty way :)

form gets posted while calling save for backbone.js restful url put method

Well I have a backbone.js model here
define ['jquery','underscore','backbone'] , ($,_,Backbone) ->
class Student extends Backbone.Model
idAttribute : "UserKey"
urlRoot : "Api/Student"
defaults:
UserKey: null
FirstName : ""
LastName : ""
Username : ""
Password : ""
Age : 18
initialize : ->
#console.log "You have been initialized"
And Lets see I have a controller here : -
public class HomeController : Controller
{
private Repository<Student, PortalContext> repo;
public HomeController()
{
repo = new Repository<Student, PortalContext>(new PortalContext());
}
[HttpGet]
public ActionResult All()
{
IList<Student> studs = repo.GetAll().ToList<Student>();
return this.Json(new { Students=studs }, JsonRequestBehavior.AllowGet);
}
[HttpGet]
public JsonResult Get(int id)
{
Student student = repo.FindBy(x => x.UserKey ==id).Select(x=>x).SingleOrDefault<Student>();
return this.Json(student,JsonRequestBehavior.AllowGet);
}
[HttpPut, ActionName("Student")]
public ActionResult Update(Student student)
{
repo.Edit(student);
repo.Save();
return Json(student);
}
}
And here is my View.Coffee file where I am saving the Model :
define ['jquery'
,'underscore'
,'backbone'
,'text!/Templates/Student/View.htm'] , ($ , _ , Backbone , ViewTemplate) ->
class StdView extends Backbone.View
_.templateSettings = { interpolate: /\{\{(.+?)\}\}/g };
template : _.template(ViewTemplate)
events : ->
"click #back":"Back"
"click #save" : "Save"
Save : ->
console.log "tryng to save"
#model.save
'FirstName' : #$el.find("#txtFirstName").val()
'LastName' : #$el.find("#txtLastName").val()
'Age': #$el.find("#txtAge").val()
,
wait:true
success: =>
alert "Saved"
#
Back: (e)->
window.history.back()
false
initialize : (options) ->
#render()
render :->
#console.log "this is details"
#setElement #template #model.toJSON()
#
It sometime saves the model but sometimes it posts back to the server i.e the backbone doesnt save the data rather it attaches the data into browser url like this
http://abc.com/?firstname=Joy&lastname=Roy&age=19#browse/1
and posts back . But sometimes it saves the data and shows the alert . I am not sure why this is happening Can someone put some light why it is happening like that? ?
After our discussion, Nettuts just provided a great 20 min video tutorial on what I believe will help you better than I can. Take a look and let me know if you have any more questions. He is using Laravel for his server, but from what I can gather, your problem is not with your sever but rather with your client application. Here is the video.

trying to create a dynamic link in MVC 3

I'm working on my company's intranet site, On one of the pages I need to include links to .PDF files if they exist. No problem, I got that to work well enough. The problem I'm having is changing the link if the .PDF doesn't exist. Here's what I currently have:
, grid.Column(format: (item) => (File.Exists(item.FileName)==true ? #Art Work : Html.Raw("")))
I'm receiving the errors:
Argument 3: cannot convert from 'lambda expression' to 'System.Func'
AND
The best overloaded method match for 'System.Web.Helpers.WebGrid.Column(string, string, System.Func, string, bool)' has some invalid arguments
I've done some due diligence with Google and can't find anything. Can someone tell me where I'm going wrong?
I would definitely write a custom helper that will be responsible to generate the proper link:
public static class HtmlExtensions
{
public static IHtmlString LinkToFile(
this HtmlHelper htmlHelper,
string filename
)
{
var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
var file = htmlHelper.ViewContext.HttpContext.Server.MapPath(filename);
if (!File.Exists(file))
{
return MvcHtmlString.Empty;
}
var anchor = new TagBuilder("a");
anchor.Attributes["href"] = urlHelper.Content(filename);
anchor.SetInnerText("Art Work");
return new HtmlString(anchor.ToString());
}
}
and then inside the view simply use this helper:
grid.Column(format: #<text>#Html.LinkToFile((string)item.FileName)</text>)
Try something like this:
format: (item) =>
{
if (File.Exists(item.FileName))
{
return new HtmlString(string.Format("Art Work", #Url.Content(item.FileName)));
}
return string.Empty;
}

Resources