How do I use the HexoJS css helper from a nunjucks template? - nunjucks

I get the error:
Unhandled rejection Template render error: (unknown path) [Line 9, Column 6]
unknown block tag: css
at Object.exports.withPrettyErrors (/Users/me/hexo-site/node_modules/hexo-renderer-nunjucks/node_modules/nunjucks/src/lib.js:35:17)
My themes/theme-name/layout/layout.nunjucks file has this code:
<title>Site title</title>
{% css "css/style.css" %}

Nunjucks does not have a css tag, and it doesn't look like hexo-renderer-nunjucks implements one either.
You can implement it yourself, but it looks easier to just use a filter:
env.addFilter('css', function(str) {
return '<link rel="stylesheet" href="' + str + '"></link"'
})
and use {{"css/style.css"|css}} instead.

Related

Unable to use DateTime input through django CreateView and ModelForm

I tried to create an object of Model Event through UI using CreateView
My Model is
class Event(models.Model):
start = models.DateTimeField(_("start"), db_index=True)
end = models.DateTimeField(_("end"), db_index=True, help_text=_("The end time must be later than the start time."))
title = models.CharField(_("title"), max_length=255)
description = models.TextField(_("description"), blank=True)
rule = models.ForeignKey(Rule)
calendar = models.ForeignKey(Calendar)
My ModelForm is
class EventForm(forms.ModelForm):
class Meta:
model=Event
fields=['start','end','title','description','rule','calendar',]
My url is
url(r'^addEvent/$', CreateEventView.as_view(), name='add-event'),
View is
class CreateEventView(CreateView):
form_class=EventForm
template_name="createEventForm.html"
success_url='/eventListView/'
I have tried to automatically render this in the following HTML template
{% extends "base.html" %}
{% load i18n %}
{% block body %}
<form method='POST'>{% csrf_token %}
{{form.as_p}}
<button type="submit">Save</button>
</form>
<h2></h2>
{% if error %}
<p>Error {{error}}</p>
{% endif %}
{% endblock %}
The other components are rendering well, including foreign-key as dropdown. I am facing a problem only with the date-time fields start and end, which are rendering as text-fields.
I tried many solutions, including adding init function to my form after removing the datetime fields
def __init__(self, *args, **kwargs):
super(EventForm, self).__init__(*args, **kwargs)
self.fields['start']=forms.DateTimeField(widget=forms.widgets.DateTimeInput())
But they are still rendering as text-fields.
I used another method suggested online and added
<link href="//cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="//cdn.bootcss.com/bootstrap-datetimepicker/4.17.44/css/bootstrap-datetimepicker.min.css" rel="stylesheet">
<script src="//cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
<script src="//cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="//cdn.bootcss.com/moment.js/2.17.1/moment.min.js"></script>
<script src="//cdn.bootcss.com/bootstrap-datetimepicker/4.17.44/js/bootstrap-datetimepicker.min.js"></script>-->
<script>
$(function () {
$('.datetime-input').datetimepicker({
format:'YYYY-MM-DD HH:mm'
});
});
</script>
To my base template and modified the form object to include widgets
class EventForm(forms.ModelForm):
class Meta:
model=Event
fields=['start','end','title','description','rule','calendar',]
widgets = {
'start': forms.widgets.DateTimeInput(attrs={'class':'datetime-input'}),
}
Even though the 'start' field is recognising the format on the datepicker function from bootstrap-datepicker, it is still rendering it as a text field.
I got the following error on the browser console:
Uncaught Error: datetimepicker component should be placed within a relative positioned container
Please let me know if there is a way to get the datetime-widget to display on the UI. Thank you. Sorry if you found my approach amateurish.

Laravel 5.4 include js and css issue

