How to get django_hitcount app working with Mezzanine blog - django

Been trying for several hours now.
I set up according to instructions but I can't get it to count hits on a blog post.
/blog/blog_post_detail.html
{% load .. .. .. hitcount_tags %}
.
.
.
.
{% block blog_post_detail_content %}
<script type="text/javascript">
$(document).ready(function() {
{% get_hit_count_javascript for blog_post %}
});
</script>
{% get_hit_count for blog_post %}
.
.
.
{% endblock %}
And in my urls.py I added:
url(r'^blog/ajax/hit/$', update_hit_count_ajax, name='hitcount_update_ajax'),
Looking at page source in browser the javascript does appear to run.
$(document).ready(function() {
var csrf = $('input[name=csrfmiddlewaretoken]').val();
$.post( '/blog/ajax/hit/',
{ csrfmiddlewaretoken: csrf, hitcount_pk : '1' },
function(data, status) {
if (data.status == 'error') {
// do something for error?
}
},
'json');
});
But it's not counting. So I'm not quite sure why it doesn't count a page hit.

Figured it out. In Mezzanine you have to put custom url patterns above the
("^", include("mezzanine.urls")),
pattern otherwise they will be ignored.

Related

In flask admin, add confirmation prompt when Save new record

Our users have the usual CRUD actions in various flask pages.
For one scenario, the Create action can be an intensive process, with lots of domain logic performed, and on occasion, items have been created accidentally.
Our users would now like to add a simple "Are you sure you want to create this Account?" prompt when they click the "Save" button. The next response would simply be Yes and No buttons.
It's not apparent how to add this - are we missing something obvious?
Override the Flask-Admin create template for the particular view and add a JavaScript confirmation to the form's onSubmit event. Adding the confirm to the submit event handles the three submit buttons; 'Save', 'Save and Add Another' and 'Save and Continue'.
For example:
class UserView(ModelView):
create_template = 'create_user.html'
# ...
In the /templates/admin folder add html file 'create_user.html':
{% extends 'admin/model/create.html' %}
{% block tail %}
{{ super() }}
<script src="{{ admin_static.url(filename='admin/js/helpers.js', v='1.0.0') }}" type="text/javascript"></script>
<script>
(function ($) {
$('form:first').on('submit', function() {
return faHelpers.safeConfirm('{{ _gettext('Are you sure you want to save this record?') }}');
});
})(jQuery);
</script>
{% endblock %}
Note there's a bug in Flask-Admin 1.5.3, helpers.js is missing from the distribution and you will need to add the safeConfirm function.
{% extends 'admin/model/create.html' %}
{% block tail %}
{{ super() }}
<script>
(function ($) {
function safeConfirm(msg) {
try {
var isconfirmed = confirm(msg);
if (isconfirmed == true) {
return true;
}
else {
return false;
}
}
catch (err) {
return false;
}
}
$('form:first').on('submit', function () {
return safeConfirm('{{ _gettext('Are you sure you want to save this record?') }}');
});
})(jQuery);
</script>
{% endblock %}

Add RTF/Rich Text Editor to CustomUserCreationForm/CustomUserEditForm

