0

I am redesigning a website using angular as the frontend and keystoneJS as the backend. The site works as follows: editors load articles on the backend in a wysiwyg editor (tinymce) in keystone. Keystone saves it in a simple text/HTML format in a mongo database. The angular frontend then connects to the database and retrieves the article(s) it needs and displays it/them.

The article model in keystone has a number of attributes like author, extract, etc., but the key ones for this issue are 1) the full article text: article.content.extended (string) and 2) the footnotes: article.footnotes (array).

I would like to give the editors the ability to easily add footnote numbers in the article text by adding a simple angular component selector with the footnote number. This will avoid the need to have them input a lot HTML content manually. They would enter all the footnote information separately and the angular component will link the two together by index.

However, I have not been able to create this app-note component because when I tested to make sure that it would render in the browser if I added the angular app-note selector to the article text, it did not appear. So, my question is how to properly load data from a database that has angular selectors in it, so that angular can process them properly??

Currently, if I put in the selector like:

<app-note>1</app-note>

Then I only see "1" in the chrome inspector with no sign of the app-note selector.

Here is some of the relevant code I am using...

FullArticleComponent that get the article in full-article.component.ts:

import { PostsService } from './../../posts.service';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-full-article',
  templateUrl: './full-article.component.html',
  styleUrls: ['./full-article.component.css']
})
export class FullArticleComponent implements OnInit {
  slug = 'initial slug';
  article: any = 'initial article';

  constructor(private postsService: PostsService, private route: ActivatedRoute) { }

  ngOnInit() {
    this.route.params.subscribe(params => {
      this.slug = params['slug'];
      this.article = this.postsService.getArticle(this.slug);
    });
    this.postsService.articleChanged.subscribe(
      () => {
        this.article = this.postsService.currentArticle;
      }
    );
  }
}

Full article loaded by using innerHTML attribute in full-article.component.html:

<div class="post-content" [innerHTML]="article.content.extended"></div>
  • What does the app-note component exactly and what do you mean with 'link the two together by index'? – Moema Sep 25 '17 at 15:17
  • @Moema the footnotes are referenced in two places. First, it appears as a superscript number in the actual text where the app-note selector appears. Second, the complete note with authors, title, link, etc. would appear in the footnote area at the bottom of the page. app-note would format the in-text reference number and link to the corresponding footnote. The footnote number would be footnote index+1. – D. Proctor Sep 26 '17 at 15:52
  • what was/is your solution? – Moema Oct 11 '17 at 08:56

1 Answers1

0

The reason why you only see a "1" and not the html element (app-note selector) is because Angular is doing a sanitization when binding to innerHtml, see Angular docs for more information.

You can easily create a pipe which does by bypass the sanitization, see this post for an example.

If you do this, you should see your app-note selector in the Chrome inspector. But this would not work the way you want, because this html element is not part of the 'Angular system', so during initialization Angular doesn't know this dynamic element and it would never get initialized.

If you want to load an Angular component from CMS, you would have to create the components dynamically after you got the data, see here for a reference.

In your case, though, I think I would go with a simple solution (I hope I understood everything right). You don't have to format dynamically, the user can format the footnote in the wysiwyg editor (Format -> Superscript - creates a <sup> element). So your user can just set the footnote numbers in the text and then create a corresponding footnote element with the same number.

Moema
  • 863
  • 4
  • 10