Uploaded image for project: '{RETIRED} CKEditor Integration'
  1. {RETIRED} CKEditor Integration
  2. CKEDITOR-316

Document translations are created when uploading a file from the wysiwyg in a multilanguage wiki

Details

    • Bug
    • Resolution: Fixed
    • Major
    • 1.39
    • 1.38
    • None
    • None
    • multilanguage
    • Easy

    Description

      Steps to reproduce:

      • set the wiki multilanguage in administration, with english default language and available languages english and french
      • set the current langage to french (by adding ?language=fr, for example, at the end of the link)
      • navigate to the Sandbox page
      • create a new page (non-terminal, blank page), using the standard create page button
      • in the wysiwyg editor that is displayed for the newly created page, without saving the page, upload a file to the page from the create link dialog as follows:
        • click the link button in the editor toolbar
        • choose "attachment"
        • using the upload tab, upload a new file
        • finalise adding the link: choose a label and confirm
        • note on that in edit mode of this document in the right panels, the language of the document is properly marked as french, as expected.
      • save the page you've just creating

      Expected result:

      • a single translation of the page exists, with default language set to french

      Actual result:

      • two translations of the page exist: the original document, with default language empty, and a french translation. The content that was introduced in the wysiwyg editor on creation is now the content of the french translation, not of the original document

      See attached screenshots for visual step-by-step.
      The version of the wysiwyg editor installed is "CKEditor Integration 1.20".

      Attachments

        1. Selection_150.png
          Selection_150.png
          27 kB
        2. Selection_152.png
          Selection_152.png
          23 kB
        3. Selection_153.png
          Selection_153.png
          18 kB
        4. Selection_155.png
          Selection_155.png
          14 kB
        5. Selection_156.png
          Selection_156.png
          18 kB
        6. Selection_157.png
          Selection_157.png
          35 kB
        7. Selection_158.png
          Selection_158.png
          24 kB
        8. Selection_149.png
          Selection_149.png
          90 kB
        9. Selection_151.png
          Selection_151.png
          63 kB

        Issue Links

          Activity

            [CKEDITOR-316] Document translations are created when uploading a file from the wysiwyg in a multilanguage wiki

            Should be fixed if you have XWiki 11.9+

            mflorea Marius Dumitru Florea added a comment - Should be fixed if you have XWiki 11.9+
            lucaa Anca Luca added a comment -

            Added link to XWIKI-15159 since apparently, as mflorea mentioned, if XWIKI-15159 is done, we could also fix this issue.

            lucaa Anca Luca added a comment - Added link to XWIKI-15159 since apparently, as mflorea mentioned, if XWIKI-15159 is done, we could also fix this issue.

            Default locale is only used to indicate what is the actual language when looking at the default translation of the document. It's really supposed to have much meaning in other context.

            But if you want to be extra safe you could make Document#setDefaultTranslation(Locale) do something only if getLocale() is Locale.Root and isNew() is true.

            tmortagne Thomas Mortagne added a comment - Default locale is only used to indicate what is the actual language when looking at the default translation of the document. It's really supposed to have much meaning in other context. But if you want to be extra safe you could make Document#setDefaultTranslation(Locale) do something only if getLocale() is Locale.Root and isNew() is true.

            Setting the default locale on translations wouldn't cause problems? You could end up with translations of the same (default) document that have different default locale (possibly different than the default locale set on the default translation).

            mflorea Marius Dumitru Florea added a comment - Setting the default locale on translations wouldn't cause problems? You could end up with translations of the same (default) document that have different default locale (possibly different than the default locale set on the default translation).
            lucaa Anca Luca added a comment -

            or add some scripting API to create a document with a default locale different than the root locale.

            I saw a discussion recently about this API, but I don't remember where, and the conclusion was the same, that it should be there.

            lucaa Anca Luca added a comment - or add some scripting API to create a document with a default locale different than the root locale. I saw a discussion recently about this API, but I don't remember where, and the conclusion was the same, that it should be there.

            or add some scripting API to create a document with a default locale different than the root locale.

            There is no reason for it to be dangerous IMO. Was probably just forgotten.

            tmortagne Thomas Mortagne added a comment - or add some scripting API to create a document with a default locale different than the root locale. There is no reason for it to be dangerous IMO. Was probably just forgotten.

            The UploadAction has this code (from XWIKI-9988):

            // It is possible to submit an attachment to a new document (the WYSIWYG content editor does it for instance).
            // Let's make sure the new document is created with the right (default) language.
            if (doc.isNew()) {
                doc.setLocale(Locale.ROOT);
                if (doc.getDefaultLocale() == Locale.ROOT) {
                    doc.setDefaultLocale(
                        LocaleUtils.toLocale(context.getWiki().getLanguagePreference(context), Locale.ROOT));
                }
            }
            

            which make sure the new document is saved with the right default locale. Unfortunately CKEditor can't use the UploadAction because it needs a custom response. It uses FileUploader instead which doesn't set the default locale because, well, it can't. There's no public scripting API to set the default locale. Basically ATM we can't create from Velocity (without PR) a document whose default locale is not the root locale. We can create with Velocity a translation for a given locale, but not the default document in that locale.

            Note that ATM there are 3 actions that set the default locale on the document that is put on the context (saving this context document would create the default document with the right locale):

            • Save
            • Upload
            • Edit

            CKEditor Integration calls the FileUploader page using the Get action. I can't use the Upload action because I need to execute some script before the file is uploaded. I can't use the Save action because I can't execute a Velocity script after the document is saved (it does a redirect). And I can't use the Edit action because of

            java.lang.NullPointerException
            	at java.lang.Class.isAssignableFrom(Native Method)
            	at org.apache.struts.util.RequestUtils.rationalizeMultipleFileProperty(RequestUtils.java:506)
            	at org.apache.struts.util.RequestUtils.populate(RequestUtils.java:459)
            	at com.xpn.xwiki.web.XWikiRequestProcessor.processPopulate(XWikiRequestProcessor.java:157)
            	at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:194)
            	at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
            	at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:462)
            	at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
            	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
            	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:860)
            	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1650)
            	at com.xpn.xwiki.web.ActionFilter.doFilter(ActionFilter.java:112)
            	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
            	at org.xwiki.wysiwyg.filter.ConversionFilter.doFilter(ConversionFilter.java:127)
            	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
            	at org.xwiki.container.servlet.filters.internal.SetHTTPHeaderFilter.doFilter(SetHTTPHeaderFilter.java:63)
            	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
            	at org.xwiki.container.servlet.filters.internal.SavedRequestRestorerFilter.doFilter(SavedRequestRestorerFilter.java:208)
            	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
            	at org.xwiki.container.servlet.filters.internal.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:111)
            	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
            	at org.xwiki.resource.servlet.RoutingFilter.doFilter(RoutingFilter.java:134)
            	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1629)
            	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:533)
            	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
            	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
            	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
            	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190)
            	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595)
            	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188)
            	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1253)
            	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168)
            	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473)
            	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564)
            	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166)
            	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1155)
            	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
            	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:219)
            	at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126)
            	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
            	at org.eclipse.jetty.server.Server.handle(Server.java:530)
            	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:347)
            	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:256)
            	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
            	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
            	at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
            	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:247)
            	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:140)
            	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
            	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:382)
            	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:708)
            	at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:626)
            	at java.lang.Thread.run(Thread.java:748)
            

            which seems to be a Struts bug that was fixed in 1.3.10.1, a version that in the end has not been released. We're using 1.3.10.

            I think the best is to:

            • either make sure the context document on the Get action has the right default locale set (like it has on Edit/Save/Upload)
            • or add some scripting API to create a document with a default locale different than the root locale.
            mflorea Marius Dumitru Florea added a comment - The UploadAction has this code (from XWIKI-9988 ): // It is possible to submit an attachment to a new document (the WYSIWYG content editor does it for instance). // Let's make sure the new document is created with the right (default) language. if (doc.isNew()) { doc.setLocale(Locale.ROOT); if (doc.getDefaultLocale() == Locale.ROOT) { doc.setDefaultLocale( LocaleUtils.toLocale(context.getWiki().getLanguagePreference(context), Locale.ROOT)); } } which make sure the new document is saved with the right default locale. Unfortunately CKEditor can't use the UploadAction because it needs a custom response. It uses FileUploader instead which doesn't set the default locale because, well, it can't. There's no public scripting API to set the default locale. Basically ATM we can't create from Velocity (without PR) a document whose default locale is not the root locale. We can create with Velocity a translation for a given locale, but not the default document in that locale. Note that ATM there are 3 actions that set the default locale on the document that is put on the context (saving this context document would create the default document with the right locale): Save Upload Edit CKEditor Integration calls the FileUploader page using the Get action. I can't use the Upload action because I need to execute some script before the file is uploaded. I can't use the Save action because I can't execute a Velocity script after the document is saved (it does a redirect). And I can't use the Edit action because of java.lang.NullPointerException at java.lang.Class.isAssignableFrom(Native Method) at org.apache.struts.util.RequestUtils.rationalizeMultipleFileProperty(RequestUtils.java:506) at org.apache.struts.util.RequestUtils.populate(RequestUtils.java:459) at com.xpn.xwiki.web.XWikiRequestProcessor.processPopulate(XWikiRequestProcessor.java:157) at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:194) at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913) at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:462) at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:860) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1650) at com.xpn.xwiki.web.ActionFilter.doFilter(ActionFilter.java:112) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) at org.xwiki.wysiwyg.filter.ConversionFilter.doFilter(ConversionFilter.java:127) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) at org.xwiki.container.servlet.filters.internal.SetHTTPHeaderFilter.doFilter(SetHTTPHeaderFilter.java:63) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) at org.xwiki.container.servlet.filters.internal.SavedRequestRestorerFilter.doFilter(SavedRequestRestorerFilter.java:208) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) at org.xwiki.container.servlet.filters.internal.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:111) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) at org.xwiki.resource.servlet.RoutingFilter.doFilter(RoutingFilter.java:134) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1629) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:533) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595) at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1253) at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564) at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1155) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:219) at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) at org.eclipse.jetty.server.Server.handle(Server.java:530) at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:347) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:256) at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279) at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102) at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:247) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:140) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:382) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:708) at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:626) at java.lang.Thread.run(Thread.java:748) which seems to be a Struts bug that was fixed in 1.3.10.1, a version that in the end has not been released. We're using 1.3.10. I think the best is to: either make sure the context document on the Get action has the right default locale set (like it has on Edit/Save/Upload) or add some scripting API to create a document with a default locale different than the root locale.

            People

              mflorea Marius Dumitru Florea
              lucaa Anca Luca
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: