Markdown not rendering html elements - asp.net-core

This is my Markdown variable
#{
Layout="_Layout";
var post =await Orchard.GetContentItemByHandleAsync($"alias:{Slug}");
string markdown=post.Content.MarkdownBodyPart.Markdown;
ViewData["Title"] = post;
ViewData["Description"]=post.Content.Blogpost.Subtitle.Text;
ViewData["Image"]=#Orchard.AssetUrl((string)post.Content.Blogpost.Image.Paths[0]);
}
And this is how I used it within my page
#await Orchard.MarkdownToHtmlAsync(markdown)
But with all this in place, html elements are not rendering (i.e , and more)
here is the link to the page that is failing to render, https://thinkwide.tech/post/blockchain

I finally got it working. I had to put the following code on the start up class under services.
services.AddOrchardCms().ConfigureServices(tenantServices =>
tenantServices.PostConfigure<MarkdownPipelineOptions>(o =>
{
o.Configure.Clear();
}));
More info about markdown pipeline is found here: https://docs.orchardcore.net/en/dev/docs/reference/modules/Markdown/

Related

Riotjs - Front-end page Structure

I'm using the riot for the system. but I have a problem using the common tag in every place. because I have to copy the all common tag each page.
I added all tags like this. Does anyone have the solution for this ?
<st-service>
<st-alert></st-alert>
<st-header></st-header>
<st-body></st-body>
<st-footer></st-footer>
</st-service>
<st-profile>
<st-alert></st-alert>
<st-header></st-header>
<st-body></st-body>
<st-footer></st-footer>
</st-profile>
I found a solution, I'm using this method to handle these common tags. like this
<st-common>
<st-alert></st-alert>
<st-header></st-header>
<yeild></yeild>
<st-footer></st-footer>
</st-common>
service-page.tag // page
<st-service-page>
<st-common>
<st-service></st-service>
</st-common>
<st-service-page>
profile-page.tag // page
<st-profile-page>
<st-common>
<st-profile></st-profile>
</st-common>
<st-profile-page>
service-view.tag
<st-service>
// html / code body related to module
</st-service>
profile-view.tag
<st-profile>
// html / code body related to module
</st-profile>
If needed in details about this I can explain.
I'd have to know more about how you're routing to say for sure, but I think you should avoid using a different outer tag for each page. If your HTML looks something like this:
<body>
<st-app />
<script>
const pages = {
"/": "st-home",
"/about/": "st-about",
}
const content_tag = pages[window.location.pathname] || "st-notfound"
riot.mount("st-app", {
content_tag: content_tag
})
</script>
</body>
Then <st-app> would be defined something like:
<st-app>
<st-alert></st-alert>
<st-header></st-header>
<div data-is={this.opts.content_page}></div>
<st-footer></st-footer>
</st-app>
The important thing here being that you're controlling which tag should be used via the data-is attribute and the mounting options for <st-app>. In this example <st-home>, <st-about>, and <st-notfound> are riot components defined elsewhere.

In a view component invoked as a tag helper, how can we access the inner HTML?