I have added in my public folder one folder called js and inside a script.js. In the view:
<script type="text/javascript" src="{!! asset('/js/script.js') !!}"></script>
and all is working in local but on the server I receive a get error:
https://url/js/script.js
How is it possible?
you should use {{ }} instead of {!! !!}
<script type="text/javascript" src="{{ asset('js/script.js') }}"></script>
{!! !!} used for Displaying Unescaped Data
By default, Blade {{ }} statements are automatically sent through
PHP's htmlspecialchars function to prevent XSS attacks. If you do not
want your data to be escaped, you may use the following syntax:
1st Simple Way To give the path: As Per Laravel 5.4 File Structure asset folder inside the resources folder So Suppose Your file inside that. ( resources/asset/ ) So You Can Use Like Below Example:
<script type="text/javascript" src="{{ URL::asset('js/jquery.js') }}"></script>
<link rel="stylesheet" href="{{ URL::asset('css/somestylesheet.css') }}" />
2nd Way You can just pass the path to the style sheet .
{!! HTML::style('css/style.css') !!}
You can just pass the path to the javascript.
{!! HTML::script('js/script.js'); !!}
Add the following lines in the require section of composer.json file and run composer update "illuminate/html": "5.*"
Register the service provider in config/app.php by adding the following value into the providers array:
'Illuminate\Html\HtmlServiceProvider'
Register facades by adding these two lines in the aliases array:
'Form'=> 'Illuminate\Html\FormFacade',
'HTML'=> 'Illuminate\Html\HtmlFacade'
3rd Way Place your assets in public directory and use the following:
<script type="text/javascript" src="{{ URL::asset('js/jquery.js') }}"></script>
<link rel="stylesheet" href="{{ URL::asset('css/somestylesheet.css') }}" />
OR ( Use URL::to() )
<link rel="stylesheet" type="text/css" href="{{ URL::to('css/style.css') }}">
<script type="text/javascript" src="{{ URL::to('js/jquery.min.js') }}"></script>
and all is working in local but on the server I receive a get error:
By server, are you referring to a remote server (e.g. VPS)? or PHP's built-in web server?
Have you tried running php artisan cache:clear as well?
I think you can try this for solve issue for http and https because your script and css no run in https url:
First you can create SchemalessUrlGenerator file in App\Libraries:
<?php
namespace App\Libraries;
use Illuminate\Http\Request;
use Illuminate\Routing\RouteCollection;
use Illuminate\Routing\UrlGenerator;
use Illuminate\Support\Str;
class SchemalessUrlGenerator extends UrlGenerator
{
public function __construct(RouteCollection $routes, Request $request)
{
parent::__construct($routes, $request);
}
public function to($path, $extra = [], $secure = null)
{
// First we will check if the URL is already a valid URL. If it is we will not
// try to generate a new one but will simply return the URL as is, which is
// convenient since developers do not always have to check if it's valid.
if ($this->isValidUrl($path)) {
return $path;
}
$scheme = $this->getScheme($secure);
$extra = $this->formatParameters($extra);
$tail = implode('/', array_map(
'rawurlencode', (array) $extra)
);
// Once we have the scheme we will compile the "tail" by collapsing the values
// into a single string delimited by slashes. This just makes it convenient
// for passing the array of parameters to this URL as a list of segments.
$root = $this->getRootUrl($scheme);
if (($queryPosition = strpos($path, '?')) !== false) {
$query = mb_substr($path, $queryPosition);
$path = mb_substr($path, 0, $queryPosition);
} else {
$query = '';
}
return '//' . $this->trimUrl($root, $path, $tail).$query;
}
/**
* {#inheritdoc}
*/
protected function getScheme($secure)
{
// Don't be smart Laravel... ask the browser?!?!
// negotiate the schema to be the same as how page was served
return '//';
}
}
Then you can add SchemalessUrlGenerator related code in App\Providers\AppServiceProvider in register method
$routes = $this->app['router']->getRoutes();
// // Replace UrlGenerator with SchemalessUrlGenerator that will serve content using "//" instead
// // of "http" or "https"
$schemalessUrlGenerator = new SchemalessUrlGenerator($routes, $this->app->make('request'));
$this->app->instance('url', $schemalessUrlGenerator);
Hope this help for you!

Scraping framework with xpath support

