SDK6 中的 Confluence 宏开发

Confluence Macro Development in SDK6

我有点沮丧。我正在尝试为融合开发一个简单的 "hello world" 宏。但是所有教程都不再适用于实际的 SDK6。

我试过这个教程:

https://developer.atlassian.com/confdev/tutorials/macro-tutorials-for-confluence/creating-a-new-confluence-macro#CreatingaNewConfluenceMacro-Step1.Createthepluginprojectandtrimtheskeleton

但是正如您看到的文章所讨论的那样,它不再正常工作了。我认为一些元素已经用 SDK6 进行了修改,并且教程不再是最新的。

我在 confluence-forum 上寻求帮助,但没有成功。有几个post围绕这个问题没有任何解决方案。

问题是,插件/插件在系统管理面板中可见,但我无法在页面上使用宏,而且在宏浏览器中也看不到宏。

现在可以使用了 - 更新

这是我所做的:

1) 下载SDK

我下载了 sdk-installer-6.2.4.exe 并安装了它

2) 创建新插件

我通过输入

创建了一个新的 confluence 插件
 atlas-create-confluence-plugin

使用以下组和工件 ID

groupid    : com.example.plugins.tutorial.confluence
artifactid : tutorial-confluence-macro-demo
version    : 1.0-SNAPSHOT
package    : package    com.example.plugins.tutorial.confluence

3) 创建 eclipse 项目

然后我通过输入

创建了eclipse项目
atlas-mvn eclipse:eclipse

4) 修改pom.xml

我修改了 pom.xml 就像 ppasler 在他的回答中解释的那样。我还修改了companyname和version,以便在confluence中查看,修改是否有效果。 pom 看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example.plugins.tutorial.confluence</groupId>
    <artifactId>tutorial-confluence-macro-demo</artifactId>
    <version>4.4-SNAPSHOT</version>

    <organization>
        <name>Hauke Company</name>
        <url>http://www.example.com/</url>
    </organization>

    <name>tutorial-confluence-macro-demo</name>
    <description>This is the com.example.plugins.tutorial.confluence:tutorial-confluence-macro-demo plugin for Atlassian Confluence.</description>
    <packaging>atlassian-plugin</packaging>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.atlassian.confluence</groupId>
            <artifactId>confluence</artifactId>
            <version>${confluence.version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>com.atlassian.plugin</groupId>
            <artifactId>atlassian-spring-scanner-annotation</artifactId>
            <version>${atlassian.spring.scanner.version}</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>com.atlassian.plugin</groupId>
            <artifactId>atlassian-spring-scanner-runtime</artifactId>
            <version>${atlassian.spring.scanner.version}</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
            <scope>provided</scope>
        </dependency>

        <!-- WIRED TEST RUNNER DEPENDENCIES -->
        <dependency>
            <groupId>com.atlassian.plugins</groupId>
            <artifactId>atlassian-plugins-osgi-testrunner</artifactId>
            <version>${plugin.testrunner.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>jsr311-api</artifactId>
            <version>1.1.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.2.2-atlassian-1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>com.atlassian.maven.plugins</groupId>
                <artifactId>maven-confluence-plugin</artifactId>
                <version>${amps.version}</version>
                <extensions>true</extensions>
                <configuration>
                    <productVersion>${confluence.version}</productVersion>
                    <productDataVersion>${confluence.data.version}</productDataVersion>
                    <enableQuickReload>true</enableQuickReload>
                    <enableFastdev>false</enableFastdev>

                    <!-- See here for an explanation of default instructions: -->
                    <!-- https://developer.atlassian.com/docs/advanced-topics/configuration-of-instructions-in-atlassian-plugins -->
                    <instructions>
                        <Atlassian-Plugin-Key>${atlassian.plugin.key}</Atlassian-Plugin-Key>

                        <!-- Add package to export here -->
                        <Export-Package>
                            com.example.plugins.tutorial.confluence.api,
                        </Export-Package>

                        <!-- Add package import here -->
                        <Import-Package>
                            org.springframework.osgi.*;resolution:="optional",
                            org.eclipse.gemini.blueprint.*;resolution:="optional",
                            *
                        </Import-Package>

                        <!-- Ensure plugin is spring powered -->
                        <Spring-Context>*</Spring-Context>
                    </instructions>
                </configuration>
            </plugin>

            <plugin>
                <groupId>com.atlassian.plugin</groupId>
                <artifactId>atlassian-spring-scanner-maven-plugin</artifactId>
                <version>1.2.6</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>atlassian-spring-scanner</goal>
                        </goals>
                        <phase>process-classes</phase>
                    </execution>
                </executions>
                <configuration>
                    <scannedDependencies>
                        <dependency>
                            <groupId>com.atlassian.plugin</groupId>
                            <artifactId>atlassian-spring-scanner-external-jar</artifactId>
                        </dependency>
                    </scannedDependencies>
                    <verbose>false</verbose>
                </configuration>
            </plugin>
        </plugins>
    </build>


    <properties>
    <confluence.version>5.9.7</confluence.version>
    <confluence.data.version>5.9.7</confluence.data.version>
    <amps.version>6.2.4</amps.version>
    <plugin.testrunner.version>1.1.1</plugin.testrunner.version>
     <atlassian.spring.scanner.version>1.2.6</atlassian.spring.scanner.version>
    </properties>
<!--
    <properties>
        <confluence.version>5.9.7</confluence.version>
        <confluence.data.version>5.9.7</confluence.data.version>
        <amps.version>6.2.3</amps.version>
        <plugin.testrunner.version>1.2.3</plugin.testrunner.version>
        <atlassian.spring.scanner.version>1.2.6</atlassian.spring.scanner.version>
        <atlassian.plugin.key>${project.groupId}.${project.artifactId}</atlassian.plugin.key>
    </properties>
-->
</project>

5) 开始日食

我将项目导入到 Eclilpse

Version: Mars.1 Release (4.5.1)
Build id: 20150924-1200
Java JDK 1.8.0_60

6) ExampleMacro class 创建

