Symfony 3 | FOSCommentBundle manage many Threads / Comments - comments

I use FOSCommentBundle in my project, I already configured it with a thread and a comment class and this is working.
But now I need to manage many types of thread and comment.
For example I have News with comments and I have Contents with comments.
Of course, the news comments are different from content comments.
I don't know how to do it in the config.yml :
fos_comment:
db_driver: orm
class:
model:
comment: Project\MyBundle\Entity\News
thread: Project\MyBundle\Entity\Comment
How can I add my other thread / comment type ? Or how can I manage this case ?
TY

In the template that you want to use FOSCommentBundle you have to put thi code:
{% include 'FOSCommentBundle:Thread:async.html.twig' with {'id': 'foo'} %}
So in the part {'id':'foo'} you can put a different id for any thread you want, even a different thread for any news, for example
{% include 'FOSCommentBundle:Thread:async.html.twig' with {'id': 'news'~news.id} %}

Related

Theme is caching previous user name

We are using CAS to login to our Drupal instance. This is working correctly and displaying the correct user content (blocks etc. based on roles). What is not working correctly is the small snippet in the theme that says welcome . It keeps showing the previous user who logged in.
How do I set this in bigpipe?
The code looks like this in the theme: <span id="user_name">{{user.displayname}}</span>
Is there a way to tell bigpipe not to cache this?
This code snippet is on one of our twig files header.twig.html which is a partial.
I ended up putting this in a block, and just referencing the block section in the theme instead of just pulling that, then I used the block to be ignored for caching.
Thanks!
I used this post with other resources to solve a similar problem. We were including {{ user.displayname }} in a twig template for the header on all pages of our site. Some users were seeing other users' names in the header after signing in. We wanted to solve the problem while impacting caching as little as possible. Here, I share in detail what we did in the hope that it will help others. I'll use the specific names used in our code. Readers will need to adjust to their own names. (The code follows our prescribed format, so please forgive that it isn't standard.)
Step 1
Create a custom module. Custom module creation is covered adequately in other places, so I won't give details here. Our custom module is named rsc.
Step 2
Create the folder modules/custom/rsc/src/Plugin/Block and in it create a file named DisplayName.php.
Step 3
In the file DisplayName.php, include the following:
<?php
namespace Drupal\rsc\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\user\Entity\User;
/**
* A block to show the user's display name
*
* #Block(
* id = "display_name",
* admin_label = "Display Name"
* )
*/
class DisplayName extends BlockBase // The class name must match the filename
{
public function build()
{
$user = User::load(\Drupal::currentUser()->id());
return
[
'#type' => 'markup',
'#markup' => $user->getDisplayName(),
'#cache' => ['contexts' => ['user']]
];
}
}
Step 4
Clear the Drupal cache to make the new block available at Block Layout.
Step 5
Go to Admin > Structure > Block Layout and place the Display Name block in the Hidden Blocks For Referencing - Not Displayed section (bottom of the list on our site). In the Configure Block dialog, edit the Machine name to display_name to match id in the code above. Clear the Display title checkbox and save. Doing this makes the block available for use in twig templates.
Step 6
In the twig template for the header, replace
{{ user.displayname }}
with
{{ drupal_entity('block', 'display_name') }}
The drupal_entity function is part of the twig_tweak module, which we were already using. It allows insertion of a custom block into a twig template. If you're not using this module, you'll need to install it, or find another method of including a block in a twig template.
Step 7
Clear the Drupal cache to make the modified template take effect.
If you see anything about this that can be improved, please comment.

Shopify - sort blog Posts from oldest to newest - old post first

How to make Shopify sort blog Posts from oldest to newest?
Now the newest post is on top. It does not work for the blog that tells the story. Naturally, you have to read a story from the begging.
Some other blogs have to be sorted in default order - from newest to older. I.e. newest top.
Q: How to make Old first sorting for some blogs?
It depends on the amount of blog posts.
There are 3 approaches.
Liquid way
You can overwrite the article paginate and reverse the loop.
Example:
{% paginate blog.articles by 9999 %}
{% for article in blog.articles reversed %}
...
{% endfor %}
{% endpaginate %}
The larger the article amount the slower the DOM load speed will be.
So if you have 1000+ articles this is not a good solution.
REST API
You can register a private app an set only the Store content like articles, blogs, comments, pages, and redirects permission to Read and everything will be disabled.
Then you will need to request the following URL: https://API_KEY:API_PASS#STORE.myshopify.com/admin/api/2020-01/blogs/BLOG_ID/articles.json?limit=250 ( multiply times if you have more than 250 articles )
And reverse the result array.
If you have many articles this solution is once again not great.
GraphQL
The best one is to use the StoreFront GraphQL API here where you can reverse the results.
Example query:
{
blogByHandle(handle:"news"){
articles(first: 50, reverse: true){
edges {
node {
title
}
}
}
}
}
This way you will keep the pagination intact ( since GraphQL return Cursor that you can use for the pagination ) and you will keep the requests at minimum.
I've actually made an app to drag and drop blogs into the positions you would like. Here's the link to the Shopify App: Article Organizer Pro

Jekyll: Can I combine collections and data files?

Short version: How do I reference a collection by variable in Liquid?
I'm building a site on Jekyll which is documentation with multiple different parts. It consists of collections of articles and there are no blogposts. Right now I have a three level menu structure defined with data files, where the third level is the actual articles. The data file look like this.
menu.yml
- title: Book
url: book
subpages:
- title: Volume 1
url: book/vol1
- title: Volume 2
url: book/vol2
- title: The Library
url: library
subpages:
- title: Getting started
url: library/getting-started
- title: Components
url: library/components
- title: Theme
url: theme
subpages:
- title: Tutorials
url: theme/tutorials
- title: Reference
url: theme/reference
Additionally, I have collections defined that match the top level items by url.
_config.yml
...
collections:
book:
output: true
library:
output: true
theme:
output: true
Right now I use the menu YML to construct myself a nice two level structure and put the articles into them to form the third level. The problem is that I don't know how to call the collections dynamically when I am constructing the menu. For example when I am creating the 'Book' menu item, I'd like to loop over site.book data collection with something like this:
{% assign collection = 'book' %}
{% for p in site.{{collection}} %}
<p>{{p.title}}</p>
{% endfor %}
site.{{collection}} doesn't work there but for example calling directly site.book does. I don't know how to pass the variable in Liquid.
What I do to get around this problem is that for every menu item that I create i loop through the whole {{site.pages}} which contains all the articles in the whole site, and match their url against the menu item url. These feels like bad programming on so many levels and I'm taking a huge performance hit when looping through everything multiple times. Generation of files goes up four times, from 5 seconds to 20 seconds right now, and it will get even worse when I make the menu even larger.
So I'm open to hearing how I could loop dynamically through the collections, or hearing about other options to create such a menu. As I have the relative url at hand, for example /book/vol1, the optimal would to find a way to get a reference to all articles within that folder (excluding those in subfolders but that is not a must-have).
The syntax for using a liquid variable inside a liquid tag looks a bit different than {% for p in site.{{collection}} %}. You can try either:
{% assign collection = 'book' %}
{% for p in site.[collection] %}
or you simply use:
{% assign books = site.book %}
{% for p in books %}

Output Available Objects and Properties in Liquid Templates

Is there a way to output (for debugging/informational purposes) the available objects and object properties in a liquid template?
That is, say I'm using the jekyll site generation tool, and I'm in my index.html template (which is, to my understanding, a liquid template). It might look something like this
{% for post in site.posts %}
<li><span>{{ post.date | date_to_string }}</span> ยป {{ post.title }}</li>
{% endfor %}
Are there any template tags I could use that would tell me/output a variable named post was available in this template (as well as the other templates). Also, are there any template tags I could use that would tell me the post object has the keys date, title, url, excerpt, permalink, etc.
There's no way to do this from a Liquid template that I'm aware of. I used the following bit of Ruby code to do it in a test for Jekyll though (setup_post is a helper method in Jekyll's test suite)
post = setup_post("2008-11-21-complex.textile")
classes = []
Liquid::Template.parse(post.content).root.nodelist.each do |token|
classes << token.name if token.is_a?(Liquid::Variable)
end
It should be possible to write a Jekyll plugin that could output this stuff on your page based on the above code.

Cannot modify site.tags from Jekyll plugin

I'm developing a plugin to facilitate multilingual Jekyll sites, and as part of this I have to categorise posts according to their language.
I'm trying to tag the post according to its language, so I have overwritten the aggregate_post_info method, but when I print the site.tags variable, it is empty.
module Jekyll
class Site
alias_method :_aggregate_post_info, :aggregate_post_info
def aggregate_post_info(post)
_aggregate_post_info(post)
#tags[post.data['lang']] << post
end
end
end
I have achieved something similar by defining my own language specific variables, like in this simplified example:
for post in site.posts.docs do
lang = post.data['lang']
for tag in post.data['tags'] do
slug = jekyll_tagging_slug(tag)
site.config['t'][lang]['tagnames'] = slug
end
end
I also automatically generate tag pages (and category pages using a different approach without plug-ins), avoid name collisions for multiple languages, and precompute aggregate counts for better performance. The whole thing is described in two blog posts http://www.guido-flohr.net/multilang-with-jekyll/ and http://www.guido-flohr.net/jekyll-multilang-tags/.
You can simply add the post language as a tag, i.e. tags: [english, ruby, etc], avoiding altogether the monkey patching. So, when you want to show only lang-tagged posts, you simply filter them:
<ul class="posts">
{% for post in site.tags.english %}
<li>
{{ post.title }}
</li>
{% endfor %}
</ul>
This way, most of the work is done by Jekyll, saving you some time and effort. :)

Resources