In tag helpers, we can access the tags inner HTML.
<!-- Index.cshtml -->
<my-first>
This is the original Inner HTML from the *.cshtml file.
</my-first>
// MyFirstTagHelper.cs > ProcessAsync
var childContent = await output.GetChildContentAsync();
var innerHtml = childContent.GetContent();
If we invoke a view component as a tag helper, how can we access the inner HTML?
<vc:my-first>
This is the original Inner HTML from the *.cshtml file.
</vc:my-first>
// MyFirstViewComponent.cs > InvokeAsync()
var innerHtml = DoMagic();
A few further thoughts:
I appreciate that we can pass arbitrary content to a view component via HTML attributes. That can become impractical, though, in the case of very large amounts of text, in which case inner HTML would be more readable and have better tooling support.
Some might also say, "Why not just use a tag helper, then?" Well, we want to associate a view with the tag helper, and tag helpers do not support views; instead, tag helpers require us to build all the HTML programmatically.
So we're stuck in a bit of bind. On the one hand, we want a tag helper, but they don't support views; on the other hand, we can use a view component as a tag helper, but view components might not let us access the inner HTML.
Sorry, but the answer is "Just use a tag helper"
See the following issue: https://github.com/aspnet/Mvc/issues/5465
Being able to invoke a ViewComponent from a tag helper is just a different way to call it instead of using #Component.Invoke().
I can see where this is misleading, and I do recall seeing in the ASP.NET Core 2.1 tutorials a statement to the effect of "View Components are like Tag Helpers, but more powerful."
Finally, a way to have our cake and eat it too! Allow a tag-helper to use a Razor view as its source of HTML, yet still wrap markup when used in a Razor page.
Use a tag-helper to get the inner HTML as a string. Then directly operate the Razor view engine to render a partial view to a string. Finally, use string replacement to place the inner HTML string into the right place in the partial view string.
The key is to use the high-quality StackOverflow answers available on rendering a Razor view as a string. See the IRazorViewToStringRenderer service here (it says ASP.NET Core 3.1 but worked for me in 2.2), or elsewhere as Mvc.RenderViewToString.
The tag-helper:
// RazorViewTagHelper.cs
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace GetSafetyCone.TagHelpers
{
public class RazorViewTagHelper : TagHelper
{
private IRazorViewToStringRenderer RazorViewToStringRenderer { get; }
public ViewName { get; set; }
public RazorViewedTagHelperBase(
IRazorViewToStringRenderer razorViewToStringRenderer)
{
this.RazorViewToStringRenderer = razorViewToStringRenderer;
}
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
var childContent = await output.GetChildContentAsync();
var childContentString = childContent.GetContent();
var viewHtmlTemplateString = await this.RazorViewToStringRenderer.Render<object>(this.ViewName, null);
var viewHtmlString = viewHtmlTemplateString.Replace("BODY_GOES_HERE", childContentString);
output.Content.SetHtmlContent(viewHtmlString); // Set the content.
}
}
}
The partial view you want to use as the source of HTML for the tag-helper:
// ViewXYZ.cshtml
#*
ViewXYZ to be rendered to string.
*#
// No model specified, so ok model was a null object.
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="max-w-3xl mx-auto">
BODY_GOES_HERE
</div>
</div>
And here's the tag-helper in use:
// YourPage.cshtml
<razor-view view-name="ViewXYZ">
<p>You should see this content wrapped in the ViewXYZ divs.</p>
</razor-view>
If you want, you can simplify the string replacement and use the childContent TagHelperContent directly as the model of the view:
// RazorViewTagHelper.cs
...
var childContent = await output.GetChildContentAsync();
var viewHtmlString = await this.RazorViewToStringRenderer.Render("viewName", childContent);
...
// ViewXYZ.cshtml
...
#model Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContent;
...
<div class="max-w-3xl mx-auto">
#(this.Model)
</div>
...

Can't print to PDF in Slim Framework, Twig, and DomPDF

I have been struggling with this and I can't get it to work, despite that in some other posts they say you can use the Twig's render() function, I get the folowing error:
Requested HTML document contains no data. Dompdf\Exception
My code so far is:
use Dompdf\Dompdf;
$app->post('/my/path/for/printing',function()use($app){
//echo '<p>printing to pdf ... ☺</p>';
$request=$app->request;
/* code for retrieving data from the database ... done.*/
$variables = [
'param1' => $param1,
'param2' => $param2,
];
$dompdf = new Dompdf();
$content = $app->render('path/for/the/view.print.twig', $variables);
$dompdf->loadHtml($content);
$dompdf->render();
$dompdf->stream('sample.pdf');
})->name('my.path.for.printing');
If I render my view, the data is displayed correctly. But with dompdf is not working.
Does anybody know how to fix this?
Otherwise, can you explain with an example of any other package how to print a Twig view in PDF?
render() doesn't return the HTML. Try:
$content = $app-view->fetch('path/for/the/view.print.twig', $variables);

getting full working single page with phantomjs

I'm trying to get this page: http://www.pqllana.com.ar/distribuidores/mapa with phantomjs.
I have special interest in getting the section that contains "ubicacion", "locales", "mapa".
As you can see in the page, it works with javascript, and I want to get those sections fully working, I mean that if I click on them they should work as expected.
What happens is that the google map is not loaded correctly, and some links doesn't work at all. I'm retrieving the page using this code:
var page = require('webpage').create();
page.open('http://www.pqllana.com.ar/distribuidores/mapa', function() {
var content = page.content;
var fs = require('fs');
try {
fs.write("hellohello.ctp", content, 'w');
} catch(e) {
console.log(e);
}
phantom.exit();
});
What I do is I pick that file and render into another page.
Looks like what I'm trying to achieve is not possible with PhantomJS (not suitable for this task), so I'm going to implement an iFrame, deactivate it's scrollbar and use dynamic size.