I'm looking for a web scraping framework that lets me
Hit a given endpoint and load the html response
Search for elements by some css selector
Recover the xpath for that element
Any suggestions? I've seen many that let me search by xpath, but none that actually generate the xpath for an element.
It seems to be true that not many people search by CSS selector yet want a result as an XPath instead, but there are some options to get there.
First I wound up doing this with JQuery plus an additional function. This is because JQuery has pretty nice selection and is easy to find support for. You can use JQuery in Node.js, so you should be able to implement my code in that domain (on a server) instead of on the client (as shown in my simple example). If that's not an option, you can look below for my other potential solution using Python or at the bottom for a C# starter.
For the JQuery approach, the pure JavaScript function is pretty simple for returning the XPath. In the following example (also on JSFiddle) I retrieved the example anchor element with the JQuery selector, got the stripped DOM element, and sent it to my getXPath function:
<html>
<head>
<title>The jQuery Example</title>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript">
function getXPath( element )
{
var xpath = '';
for ( ; element && element.nodeType == 1; element = element.parentNode )
{
var id = $(element.parentNode).children(element.tagName).index(element) + 1;
id > 1 ? (id = '[' + id + ']') : (id = '');
xpath = '/' + element.tagName.toLowerCase() + id + xpath;
}
return xpath;
}
$(document).ready(function() {
$("#example").click(function() {
alert("Link Xpath: " + getXPath($("#example")[0]));
});
});
</script>
</head>
<body>
<p id="p1">This is an example paragraph.</p>
<p id="p2">This is an example paragraph with a <a id="example" href="#">link inside.</a></p>
</body>
</html>
There is a full library for more robust CSS selector to XPath conversions called css2xpath if you need more complexity than what I provided.
Python (lxml):
For Python you'll want to use lxml's CSS selector class (see link for full tutorial and docs) to get the xml node.
The CSSSelector class
The most important class in the lxml.cssselect module is CSSSelector.
It provides the same interface as the XPath class, but accepts a CSS
selector expression as input:
>>> from lxml.cssselect import CSSSelector
>>> sel = CSSSelector('div.content')
>>> sel #doctest: +ELLIPSIS <CSSSelector ... for 'div.content'>
>>> sel.css
'div.content'
The selector actually compiles to XPath, and you can see the
expression by inspecting the object:
>>> sel.path
"descendant-or-self::div[#class and contains(concat(' ', normalize-space(#class), ' '), ' content ')]"
To use the selector, simply call it with a document or element object:
>>> from lxml.etree import fromstring
>>> h = fromstring('''<div id="outer">
... <div id="inner" class="content body">
... text
... </div></div>''')
>>> [e.get('id') for e in sel(h)]
['inner']
Using CSSSelector is equivalent to translating with cssselect and
using the XPath class:
>>> from cssselect import GenericTranslator
>>> from lxml.etree import XPath
>>> sel = XPath(GenericTranslator().css_to_xpath('div.content'))
CSSSelector takes a translator parameter to let you choose which
translator to use. It can be 'xml' (the default), 'xhtml', 'html' or a
Translator object.
If you're looking to load from a url, you can do that directly when building the etree: root = etree.fromstring(xml, base_url="http://where.it/is/from.xml")
C#
There is a library called css2xpath-reloaded which does nothing but CSS to XPath conversion.
String css = "div#test .note span:first-child";
String xpath = css2xpath.Transform(css);
// 'xpath' will contain:
// //div[#id='test']//*[contains(concat(' ',normalize-space(#class),' '),' note ')]*[1]/self::span
Of course, getting a string from the url is very easy with C# utility classes and needs little discussion:
using(WebClient client = new WebClient()) {
string s = client.DownloadString(url);
}
As for the selection with CSS Selectors, you could try Fizzler, which is pretty powerful. Here's the front page example, though you can do much more:
// Load the document using HTMLAgilityPack as normal
var html = new HtmlDocument();
html.LoadHtml(#"
<html>
<head></head>
<body>
<div>
<p class='content'>Fizzler</p>
<p>CSS Selector Engine</p></div>
</body>
</html>");
// Fizzler for HtmlAgilityPack is implemented as the
// QuerySelectorAll extension method on HtmlNode
var document = html.DocumentNode;
// yields: [<p class="content">Fizzler</p>]
document.QuerySelectorAll(".content");
// yields: [<p class="content">Fizzler</p>,<p>CSS Selector Engine</p>]
document.QuerySelectorAll("p");
// yields empty sequence
document.QuerySelectorAll("body>p");
// yields [<p class="content">Fizzler</p>,<p>CSS Selector Engine</p>]
document.QuerySelectorAll("body p");
// yields [<p class="content">Fizzler</p>]
document.QuerySelectorAll("p:first-child");

Implement layout tag for liquid template engine

I want to themed my blog that use liquid template engine, but default, the engine only support some basic tags, I want to write custom tag {% layout 'layout_name' %}
Layout file: dark.liquid
<html>
...
{% content_for_body %}
...
</html>
And template file: blog.liquid
{% layout 'dark' %}
welcome to my blog!
And output
<html>
...
welcome to my blog!
...
</html>
Thanks!
I don't think that something like this is possibly except for grabbing the first line and extracting the layout name before passing the rest of blog.liquid in, for example:
post = "{{ layout 'dark' }}\nWelcome to my blog!"
layout_name = post.split("\n").first.match(/\{\{ layout '(.+)' \}\}/)[1]
#=> "dark"
content = post.split("\n")[1..-1].join("\n")
#=> "Welcome to my blog!"
Also it should be "{{ content_for_body }}"; "{% ... %}" is used for tag blocks like an if statement.

document type does not allow element "img" / "font" here

I try to validate my xhtml and i have a little problem with this:
The end of the document i have this little JS script which contain IMG and FONT tags, and i get error for this:
document type does not allow element "img" here;
document type does not allow element "font" here
$("#nick_name").change(function()
{var usr=$("#nick_name").val();if(usr.length>=4)
{$("#status").html('<img src="images/loader.gif" align="middle" alt="" title=""/>');
.
.
.
How can i validate this?
Thank you.
Put the script in a CDATA to validate; details. I found it is a good practice when dealing with javascript and validation.
Something like this
<script type="text/javascript">
<![CDATA[
$("#nick_name").change(function()
{var usr=$("#nick_name").val();if(usr.length>=4)
{$("#status").html('<img src="images/loader.gif" align="middle" alt="" title=""/>');
.
.
.
]]>
</script>

Resources