I try to extend my custom User model as described here.
This works fine for the shown fields like ModelChoiceField and CharField.
My goal now is to add a RTF field (the control like the one shown in the Page model). I have looked through the source code of wagtail and found the method get_rich_text_editor_widget which is being used in conjunction with a CharField. Sadly I get a JavaScript error:
Uncaught TypeError: Cannot read property 'initEditor' of undefined
My guess now is that I somehow need to include or modify a hook for the widget. Or is it sufficient to override the JavaScript block in a template? It feels a bit hacky right now and I am stuck with including the required JS, that's why I am posting the question. Maybe I am missing something trivial.
# ...
from wagtail.admin.rich_text import get_rich_text_editor_widget
class CustomUserEditForm(UserEditForm):
position = forms.ModelChoiceField(queryset=Position.objects, required=True, label=_('Position'))
# biography = forms.Textarea()
biography = forms.CharField(widget=get_rich_text_editor_widget())
Update:
Updating my template (maybe not the right approach):
{% block js %}
{{ block.super }}
<script type="text/javascript" src="/static/wagtailadmin/js/draftail.js"></script>
{% endblock js %}
Results in:
I've written my solution up as an issue for draftail
https://github.com/springload/draftail/issues/450
I've got a wagtail site with this awesome RichText Editor (called Draftail) but trying to use it on a non Wagtail Admin page makes me feel dirty. I wanted a biography field that people could write about themselves and I wanted the blog authors to be able to use it as well. BUT to do that I've had to do some things that make me cringe.
Not bad:
{% block extra_css %}
<link href="{% static 'wagtailadmin/css/panels/draftail.css' %}" type="text/css" media="all" rel="stylesheet">
{% endblock extra_css %}
WTF???? why aren't we just using Favicons for things like Bold
<div data-sprite></div>
<script>
function loadIconSprite() {
var spriteURL = '{% url "wagtailadmin_sprite" %}';
var revisionKey = 'wagtail:spriteRevision';
var dataKey = 'wagtail:spriteData';
var isLocalStorage = 'localStorage' in window && typeof window.localStorage !== 'undefined';
var insertIt = function (data) {
var spriteContainer = document.body.querySelector('[data-sprite]');
spriteContainer.innerHTML = data;
}
var insert = function (data) {
if (document.body) {
insertIt(data)
} else {
document.addEventListener('DOMContentLoaded', insertIt.bind(null, data));
}
}
if (isLocalStorage && localStorage.getItem(revisionKey) === spriteURL) {
var data = localStorage.getItem(dataKey);
if (data) {
insert(data);
return true;
}
}
try {
var request = new XMLHttpRequest();
request.open('GET', spriteURL, true);
request.onload = function () {
if (request.status >= 200 && request.status < 400) {
data = request.responseText;
insert(data);
if (isLocalStorage) {
localStorage.setItem(dataKey, data);
localStorage.setItem(revisionKey, spriteURL);
}
}
}
request.send();
} catch (e) {
console.error(e);
}
}
loadIconSprite();
</script>
Because wagtail comments.js somehow needs wagtailConfig.ADMIN_API and draftail won't initialize without comments.js
<script>
(function(document, window) {
window.wagtailConfig = window.wagtailConfig || {};
wagtailConfig.ADMIN_API = {
PAGES: '',
DOCUMENTS: '',
IMAGES: '',
{# // Use this to add an extra query string on all API requests. #}
{# // Example value: '&order=-id' #}
EXTRA_CHILDREN_PARAMETERS: '',
};
{% i18n_enabled as i18n_enabled %}
{% locales as locales %}
wagtailConfig.I18N_ENABLED = {% if i18n_enabled %}true{% else %}false{% endif %};
wagtailConfig.LOCALES = {{ locales|safe }};
wagtailConfig.STRINGS = {% js_translation_strings %};
wagtailConfig.ADMIN_URLS = {
PAGES: ''
};
})(document, window);
</script>
<script src="{% static 'wagtailadmin/js/vendor/jquery-3.5.1.min.js' %}"></script>
<!-- <script src="{% static 'wagtailadmin/js/core.js' %}"></script> strangely not needed -->
<script src="{% static 'wagtailadmin/js/vendor.js' %}"></script>
<script src="{% static 'wagtailadmin/js/comments.js' %}"></script>
{{ form.media.js }}
All of this just to get the draftail editor on a non wagtail admin page!

Django oembed URLs for embedded tweets

I have a list of a few hundred Twitter oembed URLs but I don't know how to implement the GET requests of a list of ids in a view.
Edited - OP was using URLS, not ids.
<div class="tweets">
{% for id in ids %}
<script language="JavaScript" type="text/javascript">
$(".tweets").append(<div id="tweet" tweetID={{ id }}>)
</script>
<script sync src="https://platform.twitter.com/widgets.js"></script>
<script>
window.onload = (function(){
var tweet = document.getElementById("tweet");
var id = tweet.getAttribute("tweetID");
twttr.widgets.createTweet(
id, tweet,
{
conversation : 'none', // or all
cards : 'hidden', // or visible
linkColor : '#cc5443', // default is blue
theme : 'light' // or dark
})
.then (function (el) {
el.contentDocument.querySelector(".footer").style.display = "none";
});
});
</script>
{% endfor %}
</div>
I'm trying to loop through a list of tweet ids and embed them. How do I make the JQuery loop through to create a div for each list item?
RapydML and Rapydscript
are what I was looking for. First, I created a nodeenv env. Now, I'm rewriting the above code in pythonic javascript and pythonic html.

Angular and django integration

I'm writing application with django and angular and I have following problem. After authentication in django I turn mvc view with angular app definition.
<div class="main">
<div class="main-inner">
<div class="container" ng-app="povos" ng-view>
{% block content %}{% endblock %}
{% block scripts %}{% endblock %}
</div>
</div>
</div>
<script src="/static/assets/js/bootstrap.js"></script>
<script src="/static/assets/js/angular.js"></script>
<script src="/static/assets/js/angular-route.js"></script>
<script src="/static/assets/js/angular-cookies.js"></script>
<script src="/static/spa_app/app.js"></script>
<script src="/static/spa_app/modules/messages/messages.module.js"></script>
My app.js looks like that:
angular.module('povos', ['povos.messages'])
And my messages module like following:
angular.module('povos.messages', ['ngRoute'])
.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/messages', {
templateUrl: 'messages.html'
})
}])
My problem is that if I return that view and I try to request to /messages path I get:
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/messages
Using the URLconf defined in povos.urls, Django tried these URL patterns, in this order:
(urls here)
The current URL, messages, didn't match any of these.
My browses call to django mvc app. I understand in this way. Is it possible not to call django only work on angular routeProvider? How to configure it? Sorry for my english but It is not my native language.
You are serving the page through Django, so first ensure /messages/ is available in urls.py of Django.
After the root page and AngularJS files are loaded successfully, Angular starts to aware the URL:
by default it's in the hash form, thus only when the URL is /messages/#/messages, can the Angular router match the URL and render message.html.
/messages/#/messages
^ ^ ^ ^
| | | |
| | |Angular Part
|Django Part

