最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascripthtml in gitlab wiki page? - Stack Overflow

programmeradmin0浏览0评论

I'm afraid I don't really have an idea how to do this - I want to use variables in a Gitlab Wiki page. is this possible at all using html? Can I run scripts on a page?

For example, this question on using a javascript variable in html - would something like this be possible?

For my specific example, I want a page with a table where the first column is numbers, and I want to take the largest value and display it at the top of the page. So for example the table might have rows like:

1   X
22  Y
15  Z

So at the top of the page I would display "largest number is 22". Does this make sense?

I'm afraid I don't really have an idea how to do this - I want to use variables in a Gitlab Wiki page. is this possible at all using html? Can I run scripts on a page?

For example, this question on using a javascript variable in html - would something like this be possible?

For my specific example, I want a page with a table where the first column is numbers, and I want to take the largest value and display it at the top of the page. So for example the table might have rows like:

1   X
22  Y
15  Z

So at the top of the page I would display "largest number is 22". Does this make sense?

Share Improve this question asked Dec 5, 2019 at 21:43 sw_buddysw_buddy 1251 silver badge9 bronze badges 4
  • 1 You cannot have a script in your Wikipage, since they sanitize the HTML (See what they allow here). To do what you want, you could generate that page in Gitlab-CI as part of your project's deploy pipeline, using whatever rendering engine and putting that variable in there, and update it automatically using Gitlab's Wiki APIs – blex Commented Dec 5, 2019 at 21:54
  • @blex shouldn't your ment be an answer? – Ulysse BN Commented Dec 5, 2019 at 22:23
  • 1 @UlysseBN I feel like an answer should have more details of implementation. I don't have time to do that right now, maybe someone else will :) – blex Commented Dec 5, 2019 at 22:33
  • I finally took some time to do it. Hope this helps – blex Commented Dec 6, 2019 at 1:05
Add a ment  | 

1 Answer 1

Reset to default 9

You cannot have a script in your Wikipage, since they sanitize the HTML (See what they allow here). To do what you want, you could generate that page in Gitlab-CI as part of your project's deploy pipeline, using whatever rendering engine and putting that variable in there, and update it automatically using Gitlab's Wiki APIs.

How to

I created a demo NodeJS project here, which, when I push to the master branch, auto-generates the Wiki pages. You can look at the code to see how it works.

This example app exposes a function to get a list of fruit and quantities in stock. We'll automatically add that data in the Wiki.

Step 1 - Create page templates

You can add templates to your project for your Wiki pages. In my example, I used MustacheJS. And I put everything in a wiki folder (see folder structure at the end of step 5). Your template can look something like this:

wiki/templates/home.mst

# Wele to the supermarket

The biggest quantity we have in stock is for **{{topProduct.label}}**,
with a total of **{{topProduct.stock}}**!

