#tl;dr

The Workbench packages are out-of-date for 11.1 and the whole system is not configured to easily work from Mathematica using a structure differing from the standard `/language/ref` URL structure or things like that.

It's a massive pain to make it all work, but in the end we can get half-way decent, largely-functional documentation pages like [this](https://www.wolframcloud.com/objects/b3m2a1.paclets/reference/BTools/ref/GenerateHTMLDocumentation.html)

---
###Shameless Self-Promotion:

I added this system + auto-generation into my [DocGen package](https://github.com/b3m2a1/mathematica-BTools/blob/master/Packages/DocGen.m) letting me build out docs like [this PacletManager documentation](https://www.wolframcloud.com/objects/b3m2a1.paclets/reference/PacletManager/guide/PacletManager.html) using just the following:
   

    (* Build out the docs from the contexts*)
    GenerateDocumentation[
     {
      "PacletTools`",
      "PacletManager`",
      "DataPaclets`"
      },
     "Install" -> True
     ]
    
    (* Generate HTML and web deploy from paclets *)
    GenerateHTMLDocumentation[
     PacletFind[{"*Paclet*", "0"}],
     CloudDeploy -> True
     ]

---

#Full Answer

To automate the entire process takes many tedious steps, but if you don't mind doing things by hand and  follow Frank Martin's guide [here](https://mathematica.stackexchange.com/questions/128597/workbench-2-and-3-documentation-html-build-fails-output-file-test-failed) and don't mind doing things by hand you only really need the first two steps.

### *Copy the packages from Eclipse*

Install Workbench on Eclipse, as described [here](http://support.wolfram.com/kb/27221).

Then find the directory where the documentation packages are stored:

    $eclipsePath = "path/to/Eclipse";
    FileNames["DocumentationBuild", $eclipsePath, \[Infinity]]

Copy `"DocumentationTools"`, `"DocumentationBuild"` and `"Transmogrify"` to `FileNameJoin@{$UserBaseDirectory, "Applications"}`, then delete the `MenuSetup` that's in `"DocumentationTools"` (just for safety)

### *11.1 to 11.0 Down Conversion*

The heart of my initial problem was that the build tools I copied over from Workbench were out of date, so I got around that by down-converting my notebooks to 11.0 style before passing them through `ExportWebPage`.

Here's the code I used for that:

    webExportNotebookPrep[nb_] :=
     DeleteCases[
       Visible -> False
       ]@
      ReplaceRepeated[
       nb, {
        Cell[TextData[{c_, ___}], "ObjectNameGrid", ___] :>
         c,
        Cell[_, "NotesThumbnails" | "ObjectNameTranslation", ___] :>
         Sequence @@ {},
        Cell[TextData[{Cell[BoxData[_DynamicBox], ___], e__}],
          t : "NotesSection" | "PrimaryExamplesSection" |
            "ExampleSection" | "ExampleSubsection", r___] :>
         Cell[TextData[e], t, r],
        DynamicBox[e : If[$VersionNumber < _, __], ___] :>
         e,
        Cell[TextData[s_String], r___] :> Cell[s, r],
        t : TemplateBox[{_, _String}, ___] :>
         refLinkRewind[t],
        TagBox[a : ActionMenuBox[_FrameBox, ___], 
          MouseAppearanceTag["LinkHand"]] :>
         a,
        Cell[
          TextData[{t_, " ",
            Cell[
             BoxData[
              GraphicsBox[{{
                 {
                  _GrayLevel, _Thickness,
                  LineBox[{{-1.8, 0.5}, {0, 0}, {1.8, 0.5}}]
                  }
                 }},
               ___
               ]
              ],
             ___
             ]
            }],
          ___
          ] :>
         InterpretationBox[
          Cell[
           TextData[{
             t,
             StyleBox[" \[FilledDownTriangle]", "AnchorBarArrow",
              StripOnInput -> False]
             }]],
          TextCell[
           Row[{"See Also", 
             Style[" \[FilledDownTriangle]", "AnchorBarArrow"]}]
           ]
          ]
        }
       ]

With those corrections we can get out raw HTML, but there are still many issue to correct, which are largely documented by Frank Martin, which I dealt with programmatically.

---

### *File Post-Processing*

Some resources we want to link do built for a specific directory layout, corrupted or inadequate.

We'll write a general purpose function for handling this post-processing.

    webExportPostProcessSingleReplacements // Clear;
    webExportPostProcessMultiReplacements // Clear;

    (* MultiReplacements *)
    
    webExportPostProcessMultiReplacements[strip_, res_, url_] :=
      With[{
        trimmedRes =
         StringTrim[res, "/" ~~ EndOfString],
        paddedRes =
         StringTrim[res, "/" ~~ EndOfString] <> "/"
        },
       Flatten@{(*
         (* Insert prototype into loaded JS characters *)
         
         "<script src='javascript/common.js' type='text/javascript'></script>\n"<>
    
              "<script src='javascript/jquery.js' \
    type='text/javascript'></script>\n"->
         
         "<script src='javascript/jquery.js' type='text/javascript'></script>\n"<>
    
              "<script src='javascript/common.js' \
    type='text/javascript'></script>\n",*)
         (* Relink loaded JS and CSS *)
       
           h : ("src" | "href") ~~ "=" ~~ (q : "'" | "\"") ~~ 
           t : "javascript" | "css" ~~ "/" :>
          
          h <> "=" <> q <> URLBuild@{res, t} <> "/",
         h : ("src" | "href") ~~ "=" ~~ (q : "'" | "\"") ~~ "/" ~~ 
           t : "javascript" | "css" ~~ "/" :>
          
          h <> "=" <> q <> URLBuild@{res, t} <> "/",
         "/webMathematica/Resources/Documentation/English/" ->
          paddedRes,
         (* Relink loaded JS and CSS *)
         
         l : ("<link rel=\"stylesheet\" href=\"" ~~
             (paddedRes | "") ~~ 
             "css/reference.css\" />") :>
          
          l <> "\n<link rel=\"stylesheet\" href=\"" <>
           
           URLBuild@{trimmedRes, "css", "clipboard.css"} <> "\" />",
         l : ("<script src=\"" ~~ (paddedRes | "") ~~ 
             "javascript/reference.js\"></script>") :>
          
          "<script src=\"" <>
           URLBuild@{trimmedRes, "javascript",
             "jquery", "core", "1.7.2", "jquery.min.js"} <> "\" /></script>\n" <> l
         }
       ];
    
    (* SingleReplacements *)
    
    webExportPostProcessSingleReplacements[strip_, res_, url_] :=
      With[{
        trimmedRes =
         StringTrim[res, "/" ~~ EndOfString],
        paddedRes =
         StringTrim[res, "/" ~~ EndOfString] <> "/"
        },
       Flatten@{
         Replace[strip, Except[_List | _Rule] -> {}],
         (* Protect true links *)
         
         "http://reference.wolfram.com/language/" ~~
           
           t : "ref" | "guide" | "tutorial" :>
          
          "http://reference.wolfram.com/language/" <> t,
         paddedRes ~~
           t : "ref" | "guide" | "tutorial" :>
          "http://reference.wolfram.com/language/" <> t,
         "/language/" ~~
           t : "ref" | "guide" | "tutorial" :>
          
          URLBuild@{
            "http://reference.wolfram.com/language",
            t
            },
         (* Patch intra site links *)
         
         "/language/" ~~ param : Except[WhitespaceCharacter] ... ~~
           
           t : "ref" | "guide" | "tutorial" ~~
           
           doc : Except[WhitespaceCharacter | "\""] ... :>
          URLBuild@
           DeleteCases[{url, StringTrim[param, "/"], t, StringTrim[doc, "/"]}, ""],
         "http://reference.wolfram.com/language" ->
          url,
         (* Patch resource directory *)
         "/common/" ->
          paddedRes,
         (* Patch jquery version *)
         
         "jquery/core/1.6.1" ->
          "jquery/core/1.7.2",
         (* Patch mathematicaImages to work a resource base *)
         
         "\"../" ~~ i : "images/mathematicaImages" :>
          
          "\"" <> URLBuild@{trimmedRes, i},
         "\"" ~~ i : "images/mathematicaImages" :>
          
          "\"" <> URLBuild@{trimmedRes, i},
         "\"/mathematicaImages" ->
          
          "\"" <> URLBuild@{trimmedRes, "images", "mathematicaImages"},
         (* Patch includes to work a resource base *)
         
         "\"/includes" ->
          "\"" <> URLBuild@{trimmedRes, "includes"},
         (* Downconvert 2013 resources to the standard resoruce base *)
         
         "/2013/" ->
          paddedRes,
         (* Delete duplicates *)
         (l : 
             "<script src=\"" <>
              
              URLBuild@{trimmedRes, "javascript", "jquery.min.js"} <> 
              "\" /></script>\n") .. :>
          l,
         (l : "<link rel=\"stylesheet\" href=\"" <>
              
              URLBuild@{trimmedRes, "css", "clipboard.css"} <> "\" />\n") .. :>
      
              l
         }
       ];
    
    (* Extension specific replacements *)
    
    webExportPostProcessSingleReplacements["css", strip_, res_, url_] :=
      {
       (* Add clipboard styles into reference.css *)
       
       t : "/*##############################\n\tCOLORS" :>
        "/* clipboard styles */\n@import url('clipboard.css');\n" <> t
       };
    
    webExportPostProcessSingleReplacements["js", strip_, res_, url_] :=
      {
       (* Clean up dangerous characters while protecting whitespace *)
       
       w : WhitespaceCharacter :> w,
       _?(Not@*PrintableASCIIQ) -> ""	
       };
    
    webExportPostProcessMultiReplacements[_, _, _, _] :=
      {
       };
    webExportPostProcessSingleReplacements[_, _, _, _] :=
      {
       };
    
    (* Main *)
    
    webExportPostProcess // Clear
    
    Options[webExportPostProcess] = {
       "ResourceBase" -> Automatic,
       "URLBase" -> Automatic,
       "StripExtensions" -> Automatic
       };
    webExportPostProcess[file_String?FileExistsQ, ops : OptionsPattern[]] :=
      
      With[{
        s = ReadString[file],
        ext = Replace[OptionValue["StripExtensions"], 
          Automatic -> {".en." -> "."}],
        res =
         Replace[OptionValue["ResourceBase"],
          Automatic :>
           URLBuild@
            ConstantArray["..",
             With[{split = FileNameSplit@DirectoryName@file},
              SelectFirst[Range[Length@split],
               DirectoryQ@FileNameJoin@
                  Append[
                   Drop[split, -#],
                   "javascript"
                   ] &,
               1
               ]
              ]
             ]
          ],
        url =
         Replace[OptionValue["URLBase"],
          Automatic :>
           URLBuild@
            ConstantArray["..",
             With[{split = FileNameSplit@DirectoryName@file},
              SelectFirst[Range[Length@split],
               DirectoryQ@FileNameJoin@
                  Append[
                   Drop[split, -#],
                   "javascript"
                   ] &,
               1
               ]
              ]
             ]
          ]
        },
       If[StringQ[s],
        DeleteFile[file];
        Export[
         StringReplace[file,
          Replace[OptionValue["StripExtensions"], Except[_List | _Rule] -> {}]
          ],
         FixedPoint[#, s, 6] &@
           StringReplace@Join[
             webExportPostProcessMultiReplacements[
              ext,
              res,
              url
              ],
             webExportPostProcessMultiReplacements[
              FileExtension[file],
              ext,
              res,
              url
              ]
             ] //
          StringReplace@Join[
            webExportPostProcessSingleReplacements[
             ext,
             res,
             url
             ],
            webExportPostProcessSingleReplacements[
             FileExtension[file],
             ext,
             res,
             url
             ]
            ]
         ,
         "Text"
         ],
        file
        ]
       ];
    webExportPostProcess[___] := $Failed

---
### *Resource copying*

Then we'll take jkuczm's resource list to copy from [this answer](https://mathematica.stackexchange.com/questions/131104/how-can-i-build-documentation-using-docbuild-xml-outside-of-the-workbench/131569#131569) and copy each file to the documentation directory with requisite post-processing:

    $webExportAssets :=
      Map[
       <|
         "Drop" -> FileNameDepth[#[[1]]] - FileNameDepth@#[[2]],
         "Files" -> FileNames[#[[3]], #[[1]], \[Infinity]],
         "Insert" -> If[Length@# > 3, #[[4]], Nothing]
         |> &,
       {
        {
         FileNameJoin@{
           DocumentationBuild`Common`$DocumentationBuildDirectory,
           "Internal", "web", "html", "javascript"
           },
         "javascript",
         {
          "*.js"
          }
         },
        {
         FileNameJoin@{
           DocumentationBuild`Common`$DocumentationBuildDirectory,
           "Internal", "web", "html", "css"
           },
         "css",
         {
          "*.css"
          }
         },
        {
         FileNameJoin@{
           DocumentationBuild`Common`$DocumentationBuildDirectory,
           "Internal", "web", "html", "2014", "standard"
           },
         "",
         {
          "*.js", "*.json", "*.css", "*.png", "*.gif", "*.jpg",
          "*.svg", "*.eot", "*.otf", "*.ttf", "*.woff", "*.html"
          }
         },
        {
         FileNameJoin@{
           DocumentationBuild`Common`$DocumentationBuildDirectory,
           "Internal", "web", "html", "2014", "standard"
           },
         "",
         {
          "*.ttf", "*.woff"
          },
         "fonts"
         },
        {
         FileNameJoin@{
           DocumentationBuild`Common`$DocumentationBuildDirectory,
           "Internal", "web", "html", "2014",
           "minimal",
           "javascript"
           },
         "javascript",
         "faster-page-load.js"
         },
        {
         FileNameJoin@{
           DocumentationBuild`Common`$DocumentationBuildDirectory,
           "Internal", "web", "html", "images",
           "mathematicaImages"
           },
         FileNameJoin@{"images", "mathematicaImages"},
         "bullet.gif"
         }
        }
       ];
    
    webExportAssetsCopy[dir : (_String | _File)?DirectoryQ] :=
      
      Block[{d, f},
       Monitor[
        Table[
         With[{depth = a["Drop"], insert = a["Insert"]},
          Table[
           d =
            FileNameJoin@
             Flatten@{dir,
               DirectoryName@FileNameDrop[f, depth],
               insert
               };
           If[! DirectoryQ@d,
            CreateDirectory[d,
             CreateIntermediateDirectories -> True
             ]
            ];
           If[StringMatchQ[FileExtension[#], "css" | "js" | "html"],
              webExportPostProcess[#],
              #
              ] &@
            CopyFile[f,
             FileNameJoin@
              Flatten@{
                d,
                FileNameTake@f
                },
             OverwriteTarget -> True
             ],
           {f, a["Files"]}
           ]
          ],
         {a, $webExportAssets}
         ],
        Internal`LoadingPanel[
         "Copying `` to ``"~TemplateApply~
          {
           f,
           FileNameJoin@
            Flatten@{
              d,
              FileNameTake@f
              }
           }
         ]
        ]
       ];

---
### *HTML Generation*

With all of that in place we can now generate pages that will look right:

    webExportNotebook[file_, nb_, ops___?OptionQ] :=
     
     With[{params = Flatten@{ops}},
      Needs["DocumentationBuild`"];
      Block[{
        DocumentationBuild`Common`PubsEvaluateWithFE =
         Identity,
        DocumentationBuild`Common`Private`PubsStartFrontEnd =
         Identity,
        Print =
         Identity,
        NotebookOpen,
        NotebookPut,
        expFile =
         If[DirectoryQ@file,
          FileNameJoin@Flatten@{
              file,
              URLParse[
               Lookup[params, "URI",
                URLBuild@{
                  "",
                  "DocPage-" <> ToString[RandomInteger[10000]]
                  }
                ],
               "Path"]
              } <> ".html",
          file
          ]
        },
       NotebookOpen[e___] :=
        MathLink`CallFrontEnd[
         FrontEnd`NotebookOpenReturnObject[e, Visible -> False]
         ];
       NotebookPut[e_] :=
        MathLink`CallFrontEnd[
         FrontEnd`NotebookPutReturnObject[Append[e, Visible -> False]]
         ];
       Quiet[
        DocumentationBuild`Export`ExportWebPage[
         ExpandFileName[expFile],
         webExportNotebookPrep@nb,
         Normal@params,
         Sequence @@
          FilterRules[
           Flatten@{
             ops,
             "CompleteHTMLQ" -> True
             },
           FilterRules[
            Options[DocumentationBuild`Export`ExportWebPage],
            Except["HistoryData" | "Language"]
            ]
           ]
         ]
        ]
       ]
      ]

Where we'll feed the result of gathering the notebook metadata parameters in as `ops`:

    $webExportParameters =
      {
       "title" -> "Title",
       "titlemodifier" -> "TitleModifier",
       "history" -> "HistoryData",
       "type" -> "EntityType",
       "paclet" -> "PacletName",
       "context" -> "Context",
       "uri" -> "URI",
       "keywords" -> "Keywords",
       "tutorialcollectionlinks" -> "TutorialCollectionLinks",
       "summary" -> "Summary",
       "index" -> "IndexQ"
       };
    
    webExportGatherParameters[nb_, ops___?OptionQ] :=
      Normal@
       KeyMap[
        Capitalize@*
         Replace[$webExportParameters],
        Association@
         FilterRules[
          Flatten@{
            ops,
            Fold[Lookup, 
             Options[nb, TaggingRules], {TaggingRules, "Metadata"}]
            },
          Alternatives @@ 
           Flatten[Through@{Keys, Values}[$webExportParameters]]
          ]
        ];

Note that the export process also blocks / changes a lot of things that Workbench uses that we don't need, e.g opens the notebook in hidden form, prevents a new front-end from being configured, and has the `Transmogrify` process work in quieted mode.

---
### *Composite function*

We can then build all this into a single function:

    Options[GenerateHTMLDocumentation] =
      Join[
       Options[GenerateSymbolPages],
       Options[webExportPostProcess],
       Options[DocumentationBuild`Export`ExportWebPage],
       Options[webExportAssetsDeploy], {
        CloudConnect -> Automatic,
        CloudDeploy -> False,
        "DeployAssets" -> False,
        "CopyAssets" -> Automatic
        }];
    GenerateHTMLDocumentation[dir_String?DirectoryQ,
       nb : {__Notebook} | None,
       ops : OptionsPattern[]
       ] :=
      With[{
        deploy = OptionValue[CloudDeploy],
        highlight =
         CurrentValue[$FrontEndSession,
          {AutoStyleOptions, "HighlightUndefinedSymbols"}
          ]
        },
       If[
        TrueQ@OptionValue["CopyAssets"] ||
         And[
          OptionValue["CopyAssets"] === Automatic || 
           TrueQ@OptionValue["DeployAssets"],
          AnyTrue[{"css", "fonts", "images", "includes", "javascript"},
           Not@DirectoryQ[FileNameJoin@{dir, #}] &
           ]
          ],
        webExportAssetsCopy[dir]
        ];
       CheckAbort[
        Function[
          CurrentValue[$FrontEndSession,
            {AutoStyleOptions, "HighlightUndefinedSymbols"}
            ] =
           highlight;
          If[deploy,
           Replace[
            Replace[OptionValue[CloudConnect],
             Automatic -> Key["PacletsAccount"]
             ], {
             s_String :>
              If[$WolframID =!= s,
               CloudConnect[s]
               ],
             {s__String} :>
              CloudConnect[s],
             k_Key :>
              KeyChainConnect[k]
             }]
           ];
          If[deploy && OptionValue["DeployAssets"],
           Replace[
            Replace[OptionValue["ResourceBase"], {
              Automatic -> "reference",
              CloudObject[c_, ___] :> c
              }],
            s_String :>
             webExportAssetsDeploy[dir, s,
              FilterRules[
               {
                ops
                },
               Options@webExportAssetsDeploy
               ]
              ]
            ]
           ];
          If[deploy,
           Replace[
            Replace[OptionValue["URLBase"], {
              Automatic -> "reference",
              CloudObject[c_, ___] :> c
              }],
            s_String :>
             If[# =!= None,
              webExportCloudDeploy[dir, #, s,
               FilterRules[
                {
                 ops
                 },
                Options@webExportCloudDeploy
                ]
               ]
              ]
            ],
           #
           ]
          ]@
         If[nb === None,
          None,
          If[Length@nb > 1,
             Monitor[ReleaseHold[#],
              Internal`LoadingPanel[
               "Generating HTML page `` of ``"
                ~TemplateApply~
                {i, Length@nb}
               ]
              ],
             ReleaseHold@#
             ] &@
           Hold@
            Table[
             With[{
               params = webExportGatherParameters[nb[[i]], ops]
               },
              webExportPostProcess[
               webExportNotebook[dir, nb[[i]], params],
               FilterRules[
                Flatten@{
                  If[deploy,
                   
                   "URLBase" ->
                    
                    Replace[OptionValue["URLBase"], {
                      
                      Automatic :>
                       
                       First@CloudObject["reference"],
                      CloudObject[u_, ___] :>
                       u,
                      s_String :>
                       First@CloudObject[s]
                      }],
                   Nothing
                   ],
                  If[deploy,
                   
                   "ResourceBase" ->
                    
                    Replace[OptionValue["ResourceBase"], {
                      
                      Automatic :>
                       
                       First@CloudObject["reference"],
                      CloudObject[u_, ___] :>
                       u,
                      s_String :>
                       First@CloudObject[s]
                      }],
                   Nothing
                   ],
                  params
                  },
                Options[webExportPostProcess]
                ]
               ]
              ],
             {i, Length@nb}
             ]
          
          ],
        CurrentValue[$FrontEndSession,
          {AutoStyleOptions, "HighlightUndefinedSymbols"}
          ] =
         highlight;
        $Aborted
        ]
       ];

Then we merge it with the automatic documentation generation process I wrote up [here](https://mathematica.stackexchange.com/questions/146670/automating-documentation-generation/146671#146671):

    GenerateHTMLDocumentation[
       dir : (_String | _File)?
          DirectoryQ | _FileName?(DirectoryQ@*ToFileName),
       pattern : _String?(Not@*FileExistsQ) | _Symbol,
       ops___?OptionQ
       ] :=
      With[{n = Names[pattern]},
       If[Length@n > 1,
        $Failed,
        With[{
          nb =
           First[{NotebookGet[#], NotebookClose[#]}] &@
            First@Flatten@List@
               GenerateSymbolPages[
                Evaluate@First@n,
                Evaluate@FilterRules[{ops}, Options@GenerateSymbolPages],
                Visible -> False
                ]
          },
         GenerateHTMLDocumentation[
          Replace[dir, f_FileName :> ToFileName[f]],
          nb,
          ops
          ]
         ]
        ]
       ];

And then let it generate the docs without specifying a directory:

    $webDocsHTMLBuildDirectory =
      FileNameJoin@{$TemporaryDirectory, "web_docs"};
    GenerateHTMLDocumentation[
      Optional[Automatic, Automatic],
      s___
      ] :=
     With[{dir =
        Quiet[
         DeleteDirectory[$webDocsHTMLBuildDirectory, 
          DeleteContents -> True];
         CreateDirectory[$webDocsHTMLBuildDirectory]
         ]},
      GenerateHTMLDocumentation[
       dir,
       s
       ]
      ]

---
### *Viewing / Deploy the Docs*

Some things in the docs require HTTP, so to view the docs we make we'll want a function to start a server in a directory. It doesn't look like ``HTTPHandling`StartWebServer`` does that so we'll need something else. I chose to use python's [SimpleHTTPServer](https://docs.python.org/2/library/simplehttpserver.html)

I put some sugar on it in my [PyTools package](https://github.com/b3m2a1/mathematica-BTools/blob/master/Packages/PyTools.m). Look for `PySimpleServerStart` and `PySimpleServerOpen`.

But long-term having local docs is rather useless so I chose to put mine in the cloud, using these two functions to copy the resources and files up:

    Options[webExportAssetsDeploy] =
      DeleteDuplicatesBy[First]@
       Join[
        {
         Permissions -> "Public"
         },
        Options[CloudObject]
        ];
    webExportAssetsDeploy[
      dir_String?DirectoryQ,
      uri_String,
      ops : OptionsPattern[]
      ] :=
     With[{
       files =
        Select[
         FileNames[
          "css" | "fonts" | "images" | "includes" | 
            "javascript" ~~
           $PathnameSeparator <> "*",
          dir,
          \[Infinity]],
         Not@*DirectoryQ
         ]
       },
      Block[{f},
       Monitor[
        Table[
         CopyFile[
          f,
          CloudObject[
           URLBuild@
            Flatten@{uri, 
              FileNameSplit@FileNameDrop[f, FileNameDepth@dir]},
           Sequence @@ FilterRules[Flatten@{
               ops,
               Options[webExportAssetsDeploy]
               },
             Options[CloudObject]
             ]
           ]
          ],
         {f, files}
         ],
        Internal`LoadingPanel[
         "Copying `` to ``"~TemplateApply~
          {
           f,
           URLBuild@Flatten@{uri,
              FileNameSplit@FileNameDrop[f, FileNameDepth@dir]}
           }
         ]
        ]
       ]
      ]

    Options[webExportCloudDeploy] =
      DeleteDuplicatesBy[First]@
       Join[
        {
         Permissions -> "Public"
         },
        Options[CloudObject]
        ];
    webExportCloudDeploy[
      dir_String?DirectoryQ,
      pages : {__String?FileExistsQ},
      uri_String,
      ops : OptionsPattern[]
      ] :=
     With[{
       files =
        Join[
         pages,
         Select[
          FileNames[
           "Files" <> $PathnameSeparator ~~
            
            Alternatives @@ 
             Map[FileBaseName, pages] ~~
            $PathnameSeparator <> "*",
           DirectoryName@First@pages,
           \[Infinity]],
          Not@*DirectoryQ
          ]
         ]
       },
      Block[{f},
       Monitor[
        Table[
         Take[#, 1] &@
          CopyFile[
           f,
           CloudObject[
            URLBuild@
             Flatten@{uri,
               FileNameSplit@FileNameDrop[f, FileNameDepth@dir]},
            Sequence @@ FilterRules[
              Flatten@{
                ops,
                Options[webExportCloudDeploy]
                },
              Options[CloudObject]
              ]
            ]
           ],
         {f, files}
         ],
        Internal`LoadingPanel[
         "Copying `` to ``"~TemplateApply~
          {
           f,
           URLBuild@Flatten@{uri,
              FileNameSplit@FileNameDrop[f, FileNameDepth@dir]}
           }
         ]
        ]
       ]
      ]

(Note that they're already included in `GenerateHTMLDocumentation`)

---
### *End Product*

After all of that we have docs that are (mostly) functional and in the cloud. Here's an example of what this is good for:

    In[60]:= GenerateHTMLDocumentation[ 
     GenerateHTMLDocumentation,
     CloudDeploy -> True, 
     "CopyAssets" -> False
     ]
    
    Out[60]= CloudObject["https://www.wolframcloud.com/objects/b3m2a1.docs/reference/BTools/ref/GenerateHTMLDocumentation.html"]

If we then go to https://www.wolframcloud.com/objects/b3m2a1.paclets/docs/BTools/ref/GenerateHTMLDocumentation.html we get a mostly functional 11.0 style documentation page:

[![docs][1]][1]


  [1]: https://i.sstatic.net/PkDYP.png