I am writing my backend using DRF and using VueJS frontend templates. In the admin panel I use Ckeditor to edit textfield.
class ArticleModelForm(forms.ModelForm):
content = forms.CharField(widget=CKEditorUploadingWidget)
class Meta:
model=Article
fields = [ "title", "slug" "published_at"]
While rendering a post TextField I can not use template filters to render correctly, so text seems ruined. I have tried lots of things but no success yet.
<template>
<div>
<div class="container negative-margin-top150">
<div class="col col-xl-8 m-auto col-lg-12 col-md-12 col-sm-12 col-12">
<div class="ui-block">
<!-- Single Post -->
<article class="hentry blog-post single-post single-post-v1">
<div class="post-content-wrap">
<div class="post-content" >
<p class="post-paragraph">
{{article.content}}
</p>
<p>{{content}}</p>
</div>
</div>
</article>
<!-- ... end Single Post -->
</div>
</div>
</div>
</div>
</template>
and my script is below
<script>
import axios from 'axios';
export default {
name: "Article",
props: {
slug: {
type: String,
required: true
}
},
data() {
return {
article: {},
content: `${content}`,
}
},
methods: {
setPageTitle(title) {
document.title = title;
},
setRequestUser() {
this.requestUser = window.localStorage.getItem("username");
},
getArticle(slug) {
axios.get(`http://localhost:8000/api/articles/${this.slug}`)
.then(response => {
this.article = response.data;
this.setPageTitle(response.data.title);
this.content = window.content;
});
}
},
created() {
this.getArticle();
this.setRequestUser();
},
};
</script>
Now in the browser my text is rendered with template tags
<h3>The standard Lorem Ipsum passage, used since the 1500s</h3>
<p>"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
Anybody here who can point me in the right direction?
You need to use v-html attribute to render raw conent.
https://v2.vuejs.org/v2/guide/syntax.html
Related
Below the HTML and Jquery code that is not working. I want two tabbing section on a single page.
So, how can I modify it to make it work ?..
<div class="container">
<ul class="tabs">
<li class="tab-link current" data-tab="tab-1">Tab One</li>
<li class="tab-link" data-tab="tab-2">Tab Two</li>
<li class="tab-link" data-tab="tab-3">Tab Three</li>
<li class="tab-link" data-tab="tab-4">Tab Four</li>
</ul>
<div id="tab-1" class="tab-content current">
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
<div id="tab-2" class="tab-content">
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
<div id="tab-3" class="tab-content">
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
</div>
<div id="tab-4" class="tab-content">
Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
$(document).ready(function(){
$('ul.tabs li').click(function(){
var tab_id = $(this).attr('data-tab');
$('ul.tabs li').removeClass('current');
$('.tab-content').removeClass('current');
$(this).addClass('current');
$("#"+tab_id).addClass('current');
})
})
I'm using ZURB Foundation (v6) Accordions.
When an accordion opens, I want to scroll the page to be at the top of that accordion item. I can run this code:
$("#arf").on("down.zf.accordion", function() {
$('html,body').animate({scrollTop: $(this).offset().top}, 'slow');
});
Of course, this scrolls the page to the top of the accordion, not the accordion item. How would I modify this code to scroll to the accordion's item when it opens?
Here is the solution that I found that works. This works for version 6 of Foundation for Sites.
$("#form-selector").on("up.zf.accordion", function(event) {
setTimeout(function(){
$('html,body').animate({scrollTop: $('.is-active').offset().top}, 'slow');
}, 250); //Adjust to match slideSpeed
});
The setTimeout is used because of the slideSpeed of the accordion. If you do not use setTimeout it scrolls the moment down.zf.accordion fires thus scrolling to the wrong position.
You can also us down.zf.accordion in place of up.zf.accordion, however, if you use down.zf.accordion, it will fire once the page loads (as the accordion is initialized and opens) and scrolls to the accordion item. This is unwanted in my case but may be desired in certain case.
You could attach your own click listeners to each accordion <a> tag and scroll to the top of that tag on click. Eg.
JS
$('.accordionBtn').on('click', function(event) {
$('html,body').animate({scrollTop: $(event.target).offset().top}, 'slow');
});)
CSS
<ul class="accordion" data-accordion>
<li class="accordion-navigation">
<a class="accordionBtn" href="#panel1a">Accordion 1</a>
<div id="panel1a" class="content active">
Panel 1. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
</li>
<li class="accordion-navigation">
<a class="accordionBtn" href="#panel2a">Accordion 2</a>
<div id="panel2a" class="content">
Panel 2. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
</li>
<li class="accordion-navigation">
<a class="accordionBtn" href="#panel3a">Accordion 3</a>
<div id="panel3a" class="content">
Panel 3. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
</li>
</ul>
I first used the solution posted by #L84 then I thought of this one.
In the code below, $active references the currently active accordion item (Note: the reference is stored each time an accordion is opened rather than when the accordion title is clicked). When a new title is clicked, $active is the item that will be closed. We need to know its height in advance.
For the newly active accordion item to be properly positioned, the height of that previously active item has to be subtracted from the viewport's scrolling position -- note that this in necessary only if the newly active item is located further down.
$(function () {
var $active;
$(".accordion").on("click", ".accordion-title", function () {
var itemIndexNew = $(".accordion-item").index($(this).parent());
var itemIndexOld = ($active ? $(".accordion-item").index($active) : null);
if (itemIndexOld !== null && itemIndexOld < itemIndexNew) {
$("html, body").scrollTop($(window).scrollTop() - $active.height());
}
});
$(".accordion").on("down.zf.accordion", function(e) {
$active = $(".accordion").find(".accordion-item.is-active");
});
$(document).foundation();
});
You could use the below script, im also using foundation 6 accordion, this will work also if you have multiple accordions on single page. Thanks
jQuery(".accordion-title").click(function() {
var $this = this;
setTimeout(function(){
jQuery('html,body').animate({scrollTop: jQuery($this).closest('.accordion').find('.is-active').offset().top}, 'slow');
}, 250);
});
I try to understand how Ember works and I have an issue I can't understand. I am following a tutorial (guides.emberjs.com/v1.10.0/) and I don't understand why I only see an element when I go on a page when I click (and doesn't work with a direct link).
I think some screenshots will be helpful to understand my issue.
This is what I have when I visit "index.html#/posts/1". No article is displayed.
http://i.stack.imgur.com/qzwlq.png
This is what I have when I visit "index.html#/posts" and then click on Rails is Omakase on the left. An article is displayed whereas the link is on my browser is "index.html#/posts/1" (and when I refresh nothing is displayed).
http://i.stack.imgur.com/YpmzX.png
This is my index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Blog tuto</title>
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/2.3.2/css/bootstrap-combined.no-icons.min.css">
</head>
<body>
<script type="text/x-handlebars">
<div class="navbar">
<div class="navbar-inner">
<a class="brand" href="#">Bloggr</a>
<ul class="nav">
<li>{{#link-to "posts.index"}}Posts{{/link-to}}</li>
<li>{{#link-to "about"}}About{{/link-to}}</li>
</ul>
</div>
</div>
{{outlet}}
</script>
<script type="text/x-handlebars" id="about">
<p>
Lorem ipsum about
</p>
</script>
<script type="text/x-handlebars" id="posts">
<div class="container-fluid">
<div class="row-fluid">
<div class="span4">
<table class="table">
<thead>
<tr><th>Recent Posts</th></tr>
</thead>
{{#each post in model}}
<tr>
{{#link-to "posts.post" post}}
<td>{{post.title}} <small class="muted">by {{post.author}}</small></td>
{{/link-to}}
</tr>
{{/each}}
</table>
</div>
<div class="span8">
{{outlet}}
</div>
</div>
</div>
</script>
<script type="text/x-handlebars" id="posts/post">
{{#if isEditing}}
{{partial "post/edit"}}
<button {{action "doneEditing"}}>Done</button>
{{else}}
<button {{action "edit"}}>Edit</button>
{{/if}}
<h1>{{title}}</h1>
<h2><small class="muted">by {{author}}</small></h2>
<hr>
<div class="intro">
{{exerpt}}
</div>
<div class="below-the-fold">
{{body}}
</div>
</script>
<script type="text/x-handlebars" id="post/edit">
<p>{{input type="text" value=title}}</p>
<p>{{input type="text" value=exerpt}}</p>
<p>{{textarea value=body}}</p>
</script>
<script src="../js/libs/jquery.min.js"></script>
<script src="../js/libs/handlebars.js"></script>
<script src="../js/libs/ember.js"></script>
<script src="../js/libs/ember-data.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/showdown/0.3.1/showdown.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.1.0/moment.min.js"></script>
<script src="app.js"></script>
</body>
</html>
And app.js
App = Ember.Application.create();
App.Router.map(function() {
this.route('about');
this.resource('posts', function () {
this.route('post', {path: ':post_id'});
});
});
App.PostsRoute = Ember.Route.extend({
model: function () {
return posts;
}
});
App.PostsPostRoute = Ember.Route.extend({
model: function (params) {
return posts.findBy('id', params.post_id);
}
});
App.PostsPostController = Ember.ObjectController.extend({
isEditing: false,
actions: {
edit: function () {
this.set('isEditing', true);
},
doneEditing: function () {
this.set('isEditing', false);
}
}
});
var posts = [{
id: 1,
title: "Rails is Omakase",
author: "mc100s",
date: new Date('08-06-2015'),
exerpt: "Lorem ipsum dolor sit amet",
body: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
}, {
id: 2,
title: "The Parley Letter",
author: "mc100s",
date: new Date('08-06-2015'),
exerpt: "Duis aute irure dolor in reprehenderit",
body: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
}];
Thank you for your help
When you click link, model is passed directly to the route and route's model hook is not fired, so you see article. When you reload route model hook is fired and something goes wrong.
Make string id, because params.post_id is String.
findBy is Ember.Array method. http://emberjs.com/api/classes/Ember.Array.html#method_findBy
I would try:
var posts = Ember.A([{
// as is
}]);
Next change ObjectController to Controller (ObjectController is deprecated) and use {{model.title}} instead of {{title}} in template:
<script type="text/x-handlebars" id="posts/post">
{{#if isEditing}}
{{partial "post/edit"}}
<button {{action "doneEditing"}}>Done</button>
{{else}}
<button {{action "edit"}}>Edit</button>
{{/if}}
<h1>{{model.title}}</h1>
<h2><small class="muted">by {{model.author}}</small></h2>
<hr>
<div class="intro">
{{model.exerpt}}
</div>
<div class="below-the-fold">
{{model.body}}
</div>
working jsbin here: http://jsbin.com/pozabixeka/edit?html,js,output
I'm trying to reverse a model's output in ember. It was suggested (via IRC channel) that I use a computed property, but I am having a tough time figuring out how to do this.
I'm trying to do this in the controller. Any help would be appreciated, as I am pretty new to ember.
controllers/comments.js
export default Ember.Controller.extend({
model: 'comment',
reverse: function(){
return this.get('model').toArray().reverse();
}.property('model.#each')
});
comments.hbs
{{#each model as |item|}}
<div class="each__comment">
<div class="comment__image">
<img src="{{ item.img_src }}">
</div>
<div class="comment__text">
<h2 class="comment__author">{{item.full_name}}</h2>
<h3 class="comment__title">{{item.title}}</h3>
<p class="comment__description">{{item.description}} </p>
<p class="comment__date">{{ item.date_posted }}</p>
</div>
</div>
{{/each}}
routes/comments.js
export default Ember.Route.extend({
model: function() {
return this.store.find('comment');
},
actions: {
createComment: function() {
var title = this.controller.get('newComment');
if (title && !title.trim()) {
this.set('newComment', '');
return;
}
var comment = this.store.createRecord('comment', {
description: title
});
this.controller.set('newComment', '');
// Save the new model
comment.save();
}
}
});
models/comment.js
var Comment = DS.Model.extend({
img_src: DS.attr('string', {
defaultValue: '/assets/images/user-img-4.png'
}),
full_name: DS.attr('string', {
defaultValue: 'Nick Beattie'
}),
title: DS.attr('string', {
defaultValue: 'Developer'
}),
description: DS.attr('string', {
defaultValue: 'description duh'
}),
date_posted: DS.attr('string', {
defaultValue: 'Tues Nov 17th'
})
});
Comment.reopenClass({
FIXTURES: [
{
"id": "1",
"img_src": "/assets/images/user-img-1.png",
"full_name": "Tony Jackson",
"title": "Product Designer",
"description": "Morbi at augue eu felis cursus feugiat. Pellentesque a dui ut magna tristique imperdiet. Donec nec rutrum purus. Quisque id nibh metus. Proin condimentum non ipsum at sagittis. Suspendisse potenti.",
"date_posted": "Tues Apr 10th"
},
{
"id": "2",
"img_src": "/assets/images/user-img-2.png",
"full_name": "Laura Malroy",
"title": "Strategist",
"description": "Proin egestas turpis nec orci vulputate accumsan. Nullam gravida ultricies feugiat. Praesent molestie pulvinar egestas.",
"date_posted": "Sat May 14th"
},
{
"id": "3",
"img_src": "/assets/images/user-img-3.png",
"full_name": "Nicole Emsley",
"title": "Illustrator",
"description": "Etiam sed cursus mi. Morbi neque elit, ullamcorper et justo ut, pharetra egestas metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi magna dolor, pretium eget convallis ac, faucibus quis elit. Pellentesque vehicula vestibulum ante in bibendum. Nam tristique nec mi sit amet semper.",
"date_posted": "Mon Jun 9th"
}
]
});
export default Comment;
You are practically there, just switch to using the computed property in the template instead of the model property.
{{#each reverse as |item|}}
<div class="each__comment">
<div class="comment__image">
<img src="{{ item.img_src }}">
</div>
<div class="comment__text">
<h2 class="comment__author">{{item.full_name}}</h2>
<h3 class="comment__title">{{item.title}}</h3>
<p class="comment__description">{{item.description}} </p>
<p class="comment__date">{{ item.date_posted }}</p>
</div>
</div>
{{/each}}
Also you don't need to define the model property in your controller, it's just going to get overwritten by the route. Additionally, the #each notation is generally used for watching a particular property on each item, if you just want to see if the collection grows or shrinks you can watch length or [].
export default Ember.Controller.extend({
reverse: function(){
return this.get('model').toArray().reverse();
}.property('model.[]')
});
Example: http://emberjs.jsbin.com/rucojiyemu/1/edit?html,js,output
At the console.log line in the render method below, it shows that this.member instance is exactly what it should be. So member object is good. I've spit out the string in tpl and it's what it should be. So what's causing the error in topic title?
Additional info: This view is a subview rendered by parent. I'm using Backbone.Subviews.
Thanks a lot for your help. I'm spinning my wheels :-/
Here is my code...
EDIT: Changed member object attrib references and now it works...
Template...
<div class="wrap-profile container">
<div class="profile-pic">
<div class="pic">
<img src="<%= pathUploads %><%= member.photo_profile %>" width="400" height="600" id="<%= member.id %>" class="photo-img">
</div>
</div>
<div class="profile-info">
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent consectetur urna nec erat pretium tempus.
</div>
<div>
Morbi nec arcu at leo lobortis egestas. Phasellus sagittis neque dolor, ut congue lorem egestas id.m laoreet, vitae tristique lorem sollicitudin.
</div>
<div>
In vel libero eget enim rhoncus suscipit. Nunc tristique in nisi eget bibendum. Mauris et pulvinar orci.
</div>
<div>
Quisque eget sem id dolor tempus dictum. Pellentesque luctus scelerisque lacinia.
</div>
<div>
Sed gravida rutrum bibendum. Aenean condimentum eu dui nec adipiscing. Duis sagittis pharetra enim.
</div>
</div>
</div>
The view js...
// ProfileView.js
define( function(require) {
"use strict";
var $ = require('jquery'),
_ = require('underscore'),
Backbone = require('backbone'),
Helper = require('helper'),
tpl = require('text!templates/profilePicTemplate.html'),
template = _.template(tpl);
return Backbone.View.extend({
el: $("#profile"),
initialize: function(member) {
var self = this;
this.member = member;
},
render: function() {
var data = {
pathUploads: Helper.global.pathUploads,
member: this.member
};
console.log(this.member);
this.$el.html(template(data));
return this;
},
destroy: function() {
template = null
this.member = null;
}
});
});
The evidence points quite directly at this.member being a plain old javascript object instead of an instance of a Backbone.Model subclass. You seem to be aware of this, so I think it's a case of "no really, hear us now and believe us later". To test this theory, swap in this snippet.
var data = {
pathUploads: Helper.global.pathUploads,
member: new Backbone.Model(this.member)
};
If that fixes it, the theory holds.
(Aside...)
For what it's worth, making your template require a backbone model instance instead of plain data is probably inferior, so consider just having your template do <%= member.photo_profile %> instead so it doesn't care where the data comes from. This also makes it easier to use the presenter design pattern. You can use member.toJSON() in your view to get at the plain data attributes to pass in to the template.