|   Fruit   |   Quantity   |
|-----------|--------------|
{{#inventory}}
| {{label}} | {{stock}} |
{{/inventory}}

In this example, the data will e from the project code itself.

Step 2 - Build your pages

Note: The scripts I wrote as a demo use axios to make requests to the Gitlab API, mustache to render the pages, and qs to format the data as a query string before posting it to Gitlab. You can use other ones or install them as dev dependencies: npm install --save-dev axios mustache qs

Create a js file which will get the data from your app, and render the templates into a build directory. Something like this:

wiki/build.js

const fs = require('fs');
const Mustache = require('mustache');
const myApp = require('../src/index.js');
const inventory = myApp.getInventory();

// Get the Mustache template
const homeTemplate = fs.readFileSync(__dirname + '/templates/home.mst', 'utf-8');

// Get the fruit with the highest quantity
const topProduct = inventory.reduce((acc, curr) => {
  if (acc === null || curr.stock > acc.stock) {
    return curr;
  } else {
    return acc;
  }
}, null);

// Render the page using your variables
const homeContent = Mustache.render(homeTemplate, { inventory, topProduct });

// Write the file in a build directory
const buildDir = __dirname + '/../build';
if (!fs.existsSync(buildDir)) {
  fs.mkdirSync(buildDir);
}

fs.writeFileSync(buildDir + '/home.md', homeContent);

And in your package.json, add a mand to run that script:

"scripts": {
    // ...
    "wiki:build": "node wiki/build.js"
  }

Step 3 - Deploy your Wiki pages

Create a script which will upload the pages to your Wiki. This may work as-is without much modification, if you're also using NodeJS.

wiki/deploy.js

const fs = require('fs');
const Axios = require('axios');
const qs = require('qs');

const config = {
  gitlabBaseUrl: 'https://gitlab.', // Update this if you're on a private Gitlab
  projectId: process.env.CI_PROJECT_ID, // Provided by Gitlab-CI
  privateToken: process.env.WIKI_DEPLOY_TOKEN, // Added through Gitlab interface
  buildDir: __dirname + '/../build'
};

const axios = Axios.create({
  baseURL: config.gitlabBaseUrl,
  headers: { 'Private-Token': config.privateToken, Accept: 'application/json' }
});

(async function deploy() {
  const existingPages = await getExistingWikiPages();
  const updatedPages = getUpdatedPages();
  // Pages which existed but are no longer in the build (obsolete)
  const pagesToDelete = existingPages.filter(p1 => updatedPages.every(p2 => p2.slug !== p1.slug));
  // Pages which didn't exist before
  const pagesToCreate = updatedPages.filter(p1 => existingPages.every(p2 => p2.slug !== p1.slug));
  // Pages which already exist
  const pagesToUpdate = updatedPages.filter(p1 => existingPages.some(p2 => p2.slug === p1.slug));

  console.log(
    `Found ${pagesToDelete.length} pages to delete, ${pagesToCreate.length} pages to create, ${pagesToUpdate.length} pages to update.`
  );
  for (let page of pagesToDelete) {
    await deletePage(page);
  }
  for (let page of pagesToCreate) {
    await createPage(page);
  }
  for (let page of pagesToUpdate) {
    await updatePage(page);
  }
  console.log('Deploy plete!');
})();

function getExistingWikiPages() {
  return axios.get(`/api/v4/projects/${config.projectId}/wikis`).then(res => res.data);
}

function getUpdatedPages() {
  const files = fs.readdirSync(config.buildDir);
  return files.map(file => {
    const name = file // Remove the file extension
      .split('.')
      .slice(0, -1)
      .join('.');
    return {
      format: 'markdown', // You could make this depend on the file extension
      slug: name,
      title: name,
      content: fs.readFileSync(`${config.buildDir}/${file}`, 'utf-8')
    };
  });
}

function deletePage(page) {
  console.log(`Deleting ${page.slug}...`);
  return axios.delete(`/api/v4/projects/${config.projectId}/wikis/${page.slug}`);
}

function createPage(page) {
  console.log(`Creating ${page.slug}...`);
  return axios.post(`/api/v4/projects/${config.projectId}/wikis`, qs.stringify(page));
}

function updatePage(page) {
  console.log(`Updating ${page.slug}...`);
  return axios.put(`/api/v4/projects/${config.projectId}/wikis/${page.slug}`, qs.stringify(page));
}

In the config at the top, you need to specify which URL your Gitlab is using. CI_PROJECT_ID will be provided by Gitlab-CI itself as an environment variable. WIKI_DEPLOY_TOKEN, however, will not. Set it up in step 4.

And in your package.json, add a mand to run that script:

"scripts": {
    // ...
    "wiki:build": "node wiki/build.js",
    "wiki:deploy": "node wiki/deploy.js"
  }

Note: This example will delete obsolete pages, and update or create new ones depending on files it finds in the build folder and the ones the Wiki already contains. If you want to have attachments as well (images), you'll need to make use of this API also.

Step 4 - Setup a private token WIKI_DEPLOY_TOKEN

For this, you'll need to click on your profile picture at the top right corner > Settings. Then in the left menu, Access Tokens, and create a token with the api scope. The name does not matter. Copy this token now, since it will only be shown once.

Then, go to your project. In the menu on the left, click Settings > CI/CD. Expand the Variables section, and use the previously copied token to create a variable called WIKI_DEPLOY_TOKEN, make it Masked so that it does not appear in any logs, and Save variables:

This will make that token available only in your pipelines, as an environment variable.

Step 5 - Create your pipeline

If you don't already have a pipeline, all you need to do is create a .gitlab-ci.yml file at the root of your project. Declare a generate_wiki stage:

.gitlab-ci.yml

stages:
  # - tests
  # - deploy
  # ...
  - generate_wiki

generate_wiki:
  image: node:10
  stage: generate_wiki
  script:
    - npm install
    - npm run wiki:build  # build the wiki in a directory
    - npm run wiki:deploy # update it in Gitlab
  only:
    - master # Only when merging or pushing to master branch


# ... rest of your pipeline ...

As you can see, we use the mands wiki:build and wiki:deploy declared in steps 2 and 3.

Now, your project structure should look something like this:

/
├───src
│    └── index.js
├───wiki
│    ├── templates
│    │    └── home.mst
│    ├── build.js
│    └── deploy.js
├── .gitlab-ci.yml
└── package.json

Step 6 - Push to master, and enjoy the magic

After pushing, if everything went right, you can click on CI/CD in the left menu, and you should see your pipeline running:

If you click on the little circle, you should see the logs:

And if you go to your Wiki pages, they should be up to date, automagically:

发布评论

评论列表(0)

  1. 暂无评论