我创建了 class "ExampleMacro"

package com.example.plugins.tutorial.confluence;

import com.atlassian.confluence.content.render.xhtml.ConversionContext;
import com.atlassian.confluence.content.render.xhtml.XhtmlException;
import com.atlassian.confluence.macro.Macro;
import com.atlassian.confluence.macro.MacroExecutionException;
import com.atlassian.confluence.xhtml.api.MacroDefinition;
import com.atlassian.confluence.xhtml.api.MacroDefinitionHandler;
import com.atlassian.confluence.xhtml.api.XhtmlContent;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ExampleMacro implements Macro
{
    private final XhtmlContent xhtmlUtils;

    public ExampleMacro(XhtmlContent xhtmlUtils)
    {
        this.xhtmlUtils = xhtmlUtils;
    }

    @Override
    public String execute(Map<String, String> parameters, String bodyContent, ConversionContext conversionContext) throws MacroExecutionException
    {
        String body = conversionContext.getEntity().getBodyAsString();

        final List<MacroDefinition> macros = new ArrayList<MacroDefinition>();

        try
        {
            xhtmlUtils.handleMacroDefinitions(body, conversionContext, new MacroDefinitionHandler()
            {
                @Override
                public void handle(MacroDefinition macroDefinition)
                {
                    macros.add(macroDefinition);
                }
            });
        }
        catch (XhtmlException e)
        {
            throw new MacroExecutionException(e);
        }

        StringBuilder builder = new StringBuilder();
        builder.append("<p>");
        if (!macros.isEmpty())
        {
            builder.append("<table width=\"50%\">");
            builder.append("<tr><th>Macro Name</th><th>Has Body?</th></tr>");
            for (MacroDefinition defn : macros)
            {
                builder.append("<tr>");
                builder.append("<td>").append(defn.getName()).append("</td><td>").append(defn.hasBody()).append("</td>");
                builder.append("</tr>");
            }
            builder.append("</table>");
        }
        else
        {
            builder.append("You've done built yourself a macro! Nice work.");
        }
        builder.append("</p>");

        return builder.toString();

    }

    @Override
    public BodyType getBodyType()
    {
        return BodyType.NONE;
    }

    @Override
    public OutputType getOutputType()
    {
        return OutputType.BLOCK;
    }
}

7) 修改了atlassian-plugin.xml文件

<atlassian-plugin key="${atlassian.plugin.key}" name="${project.name}" plugins-version="2">
    <plugin-info>
        <description>${project.description}</description>
        <version>${project.version}</version>
        <vendor name="${project.organization.name}" url="${project.organization.url}" />
        <param name="plugin-icon">images/pluginIcon.png</param>
        <param name="plugin-logo">images/pluginLogo.png</param>
    </plugin-info>

    <!-- add our i18n resource -->
    <resource type="i18n" name="i18n" location="tutorial-confluence-macro-demo"/>

    <xhtml-macro name="tutorial-confluence-macro-demo" class="com.example.plugins.tutorial.confluence.ExampleMacro" key="my-macro">
        <parameters/>
    </xhtml-macro>

    <!-- add our web resources -->
    <web-resource key="tutorial-confluence-macro-demo-resources" name="tutorial-confluence-macro-demo Web Resources">
        <dependency>com.atlassian.auiplugin:ajs</dependency>

        <resource type="download" name="tutorial-confluence-macro-demo.css" location="/css/tutorial-confluence-macro-demo.css"/>
        <resource type="download" name="tutorial-confluence-macro-demo.js" location="/js/tutorial-confluence-macro-demo.js"/>
        <resource type="download" name="images/" location="/images"/>

        <context>tutorial-confluence-macro-demo</context>
    </web-resource>

</atlassian-plugin>

8) 开始汇合

atlas-clean
atlas-package
atlas-debug

9) 登录 confluence

这里是 confluence 管理页面的结果

现在我也可以在宏浏览器中找到它并且它可以工作

谢谢 豪克

使用 atlassian 插件真的很令人沮丧:)

我检查了宏 source code from bitbucket 并在 pom

中进行了以下更改
<properties>
    <confluence.version>5.9.7</confluence.version>
    <confluence.data.version>5.9.7</confluence.data.version>
    <amps.version>6.2.4</amps.version>
    <plugin.testrunner.version>1.1.1</plugin.testrunner.version>
</properties>

然后运行

atlas-clean
atlas-package
atlas-debug

之后我可以使用宏浏览器添加宏(使用 confluence 5.8.6 实例)。

遗憾的是我没有时间检查源代码和教程之间的区别,但我的解决方案会给你一个尝试新东西的工作状态。

您的图像正在显示 ${atlassian.plugin.key}。您的宏插件是否正常工作。它显示在宏浏览器中,但您可以在页面上使用它吗?我还注意到您在 pom.xml.

中注释掉了 atlassian.plugin.key

The use of <Atlassian-Plugin-Key> here tells the plugin system that you are a transformerless plugin and that it should skip the slow transformation step. This is VERY IMPORTANT. Without this entry in your Manifest, the plugin system will try to transform your plugin, and you will lose the load time speed benefits. You are also likely to see Spring-related errors. Do not forget to specify this entry.

参见:Atlassian Spring Scanner

导入组件的新方法是使用 Atlassian Spring Scanner。看起来您通过注释掉 atlassian.plugin.key.

混合了导入组件的新旧方式

查看:Build a Macro Add-on

Confluence 示例:Confluence Add-on Development examples