ModX, redirect to multi-language with IIS8 under Windows

I’m setting a multi-language website ( Traditional Chinese and English ), the default website works well, but I can’t load the English part.
After a nice person’s guide, I correct some mistakes, but in the friendly URL’s part, it looks like the server problem.
My server is IIS8 under Windows server 2012 R2.
The ModX is Revolution 2.8.1-pl.
Begging help, I need to finish everything before Taiwan’s new year ( 2020-02-10, 17:00), please. My teammate can’t help me, cause they don’t know much about this. Q_Q

I was working through this with @stzero on slack but then it turned out to be a Windows server with IIS which I know little about.

The missing piece at the moment seems to be needing rewrite rules on the server so that friendly URLs work. (the equivalent to the .htaccess file on Apache/Linux)

Is there anyone active on the forums who is using IIS with MODX and has an example config?

The closest thing at the moment seems to be this from the old forums: https://forums.modx.com/thread/?thread=17127&page=5

The default .htaccess rules for iis web.config are below.

        <rule name="MODX Rule 1" stopProcessing="true">
          <match url=".*" ignoreCase="false" />
          <conditions logicalGrouping="MatchAll">
            <add input="{HTTP_USER_AGENT}" pattern="^.*internal\ dummy\ connection.*$" />
          </conditions>
          <action type="CustomResponse" statusCode="403" statusReason="Forbidden" statusDescription="Forbidden" />
        </rule>

        <rule name="MODX Rule 2" stopProcessing="true">
          <match url="^(manager|assets)" ignoreCase="false" />
          <action type="None" />
        </rule>

        <rule name="MODX Rule 3" stopProcessing="true">
          <match url="^(.*)$" ignoreCase="false" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" pattern="" ignoreCase="false" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" pattern="" ignoreCase="false" />
          </conditions>
          <action type="Rewrite" url="index.php?q={R:1}" appendQueryString="true" />
        </rule>

On a multilingual website with the Babel Extra I use this - the only difference being the additional rewrites to maintain the asset path. I have rules in the web.config file on the production site that are commented out, some failed attempts to get the multilingual aspect working, one related to cultureKey with a note saying it failed but is not required - see end.

<rule name="MODX Rule 1" stopProcessing="true">
  <match url=".*" ignoreCase="false" />
  <conditions logicalGrouping="MatchAll">
    <add input="{HTTP_USER_AGENT}" pattern="^.*internal\ dummy\ connection.*$" />
  </conditions>
  <action type="CustomResponse" statusCode="403" statusReason="Forbidden" statusDescription="Forbidden" />
</rule>

<rule name="MODX Rule 2" stopProcessing="true">
  <match url="^(manager|assets)" ignoreCase="false" />
  <action type="None" />
</rule>
        
<!--
	multilingual rules
-->

<!-- redirect all requests to (de|fr|it)/favicon.ico to /favicon.ico -->
<rule name="Imported Rule 4" stopProcessing="true">
    <match url="^(de|fr|it)/favicon.ico$" ignoreCase="false" />
    <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
    </conditions>
    <action type="Rewrite" url="favicon.ico" appendQueryString="true" />
</rule>

<!-- redirect all requests to (de|fr|it)/assets/* to /assets/ -->
<rule name="Imported Rule 5" stopProcessing="true">
    <match url="^(de|fr|it)/assets(.*)$" ignoreCase="false" />
    <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
    </conditions>
    <action type="Rewrite" url="assets{R:2}" appendQueryString="true" />
</rule>

<rule name="MODX Rule 3" stopProcessing="true">
  <match url="^(.*)$" ignoreCase="false" />
  <conditions logicalGrouping="MatchAll">
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" pattern="" ignoreCase="false" />
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" pattern="" ignoreCase="false" />
  </conditions>
  <action type="Rewrite" url="index.php?q={R:1}" appendQueryString="true" />
</rule>

The cultureKey rule

<!-- redirect all other requests for cultureKey to index.php and set the cultureKey parameter - returns 404 on translated pages when enabled, doesn't seem to be required, site works without
            <rule name="Imported Rule 6" stopProcessing="true">
                <match url="^(de|fr|it)?/?(.*)$" ignoreCase="false" />
                <conditions logicalGrouping="MatchAll">
                    <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
                    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
                </conditions>
                <action type="Rewrite" url="index.php?cultureKey={R:1}&amp;q={R:2}" appendQueryString="true" />
            </rule>
-->
2 Likes

Looking at this failed rule again

<conditions logicalGrouping="MatchAll">

Should probably be

<conditions logicalGrouping="MatchAny">

Can’t remember why I was looking at cultureKey though, site was written nearly two years ago.

No idea if this helps, it’s late and I’m not thinking particularly well.

Awesome, cheers @chris.dempsey78!

@stzero Since you’re using XRouting I think you’ll only need the first section that Chris posted added to your IIS web.config

Sorry for late, I put the config file under the ‘core’ folder, but still don’t work, the XRouting shows this:

## MODX context map:
Array
(
    [_hosts] => Array
    (
        [xxx.com/] => Array
            (
                [0] => web
                [1] => en
            )

    )

[web] => Array
    (
        [base_url] => /
        [cultureKey] => zh
        [error_page] => 19
        [http_host] => xxx.com/
        [site_start] => 1
        [site_url] => http://www.xxx.com/
    )

[en] => Array
    (
        [base_url] => /en/
        [cultureKey] => en
        [error_page] => 20
        [http_host] => xxx.com/
        [site_start] => 16
        [site_url] => http://www.xxx.com/en/
        )
)
## Requested URL: 
## Requested URL with base_url: /
## Matched context(s) (Array key defines match quality):
Array
(
)
## Request will go to context: 
## Modified request URL: 

Did i miss something and many thanks.

PS: in the article : https://docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/importing-apache-modrewrite-rules

The step 5, http://www_mysite_com/iisstart.htm and to http://mysite_com/iisstart.htm was not found.

The last step : Localhost refused to connect

Do you mean the web.config file? It should be in the web root directory, not the core directory.

The last step : Localhost refused to connect

This error is a little generic to draw any conclusions. Are there any errors in the php-error.log? Or can you enable Failed Request Tracing?

Can you reach the site by specifying it’s IP address and port? What IP is returned if you ping localhost?

Sorry, I got a car accident on 02/07 so the project was delayed. :frowning:
I’ll go back to the office today and check the error message.

Sorry to hear about your accident, @stzero. Hope you’re ok!

Did you manage to get any further with the IIS configuration?

I’m not good at IIS, but it seems like a port problem?
The environment is with two internet cards on the same computer before I install Modx, it runs WordPress, and then I install the ModX on the other port 81.
My colleague targets it to another internet card and tells me it is port 80 now, but the website still not works.
The URL is http://www.weyutech.com/.
You can see a homepage, but the links don’t work, it is made by Wayfinder. Although I change them to a Friendly URL, still don’t work.