how to refresh in a div values from a model with jquery .ajax() to django

I have a view which returns a chained object of 3 models
def test(request):
output=itertools.chain(
model1.objects.all(),
model2.objects.all(),
model3.objects.all()
)
return render_to_response('test.html', {'output':output})
In the html, I added an anchor and a jQuery script, which should replace the #output with new values just from model1
<html>
<head>...</head>
<body>
<script>
$(document).ready(function() {
$("#switch").click(function() {
$.ajax({
url: $(this).attr("href"),
success: function(result) {
//whatever I put here is not triggered
}
});
});
});
</script>
<a id="switch" href="?model=1">switch to model 1</a>
<div id="output">
{% for item in output %}
<div id="{{item}}">
{{item}}
</div>
{% endfor %}
</div>
</body>
</html>
I tried to put the div#output into a separate template output.html and modified the views.py like so:
def test(request, template='test.html'):
if request.GET.get('model'):
output=model1.objects.all()
else:
output=itertools.chain(
model1.objects.all(),
model2.objects.all(),
model3.objects.all()
)
if request.is_ajax(): template='output.html'
return render_to_response(template, {'output':output})
But everytime I click the link, the whole page is refreshed (with the new values from model1).
Opera returns just the output.html
Been struggling with this for more than 3 days, Im new into Ajax and this is getting very confusing for me.
I hope someone can shed some light!
First, make sure that your view works and that you're getting the expected HTML output when accessing the url directly (you might also want to comment out if request.is_ajax() temporarily).
Then, try replacing the content of the #output div using jQuery.html() method in your ajax call. Here is an example with some animation:
$.ajax({
...
success: function( returnedData ) {
$("#output").css("color", "red").fadeOut(500, function() {
$("#output").html(returnedData);
$(this).css("color", "green").fadeIn(500);
});
}
Also, try monitoring your ajax call using Firebug/Chrome Developer Tools - both tools will allow you to quickly determine the issue.
Thanks to Daniel Rosman for the heads-up I had to prevent the default action of the a#switch. It works like butter now!
Here is the initial question: how to access jQuery.ajax() get parameters in Django views