How can we execute javascript code before sending it to the user in nodejs?

im running a blog using the ghost platform. Ghost is built with Nodejs, but I don't know much about it. I built the following code by grabbing the first image of each post and setting it as og: image. The problem is that it only loads after the website arrives on the user's machine. Is it possible to execute this from the server and then send it to the user?

    $(document).ready(function() {
        var siteURL = location.host;

         if(
                $('.post-template').length > 0 || 
                $('.page-template').length > 0
            ) {

                var featured_image = $('.post-content img[alt="featured-image"]').first().attr('src');


                // check if the featured image exists
                if(featured_image && featured_image.length > 0) {
                    var featured_image_fe = featured_image;
                    // create container for the image
                    if(featured_image_fe.substr(0,7) != 'http://'){
                        featured_image_fe = siteURL + featured_image_fe;
                    }

                    $('meta[property="og:image"]').attr('content', featured_image_fe);
                } else {
                    var featured_image = $('.post-content img').first().attr('src');

                    if(featured_image && featured_image.length > 0) {

                        var featured_image_nfe = featured_image;
                        if((featured_image_nfe.substr(0,7) != 'http://') && (featured_image_nfe.substr(0,8) != 'https://')){
                            featured_image_nfe = 'http://' + siteURL + featured_image_nfe;
                        }

                        $('meta[property="og:image"]').attr('content', featured_image_nfe);
                    } else {
                        $('meta[property="og:image"]').attr('content', 'http://media.techhamlet.com/wp-content/uploads/2014/06/techhamlet.jpg');
                    }


                }
            }
    }

      

+3


source to share


2 answers


Yes, it is definitely possible. I figured out a quick hack to get og: image support working in Ghost. This is definitely not an optimal solution, but it requires minimal code changes. You will need to install cheerio and change two files.

core / server/controllers/frontend.js

We need to update the formatResponse function starting at line 76.

var cheerio = require('cheerio');

function formatResponse(post) {
    var $ = cheerio.load(post.html);
    var firstImage = $('img').first();
    if(firstImage) {
        post.meta_image = firstImage.attr('src');
    }

    // Delete email from author for frontend output
    // TODO: do this on API level if no context is available
    if (post.author) {
        delete post.author.email;
    }
    return {post: post};
}

      

What we do is it runs the HTML post via cheerio. Grabbing the first image and overlaying the src on a new variable (meta_image) from the post object. This will make this variable available to the grip templating system.

Content / themes // default.hbs



Here I just updated the section {{! Page Meta }}

like this:

    {{! Page Meta }}
    <title>{{meta_title}}</title>
    <meta name="description" content="{{meta_description}}" />
{{#if this.post.meta_image}}
    <meta property="og:image" content="{{this.post.meta_image}}" />
{{/if}}
    <meta name="HandheldFriendly" content="True" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

      

We just check this.post.meta_image

if it exists and if it creates a meta tag.

more "correct" solution

To add this functionality, add an extra field to the post object for the og: image. Then you either fill this in with a separate field from the admin, or you can parse the html whenever you save the post and put it in the appropriate field. So the logic to fill the image og: is executed only once, when the page is saved and every time the page is rendered.

+6


source


It was like a comment, but too long and I don't know Gosht, either

Why do you

if (
    $('.post-template').length > 0 || 
    $('.page-template').length > 0
)

      

? Checking twice, the same condition will just slow down if anything.

If I understand your purpose correctly, you need to load images dynamically, if node.js can access a list of images, you can generate html dynamically (using expression or jade views) with correct html field instead of javascript.

What can you do:



In node js:

var express = require('express'),
    app = express();

function execute () {
    return 'Html stuff to load the image';
}

app.get('/', function (res, req) {
    var html_begin = '<head></head><body>',
        html_end = '</body>';

    res.send(html_begin + execute() + html_end);
});

      

Thus, the client receives

<head>
</head>
<body>
    Html stuff to load the image
</body>

      

But you can just tell node.js to execute something on the page before submitting.

+1


source







All Articles