unobtrusive validation not working with dynamic content

I'm having problems trying to get the unobtrusive jquery validation to work with a partial view that is loaded dynamically through an AJAX call.
I've been spending days trying to get this code to work with no luck.
Here's the View:
#model MvcApplication2.Models.test
#using (Html.BeginForm())
{
#Html.ValidationSummary(true);
<div id="res"></div>
<input id="submit" type="submit" value="submit" />
}
The Partial View:
#model MvcApplication2.Models.test
#Html.TextAreaFor(m => m.MyProperty);
#Html.ValidationMessageFor(m => m.MyProperty);
<script type="text/javascript" >
$.validator.unobtrusive.parse(document);
</script>
The Model:
public class test
{
[Required(ErrorMessage= "required field")]
public int MyProperty { get; set; }
}
The Controller:
public ActionResult GetView()
{
return PartialView("Test");
}
and finally, the javascript:
$(doument).ready(function () {
$.ajax({
url: '/test/getview',
success: function (res) {
$("#res").html(res);
$.validator.unobtrusive.parse($("#res"));
}
});
$("#submit").click(function () {
if ($("form").valid()) {
alert('valid');
return true;
} else {
alert('not valid');
return false;
}
});
The validation does not work. Even if I don't fill any information in the texbox, the submit event shows the alert ('valid').
However, if instead of loading dynamically the view, I use #Html.Partial("test", Model) to render the partial View in the main View (and I don't do the AJAX call), then the validation works just fine.
This is probably because if I load the content dynamically, the controls don't exist in the DOM yet. But I do a call to $.validator.unobtrusive.parse($("#res")); which should be enough to let the validator about the newly loaded controls...
Can anyone help ?
If you try to parse a form that is already parsed it won't update
What you could do when you add dynamic element to the form is either
You could remove the form's validation and re validate it like this:
var form = $(formSelector)
.removeData("validator") /* added by the raw jquery.validate plugin */
.removeData("unobtrusiveValidation"); /* added by the jquery unobtrusive plugin*/
$.validator.unobtrusive.parse(form);
Access the form's unobtrusiveValidation data using the jquery data method:
$(form).data('unobtrusiveValidation')
then access the rules collection and add the new elements attributes (which is somewhat complicated).
You can also check out this article on Applying unobtrusive jquery validation to dynamic content in ASP.Net MVC for a plugin used for adding dynamic elements to a form. This plugin uses the 2nd solution.
As an addition to Nadeem Khedr's answer....
If you've loaded a form in to your DOM dynamically and then call
jQuery.validator.unobtrusive.parse(form);
(with the extra bits mentioned) and are then going to submit that form using ajax remember to call
$(form).valid()
which returns true or false (and runs the actual validation) before you submit your form.
Surprisingly, when I viewed this question, the official ASP.NET docs still did not have any info about the unobtrusive parse() method or how to use it with dynamic content. I took the liberty of creating an issue at the docs repo (referencing #Nadeem's original answer) and submitting a pull request to fix it. This information is now visible in the client side validation section of the model validation topic.
add this to your _Layout.cshtml
$(function () {
//parsing the unobtrusive attributes when we get content via ajax
$(document).ajaxComplete(function () {
$.validator.unobtrusive.parse(document);
});
});
test this:
if ($.validator.unobtrusive != undefined) {
$.validator.unobtrusive.parse("form");
}
I got struck in the same problem and nothing worked except this:
$(document).ready(function () {
rebindvalidators();
});
function rebindvalidators() {
var $form = $("#id-of-form");
$form.unbind();
$form.data("validator", null);
$.validator.unobtrusive.parse($form);
$form.validate($form.data("unobtrusiveValidation").options);
}
and add
// Check if the form is valid
var $form = $(this.form);
if (!$form.valid())
return;
where you are trying to save the form.
I was saving the form through Ajax call.
Hope this will help someone.
just copy this code again in end of modal code
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
;)